bump product version to 6.4.0.3
[LibreOffice.git] / cui / source / dialogs / hangulhanjadlg.cxx
blobe3b0b2e5d592a31f045a58be7b695d1701ebe37f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <hangulhanjadlg.hxx>
21 #include <dialmgr.hxx>
23 #include <helpids.h>
24 #include <strings.hrc>
26 #include <algorithm>
27 #include <sal/log.hxx>
28 #include <osl/diagnose.h>
29 #include <tools/debug.hxx>
30 #include <i18nlangtag/languagetag.hxx>
31 #include <vcl/svapp.hxx>
32 #include <vcl/virdev.hxx>
33 #include <unotools/lingucfg.hxx>
34 #include <unotools/linguprops.hxx>
35 #include <com/sun/star/lang/NoSupportException.hpp>
36 #include <com/sun/star/linguistic2/ConversionDictionaryType.hpp>
37 #include <com/sun/star/linguistic2/ConversionDirection.hpp>
38 #include <com/sun/star/linguistic2/ConversionDictionaryList.hpp>
39 #include <com/sun/star/i18n/TextConversionOption.hpp>
40 #include <com/sun/star/util/XFlushable.hpp>
42 #include <comphelper/processfactory.hxx>
43 #include <comphelper/string.hxx>
45 #define HHC editeng::HangulHanjaConversion
46 #define LINE_CNT static_cast< sal_uInt16 >(2)
47 #define MAXNUM_SUGGESTIONS 50
50 namespace svx
53 using namespace ::com::sun::star;
54 using namespace css::uno;
55 using namespace css::linguistic2;
56 using namespace css::lang;
57 using namespace css::container;
60 namespace
62 class FontSwitch
64 private:
65 OutputDevice& m_rDev;
67 public:
68 FontSwitch( OutputDevice& _rDev, const vcl::Font& _rTemporaryFont )
69 :m_rDev( _rDev )
71 m_rDev.Push( PushFlags::FONT );
72 m_rDev.SetFont( _rTemporaryFont );
74 ~FontSwitch() COVERITY_NOEXCEPT_FALSE
76 m_rDev.Pop();
81 /** a class which allows to draw two texts in a pseudo-ruby way (which basically
82 means one text above or below the other, and a little bit smaller)
84 class PseudoRubyText
86 public:
87 enum RubyPosition
89 eAbove, eBelow
92 protected:
93 OUString m_sPrimaryText;
94 OUString m_sSecondaryText;
95 RubyPosition m_ePosition;
97 public:
98 PseudoRubyText();
99 void init( const OUString& rPrimaryText, const OUString& rSecondaryText, const RubyPosition& rPosition );
100 const OUString& getPrimaryText() const { return m_sPrimaryText; }
101 const OUString& getSecondaryText() const { return m_sSecondaryText; }
103 public:
104 void Paint( vcl::RenderContext& _rDevice, const ::tools::Rectangle& _rRect,
105 ::tools::Rectangle* _pPrimaryLocation, ::tools::Rectangle* _pSecondaryLocation );
108 PseudoRubyText::PseudoRubyText()
109 : m_ePosition(eAbove)
113 void PseudoRubyText::init( const OUString& rPrimaryText, const OUString& rSecondaryText, const RubyPosition& rPosition )
115 m_sPrimaryText = rPrimaryText;
116 m_sSecondaryText = rSecondaryText;
117 m_ePosition = rPosition;
121 void PseudoRubyText::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& _rRect,
122 ::tools::Rectangle* _pPrimaryLocation, ::tools::Rectangle* _pSecondaryLocation )
124 // calculate the text flags for the painting
125 constexpr DrawTextFlags nTextStyle = DrawTextFlags::Mnemonic |
126 DrawTextFlags::Left |
127 DrawTextFlags::VCenter;
129 Size aPlaygroundSize(_rRect.GetSize());
131 // the font for the secondary text:
132 vcl::Font aSmallerFont(rRenderContext.GetFont());
133 // heuristic: 80% of the original size
134 aSmallerFont.SetFontHeight( static_cast<long>( 0.8 * aSmallerFont.GetFontHeight() ) );
136 // let's calculate the size of our two texts
137 ::tools::Rectangle aPrimaryRect = rRenderContext.GetTextRect( _rRect, m_sPrimaryText, nTextStyle );
138 ::tools::Rectangle aSecondaryRect;
140 FontSwitch aFontRestore(rRenderContext, aSmallerFont);
141 aSecondaryRect = rRenderContext.GetTextRect(_rRect, m_sSecondaryText, nTextStyle);
144 // position these rectangles properly
145 // x-axis:
146 sal_Int32 nCombinedWidth = std::max( aSecondaryRect.GetWidth(), aPrimaryRect.GetWidth() );
147 // the rectangle where both texts will reside is as high as possible, and as wide as the
148 // widest of both text rects
149 aPrimaryRect.SetLeft( _rRect.Left() );
150 aSecondaryRect.SetLeft( aPrimaryRect.Left() );
151 aPrimaryRect.SetRight( _rRect.Left() + nCombinedWidth );
152 aSecondaryRect.SetRight( aPrimaryRect.Right() );
154 // y-axis:
155 sal_Int32 nCombinedHeight = aPrimaryRect.GetHeight() + aSecondaryRect.GetHeight();
156 // align to the top, for the moment
157 aPrimaryRect.Move( 0, _rRect.Top() - aPrimaryRect.Top() );
158 aSecondaryRect.Move( 0, aPrimaryRect.Top() + aPrimaryRect.GetHeight() - aSecondaryRect.Top() );
159 // move the rects to the bottom
160 aPrimaryRect.Move( 0, ( aPlaygroundSize.Height() - nCombinedHeight ) / 2 );
161 aSecondaryRect.Move( 0, ( aPlaygroundSize.Height() - nCombinedHeight ) / 2 );
163 // 'til here, everything we did assumes that the secondary text is painted _below_ the primary
164 // text. If this isn't the case, we need to correct the rectangles
165 if (eAbove == m_ePosition)
167 sal_Int32 nVertDistance = aSecondaryRect.Top() - aPrimaryRect.Top();
168 aSecondaryRect.Move( 0, -nVertDistance );
169 aPrimaryRect.Move( 0, nCombinedHeight - nVertDistance );
172 // now draw the texts
173 // as we already calculated the precise rectangles for the texts, we don't want to
174 // use the alignment flags given - within it's rect, every text is centered
175 DrawTextFlags nDrawTextStyle( nTextStyle );
176 nDrawTextStyle &= ~DrawTextFlags( DrawTextFlags::Right | DrawTextFlags::Left | DrawTextFlags::Bottom | DrawTextFlags::Top );
177 nDrawTextStyle |= DrawTextFlags::Center | DrawTextFlags::VCenter;
179 rRenderContext.DrawText( aPrimaryRect, m_sPrimaryText, nDrawTextStyle );
181 FontSwitch aFontRestore(rRenderContext, aSmallerFont);
182 rRenderContext.DrawText( aSecondaryRect, m_sSecondaryText, nDrawTextStyle );
185 // outta here
186 if (_pPrimaryLocation)
187 *_pPrimaryLocation = aPrimaryRect;
188 if (_pSecondaryLocation)
189 *_pSecondaryLocation = aSecondaryRect;
192 class RubyRadioButton
194 public:
195 RubyRadioButton(std::unique_ptr<weld::RadioButton> xControl);
196 void init(const OUString& rPrimaryText, const OUString& rSecondaryText, const PseudoRubyText::RubyPosition& rPosition);
198 void set_sensitive(bool sensitive) { m_xControl->set_sensitive(sensitive); }
199 void set_active(bool active) { m_xControl->set_active(active); }
200 bool get_active() const { return m_xControl->get_active(); }
202 void connect_clicked(const Link<weld::Button&, void>& rLink) { m_xControl->connect_clicked(rLink); }
204 private:
205 Size GetOptimalSize() const;
206 void Paint(vcl::RenderContext& rRenderContext);
208 ScopedVclPtr<VirtualDevice> m_xVirDev;
209 std::unique_ptr<weld::RadioButton> m_xControl;
210 PseudoRubyText m_aRubyText;
213 RubyRadioButton::RubyRadioButton(std::unique_ptr<weld::RadioButton> xControl)
214 : m_xVirDev(xControl->create_virtual_device())
215 , m_xControl(std::move(xControl))
217 // expand the point size of the desired font to the equivalent pixel size
218 if (vcl::Window* pDefaultDevice = dynamic_cast<vcl::Window*>(Application::GetDefaultDevice()))
219 pDefaultDevice->SetPointFont(*m_xVirDev, m_xControl->get_font());
222 void RubyRadioButton::init( const OUString& rPrimaryText, const OUString& rSecondaryText, const PseudoRubyText::RubyPosition& rPosition )
224 m_aRubyText.init(rPrimaryText, rSecondaryText, rPosition);
226 m_xVirDev->SetOutputSizePixel(GetOptimalSize());
228 Paint(*m_xVirDev);
230 m_xControl->set_image(m_xVirDev.get());
233 void RubyRadioButton::Paint(vcl::RenderContext& rRenderContext)
235 ::tools::Rectangle aOverallRect(Point(0, 0), rRenderContext.GetOutputSizePixel());
236 // inflate the rect a little bit (because the VCL radio button does the same)
237 ::tools::Rectangle aTextRect( aOverallRect );
238 aTextRect.AdjustLeft( 1 ); aTextRect.AdjustRight( -1 );
239 aTextRect.AdjustTop( 1 ); aTextRect.AdjustBottom( -1 );
241 // paint the ruby text
242 ::tools::Rectangle aPrimaryTextLocation;
243 ::tools::Rectangle aSecondaryTextLocation;
245 m_aRubyText.Paint(rRenderContext, aTextRect, &aPrimaryTextLocation, &aSecondaryTextLocation);
248 Size RubyRadioButton::GetOptimalSize() const
250 vcl::Font aSmallerFont(m_xVirDev->GetFont());
251 aSmallerFont.SetFontHeight( static_cast<long>( 0.8 * aSmallerFont.GetFontHeight() ) );
252 ::tools::Rectangle rect( Point(), Size( SAL_MAX_INT32, SAL_MAX_INT32 ) );
254 Size aPrimarySize = m_xVirDev->GetTextRect( rect, m_aRubyText.getPrimaryText() ).GetSize();
255 Size aSecondarySize;
257 FontSwitch aFontRestore(*m_xVirDev, aSmallerFont);
258 aSecondarySize = m_xVirDev->GetTextRect( rect, m_aRubyText.getSecondaryText() ).GetSize();
261 Size minimumSize;
262 minimumSize.setHeight( aPrimarySize.Height() + aSecondarySize.Height() + 5 );
263 minimumSize.setWidth( aPrimarySize.Width() + aSecondarySize.Width() + 5 );
264 return minimumSize;
267 SuggestionSet::SuggestionSet(std::unique_ptr<weld::ScrolledWindow> xScrolledWindow)
268 : SvtValueSet(std::move(xScrolledWindow))
273 void SuggestionSet::UserDraw( const UserDrawEvent& rUDEvt )
275 vcl::RenderContext* pDev = rUDEvt.GetRenderContext();
276 ::tools::Rectangle aRect = rUDEvt.GetRect();
277 sal_uInt16 nItemId = rUDEvt.GetItemId();
279 OUString sText = *static_cast< OUString* >( GetItemData( nItemId ) );
280 pDev->DrawText( aRect, sText, DrawTextFlags::Center | DrawTextFlags::VCenter );
283 SuggestionDisplay::SuggestionDisplay(weld::Builder& rBuilder)
284 : m_bDisplayListBox( true )
285 , m_bInSelectionUpdate( false )
286 , m_xValueSet(new SuggestionSet(rBuilder.weld_scrolled_window("scrollwin")))
287 , m_xValueSetWin(new weld::CustomWeld(rBuilder, "valueset", *m_xValueSet))
288 , m_xListBox(rBuilder.weld_tree_view("listbox"))
290 m_xValueSet->SetSelectHdl( LINK( this, SuggestionDisplay, SelectSuggestionValueSetHdl ) );
291 m_xListBox->connect_changed( LINK( this, SuggestionDisplay, SelectSuggestionListBoxHdl ) );
293 m_xValueSet->SetLineCount( LINE_CNT );
294 m_xValueSet->SetStyle( m_xValueSet->GetStyle() | WB_ITEMBORDER | WB_VSCROLL );
296 OUString const aOneCharacter("AU");
297 auto nItemWidth = 2 * m_xListBox->get_pixel_size(aOneCharacter).Width();
298 m_xValueSet->SetItemWidth( nItemWidth );
300 Size aSize(m_xListBox->get_approximate_digit_width() * 42, m_xListBox->get_text_height() * 5);
301 m_xValueSet->set_size_request(aSize.Width(), aSize.Height());
302 m_xListBox->set_size_request(aSize.Width(), aSize.Height());
304 implUpdateDisplay();
307 void SuggestionDisplay::implUpdateDisplay()
309 m_xListBox->set_visible(m_bDisplayListBox);
310 if (!m_bDisplayListBox)
311 m_xValueSetWin->show();
312 else
313 m_xValueSetWin->hide();
316 weld::Widget& SuggestionDisplay::implGetCurrentControl()
318 if (m_bDisplayListBox)
319 return *m_xListBox;
320 return *m_xValueSet->GetDrawingArea();
323 void SuggestionDisplay::DisplayListBox( bool bDisplayListBox )
325 if( m_bDisplayListBox != bDisplayListBox )
327 weld::Widget& rOldControl = implGetCurrentControl();
328 bool bHasFocus = rOldControl.has_focus();
330 m_bDisplayListBox = bDisplayListBox;
332 if( bHasFocus )
334 weld::Widget& rNewControl = implGetCurrentControl();
335 rNewControl.grab_focus();
338 implUpdateDisplay();
342 IMPL_LINK_NOARG(SuggestionDisplay, SelectSuggestionValueSetHdl, SvtValueSet*, void)
344 SelectSuggestionHdl(false);
347 IMPL_LINK_NOARG(SuggestionDisplay, SelectSuggestionListBoxHdl, weld::TreeView&, void)
349 SelectSuggestionHdl(true);
352 void SuggestionDisplay::SelectSuggestionHdl(bool bListBox)
354 if( m_bInSelectionUpdate )
355 return;
357 m_bInSelectionUpdate = true;
358 if (bListBox)
360 sal_uInt16 nPos = m_xListBox->get_selected_index();
361 m_xValueSet->SelectItem( nPos+1 ); //itemid == pos+1 (id 0 has special meaning)
363 else
365 sal_uInt16 nPos = m_xValueSet->GetSelectedItemId()-1; //itemid == pos+1 (id 0 has special meaning)
366 m_xListBox->select(nPos);
368 m_bInSelectionUpdate = false;
369 m_aSelectLink.Call( *this );
372 void SuggestionDisplay::SetSelectHdl( const Link<SuggestionDisplay&,void>& rLink )
374 m_aSelectLink = rLink;
377 void SuggestionDisplay::Clear()
379 m_xListBox->clear();
380 m_xValueSet->Clear();
383 void SuggestionDisplay::InsertEntry( const OUString& rStr )
385 m_xListBox->append_text(rStr);
386 sal_uInt16 nItemId = m_xListBox->n_children(); //itemid == pos+1 (id 0 has special meaning)
387 m_xValueSet->InsertItem( nItemId );
388 OUString* pItemData = new OUString( rStr );
389 m_xValueSet->SetItemData( nItemId, pItemData );
392 void SuggestionDisplay::SelectEntryPos( sal_uInt16 nPos )
394 m_xListBox->select(nPos);
395 m_xValueSet->SelectItem( nPos+1 ); //itemid == pos+1 (id 0 has special meaning)
398 sal_uInt16 SuggestionDisplay::GetEntryCount() const
400 return m_xListBox->n_children();
403 OUString SuggestionDisplay::GetEntry( sal_uInt16 nPos ) const
405 return m_xListBox->get_text( nPos );
408 OUString SuggestionDisplay::GetSelectedEntry() const
410 return m_xListBox->get_selected_text();
413 void SuggestionDisplay::SetHelpIds()
415 m_xValueSet->SetHelpId(HID_HANGULDLG_SUGGESTIONS_GRID);
416 m_xListBox->set_help_id(HID_HANGULDLG_SUGGESTIONS_LIST);
419 HangulHanjaConversionDialog::HangulHanjaConversionDialog(weld::Window* pParent)
420 : GenericDialogController(pParent, "cui/ui/hangulhanjaconversiondialog.ui", "HangulHanjaConversionDialog")
421 , m_bDocumentMode( true )
422 , m_xFind(m_xBuilder->weld_button("find"))
423 , m_xIgnore(m_xBuilder->weld_button("ignore"))
424 , m_xIgnoreAll(m_xBuilder->weld_button("ignoreall"))
425 , m_xReplace(m_xBuilder->weld_button("replace"))
426 , m_xReplaceAll(m_xBuilder->weld_button("replaceall"))
427 , m_xOptions(m_xBuilder->weld_button("options"))
428 , m_xSuggestions(new SuggestionDisplay(*m_xBuilder))
429 , m_xSimpleConversion(m_xBuilder->weld_radio_button("simpleconversion"))
430 , m_xHangulBracketed(m_xBuilder->weld_radio_button("hangulbracket"))
431 , m_xHanjaBracketed(m_xBuilder->weld_radio_button("hanjabracket"))
432 , m_xWordInput(m_xBuilder->weld_entry("wordinput"))
433 , m_xOriginalWord(m_xBuilder->weld_label("originalword"))
434 , m_xHanjaAbove(new RubyRadioButton(m_xBuilder->weld_radio_button("hanja_above")))
435 , m_xHanjaBelow(new RubyRadioButton(m_xBuilder->weld_radio_button("hanja_below")))
436 , m_xHangulAbove(new RubyRadioButton(m_xBuilder->weld_radio_button("hangul_above")))
437 , m_xHangulBelow(new RubyRadioButton(m_xBuilder->weld_radio_button("hangul_below")))
438 , m_xHangulOnly(m_xBuilder->weld_check_button("hangulonly"))
439 , m_xHanjaOnly(m_xBuilder->weld_check_button("hanjaonly"))
440 , m_xReplaceByChar(m_xBuilder->weld_check_button("replacebychar"))
442 m_xSuggestions->set_size_request(m_xOriginalWord->get_approximate_digit_width() * 42,
443 m_xOriginalWord->get_text_height() * 5);
445 const OUString sHangul(CuiResId(RID_SVXSTR_HANGUL));
446 const OUString sHanja(CuiResId(RID_SVXSTR_HANJA));
447 m_xHanjaAbove->init( sHangul, sHanja, PseudoRubyText::eAbove );
448 m_xHanjaBelow->init( sHangul, sHanja, PseudoRubyText::eBelow );
449 m_xHangulAbove->init( sHanja, sHangul, PseudoRubyText::eAbove );
450 m_xHangulBelow->init( sHanja, sHangul, PseudoRubyText::eBelow );
452 m_xWordInput->connect_changed( LINK( this, HangulHanjaConversionDialog, OnSuggestionModified ) );
453 m_xSuggestions->SetSelectHdl( LINK( this, HangulHanjaConversionDialog, OnSuggestionSelected ) );
454 m_xReplaceByChar->connect_toggled( LINK( this, HangulHanjaConversionDialog, ClickByCharacterHdl ) );
455 m_xHangulOnly->connect_toggled( LINK( this, HangulHanjaConversionDialog, OnConversionDirectionClicked ) );
456 m_xHanjaOnly->connect_toggled( LINK( this, HangulHanjaConversionDialog, OnConversionDirectionClicked ) );
457 m_xOptions->connect_clicked(LINK(this, HangulHanjaConversionDialog, OnOption));
459 // initial focus
460 FocusSuggestion( );
462 // initial control values
463 m_xSimpleConversion->set_active(true);
465 m_xSuggestions->SetHelpIds();
468 HangulHanjaConversionDialog::~HangulHanjaConversionDialog()
472 void HangulHanjaConversionDialog::FillSuggestions( const css::uno::Sequence< OUString >& _rSuggestions )
474 m_xSuggestions->Clear();
475 for ( auto const & suggestion : _rSuggestions )
476 m_xSuggestions->InsertEntry( suggestion );
478 // select the first suggestion, and fill in the suggestion edit field
479 OUString sFirstSuggestion;
480 if ( m_xSuggestions->GetEntryCount() )
482 sFirstSuggestion = m_xSuggestions->GetEntry( 0 );
483 m_xSuggestions->SelectEntryPos( 0 );
485 m_xWordInput->set_text( sFirstSuggestion );
486 m_xWordInput->save_value();
487 OnSuggestionModified( *m_xWordInput );
490 void HangulHanjaConversionDialog::SetOptionsChangedHdl(const Link<LinkParamNone*,void>& rHdl)
492 m_aOptionsChangedLink = rHdl;
495 void HangulHanjaConversionDialog::SetIgnoreHdl(const Link<weld::Button&,void>& rHdl)
497 m_xIgnore->connect_clicked(rHdl);
500 void HangulHanjaConversionDialog::SetIgnoreAllHdl(const Link<weld::Button&,void>& rHdl)
502 m_xIgnoreAll->connect_clicked(rHdl);
505 void HangulHanjaConversionDialog::SetChangeHdl(const Link<weld::Button&,void>& rHdl )
507 m_xReplace->connect_clicked(rHdl);
510 void HangulHanjaConversionDialog::SetChangeAllHdl(const Link<weld::Button&,void>& rHdl)
512 m_xReplaceAll->connect_clicked(rHdl);
515 void HangulHanjaConversionDialog::SetFindHdl(const Link<weld::Button&,void>& rHdl)
517 m_xFind->connect_clicked(rHdl);
520 void HangulHanjaConversionDialog::SetConversionFormatChangedHdl( const Link<weld::Button&,void>& rHdl )
522 m_xSimpleConversion->connect_clicked( rHdl );
523 m_xHangulBracketed->connect_clicked( rHdl );
524 m_xHanjaBracketed->connect_clicked( rHdl );
525 m_xHanjaAbove->connect_clicked( rHdl );
526 m_xHanjaBelow->connect_clicked( rHdl );
527 m_xHangulAbove->connect_clicked( rHdl );
528 m_xHangulBelow->connect_clicked( rHdl );
531 void HangulHanjaConversionDialog::SetClickByCharacterHdl( const Link<weld::ToggleButton&,void>& _rHdl )
533 m_aClickByCharacterLink = _rHdl;
536 IMPL_LINK_NOARG( HangulHanjaConversionDialog, OnSuggestionSelected, SuggestionDisplay&, void )
538 m_xWordInput->set_text(m_xSuggestions->GetSelectedEntry());
539 OnSuggestionModified( *m_xWordInput );
542 IMPL_LINK_NOARG( HangulHanjaConversionDialog, OnSuggestionModified, weld::Entry&, void )
544 m_xFind->set_sensitive(m_xWordInput->get_value_changed_from_saved());
546 bool bSameLen = m_xWordInput->get_text().getLength() == m_xOriginalWord->get_label().getLength();
547 m_xReplace->set_sensitive( m_bDocumentMode && bSameLen );
548 m_xReplaceAll->set_sensitive( m_bDocumentMode && bSameLen );
551 IMPL_LINK(HangulHanjaConversionDialog, ClickByCharacterHdl, weld::ToggleButton&, rBox, void)
553 m_aClickByCharacterLink.Call(rBox);
554 bool bByCharacter = rBox.get_active();
555 m_xSuggestions->DisplayListBox( !bByCharacter );
558 IMPL_LINK(HangulHanjaConversionDialog, OnConversionDirectionClicked, weld::ToggleButton&, rBox, void)
560 weld::CheckButton* pOtherBox = nullptr;
561 if (&rBox == m_xHangulOnly.get())
562 pOtherBox = m_xHanjaOnly.get();
563 else
564 pOtherBox = m_xHangulOnly.get();
565 bool bBoxChecked = rBox.get_active();
566 if (bBoxChecked)
567 pOtherBox->set_active(false);
568 pOtherBox->set_sensitive(!bBoxChecked);
571 IMPL_LINK_NOARG(HangulHanjaConversionDialog, OnOption, weld::Button&, void)
573 HangulHanjaOptionsDialog aOptDlg(m_xDialog.get());
574 aOptDlg.run();
575 m_aOptionsChangedLink.Call( nullptr );
578 OUString HangulHanjaConversionDialog::GetCurrentString( ) const
580 return m_xOriginalWord->get_label();
583 void HangulHanjaConversionDialog::FocusSuggestion( )
585 m_xWordInput->grab_focus();
588 void HangulHanjaConversionDialog::SetCurrentString( const OUString& _rNewString,
589 const Sequence< OUString >& _rSuggestions, bool _bOriginatesFromDocument )
591 m_xOriginalWord->set_label(_rNewString);
593 bool bOldDocumentMode = m_bDocumentMode;
594 m_bDocumentMode = _bOriginatesFromDocument; // before FillSuggestions!
595 FillSuggestions( _rSuggestions );
597 m_xIgnoreAll->set_sensitive( m_bDocumentMode );
599 // switch the def button depending if we're working for document text
600 if (bOldDocumentMode != m_bDocumentMode)
602 weld::Widget* pOldDefButton = nullptr;
603 weld::Widget* pNewDefButton = nullptr;
604 if (m_bDocumentMode)
606 pOldDefButton = m_xFind.get();
607 pNewDefButton = m_xReplace.get();
609 else
611 pOldDefButton = m_xReplace.get();
612 pNewDefButton = m_xFind.get();
615 pOldDefButton->set_has_default(false);
616 pNewDefButton->set_has_default(true);
620 OUString HangulHanjaConversionDialog::GetCurrentSuggestion( ) const
622 return m_xWordInput->get_text();
625 void HangulHanjaConversionDialog::SetByCharacter( bool _bByCharacter )
627 m_xReplaceByChar->set_active( _bByCharacter );
628 m_xSuggestions->DisplayListBox( !_bByCharacter );
631 void HangulHanjaConversionDialog::SetConversionDirectionState(
632 bool _bTryBothDirections,
633 HHC::ConversionDirection ePrimaryConversionDirection )
635 // default state: try both direction
636 m_xHangulOnly->set_active( false );
637 m_xHangulOnly->set_sensitive(true);
638 m_xHanjaOnly->set_active( false );
639 m_xHanjaOnly->set_sensitive(true);
641 if (!_bTryBothDirections)
643 weld::CheckButton* pBox = ePrimaryConversionDirection == HHC::eHangulToHanja ?
644 m_xHangulOnly.get() : m_xHanjaOnly.get();
645 pBox->set_active(true);
646 OnConversionDirectionClicked(*pBox);
650 bool HangulHanjaConversionDialog::GetUseBothDirections( ) const
652 return !m_xHangulOnly->get_active() && !m_xHanjaOnly->get_active();
655 HHC::ConversionDirection HangulHanjaConversionDialog::GetDirection(
656 HHC::ConversionDirection eDefaultDirection ) const
658 HHC::ConversionDirection eDirection = eDefaultDirection;
659 if (m_xHangulOnly->get_active() && !m_xHanjaOnly->get_active())
660 eDirection = HHC::eHangulToHanja;
661 else if (!m_xHangulOnly->get_active() && m_xHanjaOnly->get_active())
662 eDirection = HHC::eHanjaToHangul;
663 return eDirection;
666 void HangulHanjaConversionDialog::SetConversionFormat( HHC::ConversionFormat _eType )
668 switch ( _eType )
670 case HHC::eSimpleConversion: m_xSimpleConversion->set_active(true); break;
671 case HHC::eHangulBracketed: m_xHangulBracketed->set_active(true); break;
672 case HHC::eHanjaBracketed: m_xHanjaBracketed->set_active(true); break;
673 case HHC::eRubyHanjaAbove: m_xHanjaAbove->set_active(true); break;
674 case HHC::eRubyHanjaBelow: m_xHanjaBelow->set_active(true); break;
675 case HHC::eRubyHangulAbove: m_xHangulAbove->set_active(true); break;
676 case HHC::eRubyHangulBelow: m_xHangulBelow->set_active(true); break;
677 default:
678 OSL_FAIL( "HangulHanjaConversionDialog::SetConversionFormat: unknown type!" );
682 HHC::ConversionFormat HangulHanjaConversionDialog::GetConversionFormat( ) const
684 if ( m_xSimpleConversion->get_active() )
685 return HHC::eSimpleConversion;
686 if ( m_xHangulBracketed->get_active() )
687 return HHC::eHangulBracketed;
688 if ( m_xHanjaBracketed->get_active() )
689 return HHC::eHanjaBracketed;
690 if ( m_xHanjaAbove->get_active() )
691 return HHC::eRubyHanjaAbove;
692 if ( m_xHanjaBelow->get_active() )
693 return HHC::eRubyHanjaBelow;
694 if ( m_xHangulAbove->get_active() )
695 return HHC::eRubyHangulAbove;
696 if ( m_xHangulBelow->get_active() )
697 return HHC::eRubyHangulBelow;
699 OSL_FAIL( "HangulHanjaConversionDialog::GetConversionFormat: no radio checked?" );
700 return HHC::eSimpleConversion;
703 void HangulHanjaConversionDialog::EnableRubySupport( bool bVal )
705 m_xHanjaAbove->set_sensitive( bVal );
706 m_xHanjaBelow->set_sensitive( bVal );
707 m_xHangulAbove->set_sensitive( bVal );
708 m_xHangulBelow->set_sensitive( bVal );
711 void HangulHanjaOptionsDialog::Init()
713 if( !m_xConversionDictionaryList.is() )
715 m_xConversionDictionaryList = ConversionDictionaryList::create( ::comphelper::getProcessComponentContext() );
718 m_aDictList.clear();
719 m_xDictsLB->clear();
721 Reference< XNameContainer > xNameCont = m_xConversionDictionaryList->getDictionaryContainer();
722 if( xNameCont.is() )
724 Sequence< OUString > aDictNames( xNameCont->getElementNames() );
726 const OUString* pDic = aDictNames.getConstArray();
727 sal_Int32 nCount = aDictNames.getLength();
729 sal_Int32 i;
730 for( i = 0 ; i < nCount ; ++i )
732 Any aAny( xNameCont->getByName( pDic[ i ] ) );
733 Reference< XConversionDictionary > xDic;
734 if( ( aAny >>= xDic ) && xDic.is() )
736 if( LANGUAGE_KOREAN == LanguageTag( xDic->getLocale() ).getLanguageType() )
738 m_aDictList.push_back( xDic );
739 AddDict( xDic->getName(), xDic->isActive() );
744 if (m_xDictsLB->n_children())
745 m_xDictsLB->select(0);
748 IMPL_LINK_NOARG(HangulHanjaOptionsDialog, OkHdl, weld::Button&, void)
750 sal_uInt32 nCnt = m_aDictList.size();
751 sal_uInt32 n = 0;
752 sal_uInt32 nActiveDics = 0;
753 Sequence< OUString > aActiveDics;
755 aActiveDics.realloc( nCnt );
756 OUString* pActActiveDic = aActiveDics.getArray();
758 while( nCnt )
760 Reference< XConversionDictionary > xDict = m_aDictList[ n ];
762 DBG_ASSERT( xDict.is(), "-HangulHanjaOptionsDialog::OkHdl(): someone is evaporated..." );
764 bool bActive = m_xDictsLB->get_toggle(n, 0) == TRISTATE_TRUE;
765 xDict->setActive( bActive );
766 Reference< util::XFlushable > xFlush( xDict, uno::UNO_QUERY );
767 if( xFlush.is() )
768 xFlush->flush();
770 if( bActive )
772 pActActiveDic[ nActiveDics ] = xDict->getName();
773 ++nActiveDics;
776 ++n;
777 --nCnt;
780 // save configuration
781 aActiveDics.realloc( nActiveDics );
782 Any aTmp;
783 SvtLinguConfig aLngCfg;
784 aTmp <<= aActiveDics;
785 aLngCfg.SetProperty( UPH_ACTIVE_CONVERSION_DICTIONARIES, aTmp );
787 aTmp <<= m_xIgnorepostCB->get_active();
788 aLngCfg.SetProperty( UPH_IS_IGNORE_POST_POSITIONAL_WORD, aTmp );
790 aTmp <<= m_xShowrecentlyfirstCB->get_active();
791 aLngCfg.SetProperty( UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST, aTmp );
793 aTmp <<= m_xAutoreplaceuniqueCB->get_active();
794 aLngCfg.SetProperty( UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES, aTmp );
796 m_xDialog->response(RET_OK);
799 IMPL_LINK_NOARG(HangulHanjaOptionsDialog, DictsLB_SelectHdl, weld::TreeView&, void)
801 bool bSel = m_xDictsLB->get_selected_index() != -1;
803 m_xEditPB->set_sensitive(bSel);
804 m_xDeletePB->set_sensitive(bSel);
807 IMPL_LINK_NOARG(HangulHanjaOptionsDialog, NewDictHdl, weld::Button&, void)
809 OUString aName;
810 HangulHanjaNewDictDialog aNewDlg(m_xDialog.get());
811 aNewDlg.run();
812 if (aNewDlg.GetName(aName))
814 if( m_xConversionDictionaryList.is() )
818 Reference< XConversionDictionary > xDic =
819 m_xConversionDictionaryList->addNewDictionary( aName, LanguageTag::convertToLocale( LANGUAGE_KOREAN ), ConversionDictionaryType::HANGUL_HANJA );
821 if( xDic.is() )
823 //adapt local caches:
824 m_aDictList.push_back( xDic );
825 AddDict( xDic->getName(), xDic->isActive() );
828 catch( const ElementExistException& )
831 catch( const NoSupportException& )
838 IMPL_LINK_NOARG(HangulHanjaOptionsDialog, EditDictHdl, weld::Button&, void)
840 int nEntry = m_xDictsLB->get_selected_index();
841 DBG_ASSERT(nEntry != -1, "+HangulHanjaEditDictDialog::EditDictHdl(): call of edit should not be possible with no selection!");
842 if (nEntry != -1)
844 HangulHanjaEditDictDialog aEdDlg(m_xDialog.get(), m_aDictList, nEntry);
845 aEdDlg.run();
849 IMPL_LINK_NOARG(HangulHanjaOptionsDialog, DeleteDictHdl, weld::Button&, void)
851 int nSelPos = m_xDictsLB->get_selected_index();
852 if (nSelPos != -1)
854 Reference< XConversionDictionary > xDic( m_aDictList[ nSelPos ] );
855 if( m_xConversionDictionaryList.is() && xDic.is() )
857 Reference< XNameContainer > xNameCont = m_xConversionDictionaryList->getDictionaryContainer();
858 if( xNameCont.is() )
862 xNameCont->removeByName( xDic->getName() );
864 //adapt local caches:
865 m_aDictList.erase(m_aDictList.begin()+nSelPos );
866 m_xDictsLB->remove(nSelPos);
868 catch( const ElementExistException& )
871 catch( const NoSupportException& )
879 HangulHanjaOptionsDialog::HangulHanjaOptionsDialog(weld::Window* pParent)
880 : GenericDialogController(pParent, "cui/ui/hangulhanjaoptdialog.ui", "HangulHanjaOptDialog")
881 , m_xDictsLB(m_xBuilder->weld_tree_view("dicts"))
882 , m_xIgnorepostCB(m_xBuilder->weld_check_button("ignorepost"))
883 , m_xShowrecentlyfirstCB(m_xBuilder->weld_check_button("showrecentfirst"))
884 , m_xAutoreplaceuniqueCB(m_xBuilder->weld_check_button("autoreplaceunique"))
885 , m_xNewPB(m_xBuilder->weld_button("new"))
886 , m_xEditPB(m_xBuilder->weld_button("edit"))
887 , m_xDeletePB(m_xBuilder->weld_button("delete"))
888 , m_xOkPB(m_xBuilder->weld_button("ok"))
890 m_xDictsLB->set_size_request(m_xDictsLB->get_approximate_digit_width() * 32,
891 m_xDictsLB->get_height_rows(5));
893 std::vector<int> aWidths;
894 aWidths.push_back(m_xDictsLB->get_checkbox_column_width());
895 m_xDictsLB->set_column_fixed_widths(aWidths);
897 m_xDictsLB->connect_changed( LINK( this, HangulHanjaOptionsDialog, DictsLB_SelectHdl ) );
899 m_xOkPB->connect_clicked( LINK( this, HangulHanjaOptionsDialog, OkHdl ) );
900 m_xNewPB->connect_clicked( LINK( this, HangulHanjaOptionsDialog, NewDictHdl ) );
901 m_xEditPB->connect_clicked( LINK( this, HangulHanjaOptionsDialog, EditDictHdl ) );
902 m_xDeletePB->connect_clicked( LINK( this, HangulHanjaOptionsDialog, DeleteDictHdl ) );
904 SvtLinguConfig aLngCfg;
905 Any aTmp;
906 bool bVal = bool();
907 aTmp = aLngCfg.GetProperty( UPH_IS_IGNORE_POST_POSITIONAL_WORD );
908 if( aTmp >>= bVal )
909 m_xIgnorepostCB->set_active( bVal );
911 aTmp = aLngCfg.GetProperty( UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST );
912 if( aTmp >>= bVal )
913 m_xShowrecentlyfirstCB->set_active( bVal );
915 aTmp = aLngCfg.GetProperty( UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES );
916 if( aTmp >>= bVal )
917 m_xAutoreplaceuniqueCB->set_active( bVal );
919 Init();
922 HangulHanjaOptionsDialog::~HangulHanjaOptionsDialog()
926 void HangulHanjaOptionsDialog::AddDict(const OUString& rName, bool bChecked)
928 m_xDictsLB->append();
929 int nRow = m_xDictsLB->n_children() - 1;
930 m_xDictsLB->set_toggle(nRow, bChecked ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
931 m_xDictsLB->set_text(nRow, rName, 1);
932 m_xDictsLB->set_id(nRow, rName);
935 IMPL_LINK_NOARG(HangulHanjaNewDictDialog, OKHdl, weld::Button&, void)
937 OUString aName(comphelper::string::stripEnd(m_xDictNameED->get_text(), ' '));
939 m_bEntered = !aName.isEmpty();
940 if (m_bEntered)
941 m_xDictNameED->set_text(aName); // do this in case of trailing chars have been deleted
943 m_xDialog->response(RET_OK);
946 IMPL_LINK_NOARG(HangulHanjaNewDictDialog, ModifyHdl, weld::Entry&, void)
948 OUString aName(comphelper::string::stripEnd(m_xDictNameED->get_text(), ' '));
950 m_xOkBtn->set_sensitive(!aName.isEmpty());
953 HangulHanjaNewDictDialog::HangulHanjaNewDictDialog(weld::Window* pParent)
954 : GenericDialogController(pParent, "cui/ui/hangulhanjaadddialog.ui", "HangulHanjaAddDialog")
955 , m_bEntered(false)
956 , m_xOkBtn(m_xBuilder->weld_button("ok"))
957 , m_xDictNameED(m_xBuilder->weld_entry("entry"))
959 m_xOkBtn->connect_clicked( LINK( this, HangulHanjaNewDictDialog, OKHdl ) );
960 m_xDictNameED->connect_changed( LINK( this, HangulHanjaNewDictDialog, ModifyHdl ) );
963 HangulHanjaNewDictDialog::~HangulHanjaNewDictDialog()
967 bool HangulHanjaNewDictDialog::GetName( OUString& _rRetName ) const
969 if( m_bEntered )
970 _rRetName = comphelper::string::stripEnd(m_xDictNameED->get_text(), ' ');
972 return m_bEntered;
975 class SuggestionList
977 private:
978 protected:
979 std::vector<OUString> m_vElements;
980 sal_uInt16 m_nNumOfEntries;
981 // index of the internal iterator, used for First() and Next() methods
982 sal_uInt16 m_nAct;
984 const OUString* Next_();
985 public:
986 SuggestionList();
987 ~SuggestionList();
989 void Set( const OUString& _rElement, sal_uInt16 _nNumOfElement );
990 void Reset( sal_uInt16 _nNumOfElement );
991 const OUString & Get( sal_uInt16 _nNumOfElement ) const;
992 void Clear();
994 const OUString* First();
995 const OUString* Next();
997 sal_uInt16 GetCount() const { return m_nNumOfEntries; }
1000 SuggestionList::SuggestionList() :
1001 m_vElements(MAXNUM_SUGGESTIONS)
1003 m_nAct = m_nNumOfEntries = 0;
1006 SuggestionList::~SuggestionList()
1008 Clear();
1011 void SuggestionList::Set( const OUString& _rElement, sal_uInt16 _nNumOfElement )
1013 m_vElements[_nNumOfElement] = _rElement;
1014 ++m_nNumOfEntries;
1017 void SuggestionList::Reset( sal_uInt16 _nNumOfElement )
1019 m_vElements[_nNumOfElement].clear();
1020 --m_nNumOfEntries;
1023 const OUString& SuggestionList::Get( sal_uInt16 _nNumOfElement ) const
1025 return m_vElements[_nNumOfElement];
1028 void SuggestionList::Clear()
1030 if( m_nNumOfEntries )
1032 for (auto & vElement : m_vElements)
1033 vElement.clear();
1034 m_nNumOfEntries = m_nAct = 0;
1038 const OUString* SuggestionList::Next_()
1040 while( m_nAct < m_vElements.size() )
1042 auto & s = m_vElements[ m_nAct ];
1043 if (!s.isEmpty())
1044 return &s;
1045 ++m_nAct;
1048 return nullptr;
1051 const OUString* SuggestionList::First()
1053 m_nAct = 0;
1054 return Next_();
1057 const OUString* SuggestionList::Next()
1059 const OUString* pRet;
1061 if( m_nAct < m_nNumOfEntries )
1063 ++m_nAct;
1064 pRet = Next_();
1066 else
1067 pRet = nullptr;
1069 return pRet;
1073 bool SuggestionEdit::ShouldScroll( bool _bUp ) const
1075 bool bRet = false;
1077 if( _bUp )
1079 if( !m_pPrev )
1080 bRet = m_pScrollBar->vadjustment_get_value() > m_pScrollBar->vadjustment_get_lower();
1082 else
1084 if( !m_pNext )
1085 bRet = m_pScrollBar->vadjustment_get_value() < ( m_pScrollBar->vadjustment_get_upper() - 4 );
1088 return bRet;
1091 void SuggestionEdit::DoJump( bool _bUp )
1093 m_pScrollBar->vadjustment_set_value( m_pScrollBar->vadjustment_get_value() + ( _bUp? -1 : 1 ) );
1094 m_pParent->UpdateScrollbar();
1097 SuggestionEdit::SuggestionEdit(std::unique_ptr<weld::Entry> xEntry, HangulHanjaEditDictDialog* pParent)
1098 : m_pParent(pParent)
1099 , m_pPrev(nullptr)
1100 , m_pNext(nullptr)
1101 , m_pScrollBar(nullptr)
1102 , m_xEntry(std::move(xEntry))
1104 m_xEntry->connect_key_press(LINK(this, SuggestionEdit, KeyInputHdl));
1107 IMPL_LINK(SuggestionEdit, KeyInputHdl, const KeyEvent&, rKEvt, bool)
1109 bool bHandled = false;
1111 const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
1112 sal_uInt16 nMod = rKeyCode.GetModifier();
1113 sal_uInt16 nCode = rKeyCode.GetCode();
1114 if( nCode == KEY_TAB && ( !nMod || KEY_SHIFT == nMod ) )
1116 bool bUp = KEY_SHIFT == nMod;
1117 if( ShouldScroll( bUp ) )
1119 DoJump( bUp );
1120 m_xEntry->select_region(0, -1);
1121 // Tab-travel doesn't really happen, so emulate it by setting a selection manually
1122 bHandled = true;
1125 else if( KEY_UP == nCode || KEY_DOWN == nCode )
1127 bool bUp = KEY_UP == nCode;
1128 if( ShouldScroll( bUp ) )
1130 DoJump( bUp );
1131 bHandled = true;
1133 else if( bUp )
1135 if( m_pPrev )
1137 m_pPrev->grab_focus();
1138 bHandled = true;
1141 else if( m_pNext )
1143 m_pNext->grab_focus();
1144 bHandled = true;
1148 return bHandled;
1151 void SuggestionEdit::init(weld::ScrolledWindow* pScrollBar, SuggestionEdit* pPrev, SuggestionEdit* pNext)
1153 m_pScrollBar = pScrollBar;
1154 m_pPrev = pPrev;
1155 m_pNext = pNext;
1158 namespace
1160 bool GetConversions( const Reference< XConversionDictionary >& _xDict,
1161 const OUString& _rOrg,
1162 Sequence< OUString >& _rEntries )
1164 bool bRet = false;
1165 if( _xDict.is() && !_rOrg.isEmpty() )
1169 _rEntries = _xDict->getConversions( _rOrg,
1171 _rOrg.getLength(),
1172 ConversionDirection_FROM_LEFT,
1173 css::i18n::TextConversionOption::NONE );
1174 bRet = _rEntries.hasElements();
1176 catch( const IllegalArgumentException& )
1181 return bRet;
1185 IMPL_LINK_NOARG( HangulHanjaEditDictDialog, ScrollHdl, weld::ScrolledWindow&, void )
1187 UpdateScrollbar();
1190 IMPL_LINK_NOARG( HangulHanjaEditDictDialog, OriginalModifyHdl, weld::ComboBox&, void )
1192 m_bModifiedOriginal = true;
1193 m_aOriginal = comphelper::string::stripEnd( m_xOriginalLB->get_active_text(), ' ' );
1195 UpdateSuggestions();
1196 UpdateButtonStates();
1199 IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl1, weld::Entry&, rEdit, void )
1201 EditModify( &rEdit, 0 );
1204 IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl2, weld::Entry&, rEdit, void )
1206 EditModify( &rEdit, 1 );
1209 IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl3, weld::Entry&, rEdit, void )
1211 EditModify( &rEdit, 2 );
1214 IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl4, weld::Entry&, rEdit, void )
1216 EditModify( &rEdit, 3 );
1219 IMPL_LINK_NOARG( HangulHanjaEditDictDialog, BookLBSelectHdl, weld::ComboBox&, void )
1221 InitEditDictDialog( m_xBookLB->get_active() );
1224 IMPL_LINK_NOARG( HangulHanjaEditDictDialog, NewPBPushHdl, weld::Button&, void )
1226 DBG_ASSERT( m_xSuggestions, "-HangulHanjaEditDictDialog::NewPBPushHdl(): no suggestions... search in hell..." );
1227 Reference< XConversionDictionary > xDict = m_rDictList[ m_nCurrentDict ];
1228 if( xDict.is() && m_xSuggestions )
1230 //delete old entry
1231 bool bRemovedSomething = DeleteEntryFromDictionary( xDict );
1233 OUString aLeft( m_aOriginal );
1234 const OUString* pRight = m_xSuggestions->First();
1235 bool bAddedSomething = false;
1236 while( pRight )
1240 //add new entry
1241 xDict->addEntry( aLeft, *pRight );
1242 bAddedSomething = true;
1244 catch( const IllegalArgumentException& )
1247 catch( const ElementExistException& )
1251 pRight = m_xSuggestions->Next();
1254 if( bAddedSomething || bRemovedSomething )
1255 InitEditDictDialog( m_nCurrentDict );
1257 else
1259 SAL_INFO( "cui.dialogs", "dictionary faded away..." );
1263 bool HangulHanjaEditDictDialog::DeleteEntryFromDictionary( const Reference< XConversionDictionary >& xDict )
1265 bool bRemovedSomething = false;
1266 if( xDict.is() )
1268 OUString aOrg( m_aOriginal );
1269 Sequence< OUString > aEntries;
1270 GetConversions( xDict, m_aOriginal, aEntries );
1272 sal_uInt32 n = aEntries.getLength();
1273 OUString* pEntry = aEntries.getArray();
1274 while( n )
1278 xDict->removeEntry( aOrg, *pEntry );
1279 bRemovedSomething = true;
1281 catch( const NoSuchElementException& )
1282 { // can not be...
1285 ++pEntry;
1286 --n;
1289 return bRemovedSomething;
1292 IMPL_LINK_NOARG( HangulHanjaEditDictDialog, DeletePBPushHdl, weld::Button&, void )
1294 if( DeleteEntryFromDictionary( m_rDictList[ m_nCurrentDict ] ) )
1296 m_aOriginal.clear();
1297 m_bModifiedOriginal = true;
1298 InitEditDictDialog( m_nCurrentDict );
1302 void HangulHanjaEditDictDialog::InitEditDictDialog( sal_uInt32 nSelDict )
1304 if( m_xSuggestions )
1305 m_xSuggestions->Clear();
1307 if( m_nCurrentDict != nSelDict )
1309 m_nCurrentDict = nSelDict;
1310 m_aOriginal.clear();
1311 m_bModifiedOriginal = true;
1314 UpdateOriginalLB();
1316 m_xOriginalLB->set_entry_text( !m_aOriginal.isEmpty() ? m_aOriginal : m_aEditHintText);
1317 m_xOriginalLB->select_entry_region(0, -1);
1318 m_xOriginalLB->grab_focus();
1320 UpdateSuggestions();
1321 UpdateButtonStates();
1324 void HangulHanjaEditDictDialog::UpdateOriginalLB()
1326 m_xOriginalLB->clear();
1327 Reference< XConversionDictionary > xDict = m_rDictList[ m_nCurrentDict ];
1328 if( xDict.is() )
1330 Sequence< OUString > aEntries = xDict->getConversionEntries( ConversionDirection_FROM_LEFT );
1331 sal_uInt32 n = aEntries.getLength();
1332 OUString* pEntry = aEntries.getArray();
1333 while( n )
1335 m_xOriginalLB->append_text( *pEntry );
1337 ++pEntry;
1338 --n;
1341 else
1343 SAL_INFO( "cui.dialogs", "dictionary faded away..." );
1347 void HangulHanjaEditDictDialog::UpdateButtonStates()
1349 bool bHaveValidOriginalString = !m_aOriginal.isEmpty() && m_aOriginal != m_aEditHintText;
1350 bool bNew = bHaveValidOriginalString && m_xSuggestions && m_xSuggestions->GetCount() > 0;
1351 bNew = bNew && ( m_bModifiedSuggestions || m_bModifiedOriginal );
1353 m_xNewPB->set_sensitive( bNew );
1354 m_xDeletePB->set_sensitive(!m_bModifiedOriginal && bHaveValidOriginalString);
1357 void HangulHanjaEditDictDialog::UpdateSuggestions()
1359 Sequence< OUString > aEntries;
1360 bool bFound = GetConversions( m_rDictList[ m_nCurrentDict ], m_aOriginal, aEntries );
1361 if( bFound )
1363 m_bModifiedOriginal = false;
1365 if( m_xSuggestions )
1366 m_xSuggestions->Clear();
1368 //fill found entries into boxes
1369 sal_uInt32 nCnt = aEntries.getLength();
1370 if( nCnt )
1372 if( !m_xSuggestions )
1373 m_xSuggestions.reset(new SuggestionList);
1375 const OUString* pSugg = aEntries.getConstArray();
1376 sal_uInt32 n = 0;
1377 while( nCnt )
1379 m_xSuggestions->Set( pSugg[ n ], sal_uInt16( n ) );
1380 ++n;
1381 --nCnt;
1384 m_bModifiedSuggestions = false;
1387 m_xScrollSB->vadjustment_set_value( 0 );
1388 UpdateScrollbar(); // will force edits to be filled new
1391 void HangulHanjaEditDictDialog::SetEditText(SuggestionEdit& rEdit, sal_uInt16 nEntryNum)
1393 OUString aStr;
1394 if( m_xSuggestions )
1396 aStr = m_xSuggestions->Get(nEntryNum);
1399 rEdit.set_text(aStr);
1402 void HangulHanjaEditDictDialog::EditModify(const weld::Entry* pEdit, sal_uInt8 _nEntryOffset)
1404 m_bModifiedSuggestions = true;
1406 OUString aTxt( pEdit->get_text() );
1407 sal_uInt16 nEntryNum = m_nTopPos + _nEntryOffset;
1408 if( aTxt.isEmpty() )
1410 //reset suggestion
1411 if( m_xSuggestions )
1412 m_xSuggestions->Reset( nEntryNum );
1414 else
1416 //set suggestion
1417 if( !m_xSuggestions )
1418 m_xSuggestions.reset(new SuggestionList);
1419 m_xSuggestions->Set( aTxt, nEntryNum );
1422 UpdateButtonStates();
1425 HangulHanjaEditDictDialog::HangulHanjaEditDictDialog(weld::Window* pParent, HHDictList& _rDictList, sal_uInt32 nSelDict)
1426 : GenericDialogController(pParent, "cui/ui/hangulhanjaeditdictdialog.ui", "HangulHanjaEditDictDialog")
1427 , m_aEditHintText ( CuiResId(RID_SVXSTR_EDITHINT) )
1428 , m_rDictList ( _rDictList )
1429 , m_nCurrentDict ( 0xFFFFFFFF )
1430 , m_nTopPos ( 0 )
1431 , m_bModifiedSuggestions ( false )
1432 , m_bModifiedOriginal ( false )
1433 , m_xBookLB(m_xBuilder->weld_combo_box("book"))
1434 , m_xOriginalLB(m_xBuilder->weld_combo_box("original"))
1435 , m_xEdit1(new SuggestionEdit(m_xBuilder->weld_entry("edit1"), this))
1436 , m_xEdit2(new SuggestionEdit(m_xBuilder->weld_entry("edit2"), this))
1437 , m_xEdit3(new SuggestionEdit(m_xBuilder->weld_entry("edit3"), this))
1438 , m_xEdit4(new SuggestionEdit(m_xBuilder->weld_entry("edit4"), this))
1439 , m_xContents(m_xBuilder->weld_widget("box"))
1440 , m_xScrollSB(m_xBuilder->weld_scrolled_window("scrollbar"))
1441 , m_xNewPB(m_xBuilder->weld_button("new"))
1442 , m_xDeletePB(m_xBuilder->weld_button("delete"))
1444 m_xScrollSB->set_user_managed_scrolling();
1446 Size aSize(m_xContents->get_preferred_size());
1447 m_xScrollSB->set_size_request(-1, aSize.Height());
1449 m_xEdit1->init( m_xScrollSB.get(), nullptr, m_xEdit2.get() );
1450 m_xEdit2->init( m_xScrollSB.get(), m_xEdit1.get(), m_xEdit3.get() );
1451 m_xEdit3->init( m_xScrollSB.get(), m_xEdit2.get(), m_xEdit4.get() );
1452 m_xEdit4->init( m_xScrollSB.get(), m_xEdit3.get(), nullptr );
1454 m_xOriginalLB->connect_changed( LINK( this, HangulHanjaEditDictDialog, OriginalModifyHdl ) );
1456 m_xNewPB->connect_clicked( LINK( this, HangulHanjaEditDictDialog, NewPBPushHdl ) );
1457 m_xNewPB->set_sensitive( false );
1459 m_xDeletePB->connect_clicked( LINK( this, HangulHanjaEditDictDialog, DeletePBPushHdl ) );
1460 m_xDeletePB->set_sensitive( false );
1462 static_assert(MAXNUM_SUGGESTIONS >= 5, "number of suggestions should not under-run the value of 5");
1464 // 4 here, because we have 4 edits / page
1465 m_xScrollSB->vadjustment_configure(0, 0, MAXNUM_SUGGESTIONS, 1, 4, 4);
1466 m_xScrollSB->connect_vadjustment_changed(LINK(this, HangulHanjaEditDictDialog, ScrollHdl));
1468 m_xEdit1->connect_changed( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl1 ) );
1469 m_xEdit2->connect_changed( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl2 ) );
1470 m_xEdit3->connect_changed( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl3 ) );
1471 m_xEdit4->connect_changed( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl4 ) );
1473 m_xBookLB->connect_changed( LINK( this, HangulHanjaEditDictDialog, BookLBSelectHdl ) );
1474 sal_uInt32 nDictCnt = m_rDictList.size();
1475 for( sal_uInt32 n = 0 ; n < nDictCnt ; ++n )
1477 Reference< XConversionDictionary > xDic( m_rDictList[n] );
1478 OUString aName;
1479 if( xDic.is() )
1480 aName = xDic->getName();
1481 m_xBookLB->append_text( aName );
1483 m_xBookLB->set_active(nSelDict);
1485 InitEditDictDialog(nSelDict);
1488 HangulHanjaEditDictDialog::~HangulHanjaEditDictDialog()
1492 void HangulHanjaEditDictDialog::UpdateScrollbar()
1494 sal_uInt16 nPos = m_xScrollSB->vadjustment_get_value();
1495 m_nTopPos = nPos;
1497 SetEditText( *m_xEdit1, nPos++ );
1498 SetEditText( *m_xEdit2, nPos++ );
1499 SetEditText( *m_xEdit3, nPos++ );
1500 SetEditText( *m_xEdit4, nPos );
1504 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */