LibreOffice Module cui (master) 1
hangulhanjadlg.cxx
Go to the documentation of this file.
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 <helpids.h>
24#include <strings.hrc>
25
26#include <algorithm>
27#include <sal/log.hxx>
28#include <osl/diagnose.h>
29#include <tools/debug.hxx>
31#include <vcl/virdev.hxx>
32#include <vcl/weldutils.hxx>
33#include <unotools/lingucfg.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>
41
43#include <comphelper/string.hxx>
44
45#define HHC editeng::HangulHanjaConversion
46#define LINE_CNT static_cast< sal_uInt16 >(2)
47#define MAXNUM_SUGGESTIONS 50
48
49
50namespace svx
51{
52
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;
58
59
60 namespace
61 {
62 class FontSwitch
63 {
64 private:
66
67 public:
68 FontSwitch( OutputDevice& _rDev, const vcl::Font& _rTemporaryFont )
69 :m_rDev( _rDev )
70 {
72 m_rDev.SetFont( _rTemporaryFont );
73 }
74 ~FontSwitch() COVERITY_NOEXCEPT_FALSE
75 {
76 m_rDev.Pop();
77 }
78 };
79
83 class PseudoRubyText
84 {
85 public:
86 enum RubyPosition
87 {
88 eAbove, eBelow
89 };
90
91 protected:
95
96 public:
97 PseudoRubyText();
98 void init( const OUString& rPrimaryText, const OUString& rSecondaryText, const RubyPosition& rPosition );
99 const OUString& getPrimaryText() const { return m_sPrimaryText; }
100 const OUString& getSecondaryText() const { return m_sSecondaryText; }
101
102 public:
103 void Paint( vcl::RenderContext& _rDevice, const ::tools::Rectangle& _rRect,
104 ::tools::Rectangle* _pPrimaryLocation, ::tools::Rectangle* _pSecondaryLocation );
105 };
106
107 }
108
109 PseudoRubyText::PseudoRubyText()
110 : m_ePosition(eAbove)
111 {
112 }
113
114 void PseudoRubyText::init( const OUString& rPrimaryText, const OUString& rSecondaryText, const RubyPosition& rPosition )
115 {
116 m_sPrimaryText = rPrimaryText;
117 m_sSecondaryText = rSecondaryText;
118 m_ePosition = rPosition;
119 }
120
121
122 void PseudoRubyText::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& _rRect,
123 ::tools::Rectangle* _pPrimaryLocation, ::tools::Rectangle* _pSecondaryLocation )
124 {
125 // calculate the text flags for the painting
126 constexpr DrawTextFlags nTextStyle = DrawTextFlags::Mnemonic |
127 DrawTextFlags::Left |
128 DrawTextFlags::VCenter;
129
130 Size aPlaygroundSize(_rRect.GetSize());
131
132 // the font for the secondary text:
133 vcl::Font aSmallerFont(rRenderContext.GetFont());
134 // heuristic: 80% of the original size
135 aSmallerFont.SetFontHeight( static_cast<tools::Long>( 0.8 * aSmallerFont.GetFontHeight() ) );
136
137 // let's calculate the size of our two texts
138 ::tools::Rectangle aPrimaryRect = rRenderContext.GetTextRect( _rRect, m_sPrimaryText, nTextStyle );
139 ::tools::Rectangle aSecondaryRect;
140 {
141 FontSwitch aFontRestore(rRenderContext, aSmallerFont);
142 aSecondaryRect = rRenderContext.GetTextRect(_rRect, m_sSecondaryText, nTextStyle);
143 }
144
145 // position these rectangles properly
146 // x-axis:
147 sal_Int32 nCombinedWidth = std::max( aSecondaryRect.GetWidth(), aPrimaryRect.GetWidth() );
148 // the rectangle where both texts will reside is as high as possible, and as wide as the
149 // widest of both text rects
150 aPrimaryRect.SetLeft( _rRect.Left() );
151 aSecondaryRect.SetLeft( aPrimaryRect.Left() );
152 aPrimaryRect.SetRight( _rRect.Left() + nCombinedWidth );
153 aSecondaryRect.SetRight( aPrimaryRect.Right() );
154
155 // y-axis:
156 sal_Int32 nCombinedHeight = aPrimaryRect.GetHeight() + aSecondaryRect.GetHeight();
157 // align to the top, for the moment
158 aPrimaryRect.Move( 0, _rRect.Top() - aPrimaryRect.Top() );
159 aSecondaryRect.Move( 0, aPrimaryRect.Top() + aPrimaryRect.GetHeight() - aSecondaryRect.Top() );
160 // move the rects to the bottom
161 aPrimaryRect.Move( 0, ( aPlaygroundSize.Height() - nCombinedHeight ) / 2 );
162 aSecondaryRect.Move( 0, ( aPlaygroundSize.Height() - nCombinedHeight ) / 2 );
163
164 // 'til here, everything we did assumes that the secondary text is painted _below_ the primary
165 // text. If this isn't the case, we need to correct the rectangles
166 if (eAbove == m_ePosition)
167 {
168 sal_Int32 nVertDistance = aSecondaryRect.Top() - aPrimaryRect.Top();
169 aSecondaryRect.Move( 0, -nVertDistance );
170 aPrimaryRect.Move( 0, nCombinedHeight - nVertDistance );
171 }
172
173 // now draw the texts
174 // as we already calculated the precise rectangles for the texts, we don't want to
175 // use the alignment flags given - within its rect, every text is centered
176 DrawTextFlags nDrawTextStyle( nTextStyle );
177 nDrawTextStyle &= ~DrawTextFlags( DrawTextFlags::Right | DrawTextFlags::Left | DrawTextFlags::Bottom | DrawTextFlags::Top );
178 nDrawTextStyle |= DrawTextFlags::Center | DrawTextFlags::VCenter;
179
180 rRenderContext.DrawText( aPrimaryRect, m_sPrimaryText, nDrawTextStyle );
181 {
182 FontSwitch aFontRestore(rRenderContext, aSmallerFont);
183 rRenderContext.DrawText( aSecondaryRect, m_sSecondaryText, nDrawTextStyle );
184 }
185
186 // outta here
187 if (_pPrimaryLocation)
188 *_pPrimaryLocation = aPrimaryRect;
189 if (_pSecondaryLocation)
190 *_pSecondaryLocation = aSecondaryRect;
191 }
192
194 {
195 public:
196 RubyRadioButton(std::unique_ptr<weld::RadioButton> xControl, std::unique_ptr<weld::Image> xImage);
197 void init(const OUString& rPrimaryText, const OUString& rSecondaryText, const PseudoRubyText::RubyPosition& rPosition);
198
199 void set_sensitive(bool sensitive)
200 {
201 m_xControl->set_sensitive(sensitive);
202 m_xImage->set_sensitive(sensitive);
203 }
204 void set_active(bool active) { m_xControl->set_active(active); }
205 bool get_active() const { return m_xControl->get_active(); }
206
207 void connect_toggled(const Link<weld::Toggleable&, void>& rLink) { m_xControl->connect_toggled(rLink); }
208
209 private:
210 Size GetOptimalSize() const;
211 void Paint(vcl::RenderContext& rRenderContext);
212
214 std::unique_ptr<weld::RadioButton> m_xControl;
215 std::unique_ptr<weld::Image> m_xImage;
216 PseudoRubyText m_aRubyText;
217 };
218
219 RubyRadioButton::RubyRadioButton(std::unique_ptr<weld::RadioButton> xControl, std::unique_ptr<weld::Image> xImage)
220 : m_xVirDev(xControl->create_virtual_device())
221 , m_xControl(std::move(xControl))
222 , m_xImage(std::move(xImage))
223 {
224 // expand the point size of the desired font to the equivalent pixel size
226 }
227
228 void RubyRadioButton::init( const OUString& rPrimaryText, const OUString& rSecondaryText, const PseudoRubyText::RubyPosition& rPosition )
229 {
230 m_aRubyText.init(rPrimaryText, rSecondaryText, rPosition);
231
232 m_xVirDev->SetOutputSizePixel(GetOptimalSize());
233
235
236 m_xImage->set_image(m_xVirDev.get());
237 }
238
240 {
241 ::tools::Rectangle aOverallRect(Point(0, 0), rRenderContext.GetOutputSizePixel());
242 // inflate the rect a little bit (because the VCL radio button does the same)
243 ::tools::Rectangle aTextRect( aOverallRect );
244 aTextRect.AdjustLeft( 1 ); aTextRect.AdjustRight( -1 );
245 aTextRect.AdjustTop( 1 ); aTextRect.AdjustBottom( -1 );
246
247 // paint the ruby text
248 ::tools::Rectangle aPrimaryTextLocation;
249 ::tools::Rectangle aSecondaryTextLocation;
250
251 m_aRubyText.Paint(rRenderContext, aTextRect, &aPrimaryTextLocation, &aSecondaryTextLocation);
252 }
253
255 {
256 vcl::Font aSmallerFont(m_xVirDev->GetFont());
257 aSmallerFont.SetFontHeight( static_cast<tools::Long>( 0.8 * aSmallerFont.GetFontHeight() ) );
259
260 Size aPrimarySize = m_xVirDev->GetTextRect( rect, m_aRubyText.getPrimaryText() ).GetSize();
261 Size aSecondarySize;
262 {
263 FontSwitch aFontRestore(*m_xVirDev, aSmallerFont);
264 aSecondarySize = m_xVirDev->GetTextRect( rect, m_aRubyText.getSecondaryText() ).GetSize();
265 }
266
267 Size minimumSize;
268 minimumSize.setHeight( aPrimarySize.Height() + aSecondarySize.Height() + 5 );
269 minimumSize.setWidth(std::max(aPrimarySize.Width(), aSecondarySize.Width()) + 5 );
270 return minimumSize;
271 }
272
273 SuggestionSet::SuggestionSet(std::unique_ptr<weld::ScrolledWindow> xScrolledWindow)
274 : ValueSet(std::move(xScrolledWindow))
275
276 {
277 }
278
280 {
281 vcl::RenderContext* pDev = rUDEvt.GetRenderContext();
282 ::tools::Rectangle aRect = rUDEvt.GetRect();
283 sal_uInt16 nItemId = rUDEvt.GetItemId();
284
285 OUString sText = *static_cast< OUString* >( GetItemData( nItemId ) );
286 pDev->DrawText( aRect, sText, DrawTextFlags::Center | DrawTextFlags::VCenter );
287 }
288
290 : m_bDisplayListBox( true )
291 , m_bInSelectionUpdate( false )
292 , m_xValueSet(new SuggestionSet(rBuilder.weld_scrolled_window("scrollwin", true)))
293 , m_xValueSetWin(new weld::CustomWeld(rBuilder, "valueset", *m_xValueSet))
294 , m_xListBox(rBuilder.weld_tree_view("listbox"))
295 {
296 m_xValueSet->SetSelectHdl( LINK( this, SuggestionDisplay, SelectSuggestionValueSetHdl ) );
297 m_xListBox->connect_changed( LINK( this, SuggestionDisplay, SelectSuggestionListBoxHdl ) );
298
299 m_xValueSet->SetLineCount( LINE_CNT );
300 m_xValueSet->SetStyle( m_xValueSet->GetStyle() | WB_ITEMBORDER | WB_VSCROLL );
301
302 auto nItemWidth = 2 * m_xListBox->get_pixel_size("AU").Width();
303 m_xValueSet->SetItemWidth( nItemWidth );
304
305 Size aSize(m_xListBox->get_approximate_digit_width() * 42, m_xListBox->get_text_height() * 5);
306 m_xValueSet->set_size_request(aSize.Width(), aSize.Height());
307 m_xListBox->set_size_request(aSize.Width(), aSize.Height());
308
310 }
311
313 {
314 m_xListBox->set_visible(m_bDisplayListBox);
316 m_xValueSetWin->show();
317 else
318 m_xValueSetWin->hide();
319 }
320
322 {
324 return *m_xListBox;
325 return *m_xValueSet->GetDrawingArea();
326 }
327
328 void SuggestionDisplay::DisplayListBox( bool bDisplayListBox )
329 {
330 if( m_bDisplayListBox == bDisplayListBox )
331 return;
332
333 weld::Widget& rOldControl = implGetCurrentControl();
334 bool bHasFocus = rOldControl.has_focus();
335
336 m_bDisplayListBox = bDisplayListBox;
337
338 if( bHasFocus )
339 {
340 weld::Widget& rNewControl = implGetCurrentControl();
341 rNewControl.grab_focus();
342 }
343
345 }
346
347 IMPL_LINK_NOARG(SuggestionDisplay, SelectSuggestionValueSetHdl, ValueSet*, void)
348 {
349 SelectSuggestionHdl(false);
350 }
351
352 IMPL_LINK_NOARG(SuggestionDisplay, SelectSuggestionListBoxHdl, weld::TreeView&, void)
353 {
354 SelectSuggestionHdl(true);
355 }
356
358 {
360 return;
361
363 if (bListBox)
364 {
365 sal_uInt16 nPos = m_xListBox->get_selected_index();
366 m_xValueSet->SelectItem( nPos+1 ); //itemid == pos+1 (id 0 has special meaning)
367 }
368 else
369 {
370 sal_uInt16 nPos = m_xValueSet->GetSelectedItemId()-1; //itemid == pos+1 (id 0 has special meaning)
371 m_xListBox->select(nPos);
372 }
373 m_bInSelectionUpdate = false;
374 m_aSelectLink.Call( *this );
375 }
376
378 {
379 m_aSelectLink = rLink;
380 }
381
383 {
384 m_xListBox->clear();
385 m_xValueSet->Clear();
386 }
387
388 void SuggestionDisplay::InsertEntry( const OUString& rStr )
389 {
390 m_xListBox->append_text(rStr);
391 sal_uInt16 nItemId = m_xListBox->n_children(); //itemid == pos+1 (id 0 has special meaning)
392 m_xValueSet->InsertItem( nItemId );
393 OUString* pItemData = new OUString( rStr );
394 m_xValueSet->SetItemData( nItemId, pItemData );
395 }
396
397 void SuggestionDisplay::SelectEntryPos( sal_uInt16 nPos )
398 {
399 m_xListBox->select(nPos);
400 m_xValueSet->SelectItem( nPos+1 ); //itemid == pos+1 (id 0 has special meaning)
401 }
402
404 {
405 return m_xListBox->n_children();
406 }
407
408 OUString SuggestionDisplay::GetEntry( sal_uInt16 nPos ) const
409 {
410 return m_xListBox->get_text( nPos );
411 }
412
414 {
415 return m_xListBox->get_selected_text();
416 }
417
419 {
422 }
423
425 : GenericDialogController(pParent, "cui/ui/hangulhanjaconversiondialog.ui", "HangulHanjaConversionDialog")
426 , m_bDocumentMode( true )
427 , m_xFind(m_xBuilder->weld_button("find"))
428 , m_xIgnore(m_xBuilder->weld_button("ignore"))
429 , m_xIgnoreAll(m_xBuilder->weld_button("ignoreall"))
430 , m_xReplace(m_xBuilder->weld_button("replace"))
431 , m_xReplaceAll(m_xBuilder->weld_button("replaceall"))
432 , m_xOptions(m_xBuilder->weld_button("options"))
433 , m_xSuggestions(new SuggestionDisplay(*m_xBuilder))
434 , m_xSimpleConversion(m_xBuilder->weld_radio_button("simpleconversion"))
435 , m_xHangulBracketed(m_xBuilder->weld_radio_button("hangulbracket"))
436 , m_xHanjaBracketed(m_xBuilder->weld_radio_button("hanjabracket"))
437 , m_xWordInput(m_xBuilder->weld_entry("wordinput"))
438 , m_xOriginalWord(m_xBuilder->weld_label("originalword"))
439 , m_xHanjaAbove(new RubyRadioButton(m_xBuilder->weld_radio_button("hanja_above"),
440 m_xBuilder->weld_image("hanja_above_img")))
441 , m_xHanjaBelow(new RubyRadioButton(m_xBuilder->weld_radio_button("hanja_below"),
442 m_xBuilder->weld_image("hanja_below_img")))
443 , m_xHangulAbove(new RubyRadioButton(m_xBuilder->weld_radio_button("hangul_above"),
444 m_xBuilder->weld_image("hangul_above_img")))
445 , m_xHangulBelow(new RubyRadioButton(m_xBuilder->weld_radio_button("hangul_below"),
446 m_xBuilder->weld_image("hangul_below_img")))
447 , m_xHangulOnly(m_xBuilder->weld_check_button("hangulonly"))
448 , m_xHanjaOnly(m_xBuilder->weld_check_button("hanjaonly"))
449 , m_xReplaceByChar(m_xBuilder->weld_check_button("replacebychar"))
450 {
451 m_xSuggestions->set_size_request(m_xOriginalWord->get_approximate_digit_width() * 42,
452 m_xOriginalWord->get_text_height() * 5);
453
454 const OUString sHangul(CuiResId(RID_CUISTR_HANGUL));
455 const OUString sHanja(CuiResId(RID_CUISTR_HANJA));
456 m_xHanjaAbove->init( sHangul, sHanja, PseudoRubyText::eAbove );
457 m_xHanjaBelow->init( sHangul, sHanja, PseudoRubyText::eBelow );
458 m_xHangulAbove->init( sHanja, sHangul, PseudoRubyText::eAbove );
459 m_xHangulBelow->init( sHanja, sHangul, PseudoRubyText::eBelow );
460
461 m_xWordInput->connect_changed( LINK( this, HangulHanjaConversionDialog, OnSuggestionModified ) );
462 m_xSuggestions->SetSelectHdl( LINK( this, HangulHanjaConversionDialog, OnSuggestionSelected ) );
463 m_xReplaceByChar->connect_toggled( LINK( this, HangulHanjaConversionDialog, ClickByCharacterHdl ) );
464 m_xHangulOnly->connect_toggled( LINK( this, HangulHanjaConversionDialog, OnConversionDirectionClicked ) );
465 m_xHanjaOnly->connect_toggled( LINK( this, HangulHanjaConversionDialog, OnConversionDirectionClicked ) );
466 m_xOptions->connect_clicked(LINK(this, HangulHanjaConversionDialog, OnOption));
467
468 // initial focus
470
471 // initial control values
472 m_xSimpleConversion->set_active(true);
473
474 m_xSuggestions->SetHelpIds();
475 }
476
478 {
479 }
480
481 void HangulHanjaConversionDialog::FillSuggestions( const css::uno::Sequence< OUString >& _rSuggestions )
482 {
483 m_xSuggestions->Clear();
484 for ( auto const & suggestion : _rSuggestions )
485 m_xSuggestions->InsertEntry( suggestion );
486
487 // select the first suggestion, and fill in the suggestion edit field
488 OUString sFirstSuggestion;
489 if ( m_xSuggestions->GetEntryCount() )
490 {
491 sFirstSuggestion = m_xSuggestions->GetEntry( 0 );
492 m_xSuggestions->SelectEntryPos( 0 );
493 }
494 m_xWordInput->set_text( sFirstSuggestion );
495 m_xWordInput->save_value();
496 OnSuggestionModified( *m_xWordInput );
497 }
498
500 {
502 }
503
505 {
506 m_xIgnore->connect_clicked(rHdl);
507 }
508
510 {
511 m_xIgnoreAll->connect_clicked(rHdl);
512 }
513
515 {
516 m_xReplace->connect_clicked(rHdl);
517 }
518
520 {
521 m_xReplaceAll->connect_clicked(rHdl);
522 }
523
525 {
526 m_xFind->connect_clicked(rHdl);
527 }
528
530 {
531 m_xSimpleConversion->connect_toggled( rHdl );
532 m_xHangulBracketed->connect_toggled( rHdl );
533 m_xHanjaBracketed->connect_toggled( rHdl );
534 m_xHanjaAbove->connect_toggled( rHdl );
535 m_xHanjaBelow->connect_toggled( rHdl );
536 m_xHangulAbove->connect_toggled( rHdl );
537 m_xHangulBelow->connect_toggled( rHdl );
538 }
539
541 {
543 }
544
546 {
547 m_xWordInput->set_text(m_xSuggestions->GetSelectedEntry());
548 OnSuggestionModified( *m_xWordInput );
549 }
550
552 {
553 m_xFind->set_sensitive(m_xWordInput->get_value_changed_from_saved());
554
555 bool bSameLen = m_xWordInput->get_text().getLength() == m_xOriginalWord->get_label().getLength();
556 m_xReplace->set_sensitive( m_bDocumentMode && bSameLen );
557 m_xReplaceAll->set_sensitive( m_bDocumentMode && bSameLen );
558 }
559
560 IMPL_LINK(HangulHanjaConversionDialog, ClickByCharacterHdl, weld::Toggleable&, rBox, void)
561 {
562 m_aClickByCharacterLink.Call(rBox);
563 bool bByCharacter = rBox.get_active();
564 m_xSuggestions->DisplayListBox( !bByCharacter );
565 }
566
567 IMPL_LINK(HangulHanjaConversionDialog, OnConversionDirectionClicked, weld::Toggleable&, rBox, void)
568 {
569 weld::CheckButton* pOtherBox = nullptr;
570 if (&rBox == m_xHangulOnly.get())
571 pOtherBox = m_xHanjaOnly.get();
572 else
573 pOtherBox = m_xHangulOnly.get();
574 bool bBoxChecked = rBox.get_active();
575 if (bBoxChecked)
576 pOtherBox->set_active(false);
577 pOtherBox->set_sensitive(!bBoxChecked);
578 }
579
581 {
582 HangulHanjaOptionsDialog aOptDlg(m_xDialog.get());
583 aOptDlg.run();
584 m_aOptionsChangedLink.Call( nullptr );
585 }
586
588 {
589 return m_xOriginalWord->get_label();
590 }
591
593 {
594 m_xWordInput->grab_focus();
595 }
596
597 void HangulHanjaConversionDialog::SetCurrentString( const OUString& _rNewString,
598 const Sequence< OUString >& _rSuggestions, bool _bOriginatesFromDocument )
599 {
600 m_xOriginalWord->set_label(_rNewString);
601
602 bool bOldDocumentMode = m_bDocumentMode;
603 m_bDocumentMode = _bOriginatesFromDocument; // before FillSuggestions!
604 FillSuggestions( _rSuggestions );
605
606 m_xIgnoreAll->set_sensitive( m_bDocumentMode );
607
608 // switch the def button depending if we're working for document text
609 if (bOldDocumentMode == m_bDocumentMode)
610 return;
611
612 weld::Widget* pOldDefButton = nullptr;
613 weld::Widget* pNewDefButton = nullptr;
614 if (m_bDocumentMode)
615 {
616 pOldDefButton = m_xFind.get();
617 pNewDefButton = m_xReplace.get();
618 }
619 else
620 {
621 pOldDefButton = m_xReplace.get();
622 pNewDefButton = m_xFind.get();
623 }
624
625 m_xDialog->change_default_widget(pOldDefButton, pNewDefButton);
626 }
627
629 {
630 return m_xWordInput->get_text();
631 }
632
634 {
635 m_xReplaceByChar->set_active( _bByCharacter );
636 m_xSuggestions->DisplayListBox( !_bByCharacter );
637 }
638
640 bool _bTryBothDirections,
641 HHC::ConversionDirection ePrimaryConversionDirection )
642 {
643 // default state: try both direction
644 m_xHangulOnly->set_active( false );
645 m_xHangulOnly->set_sensitive(true);
646 m_xHanjaOnly->set_active( false );
647 m_xHanjaOnly->set_sensitive(true);
648
649 if (!_bTryBothDirections)
650 {
651 weld::CheckButton* pBox = ePrimaryConversionDirection == HHC::eHangulToHanja ?
652 m_xHangulOnly.get() : m_xHanjaOnly.get();
653 pBox->set_active(true);
654 OnConversionDirectionClicked(*pBox);
655 }
656 }
657
659 {
660 return !m_xHangulOnly->get_active() && !m_xHanjaOnly->get_active();
661 }
662
664 HHC::ConversionDirection eDefaultDirection ) const
665 {
666 HHC::ConversionDirection eDirection = eDefaultDirection;
667 if (m_xHangulOnly->get_active() && !m_xHanjaOnly->get_active())
668 eDirection = HHC::eHangulToHanja;
669 else if (!m_xHangulOnly->get_active() && m_xHanjaOnly->get_active())
670 eDirection = HHC::eHanjaToHangul;
671 return eDirection;
672 }
673
674 void HangulHanjaConversionDialog::SetConversionFormat( HHC::ConversionFormat _eType )
675 {
676 switch ( _eType )
677 {
678 case HHC::eSimpleConversion: m_xSimpleConversion->set_active(true); break;
679 case HHC::eHangulBracketed: m_xHangulBracketed->set_active(true); break;
680 case HHC::eHanjaBracketed: m_xHanjaBracketed->set_active(true); break;
681 case HHC::eRubyHanjaAbove: m_xHanjaAbove->set_active(true); break;
682 case HHC::eRubyHanjaBelow: m_xHanjaBelow->set_active(true); break;
683 case HHC::eRubyHangulAbove: m_xHangulAbove->set_active(true); break;
684 case HHC::eRubyHangulBelow: m_xHangulBelow->set_active(true); break;
685 default:
686 OSL_FAIL( "HangulHanjaConversionDialog::SetConversionFormat: unknown type!" );
687 }
688 }
689
691 {
692 if ( m_xSimpleConversion->get_active() )
693 return HHC::eSimpleConversion;
694 if ( m_xHangulBracketed->get_active() )
695 return HHC::eHangulBracketed;
696 if ( m_xHanjaBracketed->get_active() )
697 return HHC::eHanjaBracketed;
698 if ( m_xHanjaAbove->get_active() )
699 return HHC::eRubyHanjaAbove;
700 if ( m_xHanjaBelow->get_active() )
701 return HHC::eRubyHanjaBelow;
702 if ( m_xHangulAbove->get_active() )
703 return HHC::eRubyHangulAbove;
704 if ( m_xHangulBelow->get_active() )
705 return HHC::eRubyHangulBelow;
706
707 OSL_FAIL( "HangulHanjaConversionDialog::GetConversionFormat: no radio checked?" );
708 return HHC::eSimpleConversion;
709 }
710
712 {
713 m_xHanjaAbove->set_sensitive( bVal );
714 m_xHanjaBelow->set_sensitive( bVal );
715 m_xHangulAbove->set_sensitive( bVal );
716 m_xHangulBelow->set_sensitive( bVal );
717 }
718
720 {
722 {
723 m_xConversionDictionaryList = ConversionDictionaryList::create( ::comphelper::getProcessComponentContext() );
724 }
725
726 m_aDictList.clear();
727 m_xDictsLB->clear();
728
729 Reference< XNameContainer > xNameCont = m_xConversionDictionaryList->getDictionaryContainer();
730 if( xNameCont.is() )
731 {
732 Sequence< OUString > aDictNames( xNameCont->getElementNames() );
733
734 const OUString* pDic = aDictNames.getConstArray();
735 sal_Int32 nCount = aDictNames.getLength();
736
737 sal_Int32 i;
738 for( i = 0 ; i < nCount ; ++i )
739 {
740 Any aAny( xNameCont->getByName( pDic[ i ] ) );
741 Reference< XConversionDictionary > xDic;
742 if( ( aAny >>= xDic ) && xDic.is() )
743 {
744 if( LANGUAGE_KOREAN == LanguageTag( xDic->getLocale() ).getLanguageType() )
745 {
746 m_aDictList.push_back( xDic );
747 AddDict( xDic->getName(), xDic->isActive() );
748 }
749 }
750 }
751 }
752 if (m_xDictsLB->n_children())
753 m_xDictsLB->select(0);
754 }
755
757 {
758 sal_uInt32 nCnt = m_aDictList.size();
759 sal_uInt32 n = 0;
760 sal_uInt32 nActiveDics = 0;
761 Sequence< OUString > aActiveDics;
762
763 aActiveDics.realloc( nCnt );
764 OUString* pActActiveDic = aActiveDics.getArray();
765
766 while( nCnt )
767 {
768 Reference< XConversionDictionary > xDict = m_aDictList[ n ];
769
770 DBG_ASSERT( xDict.is(), "-HangulHanjaOptionsDialog::OkHdl(): someone is evaporated..." );
771
772 bool bActive = m_xDictsLB->get_toggle(n) == TRISTATE_TRUE;
773 xDict->setActive( bActive );
774 Reference< util::XFlushable > xFlush( xDict, uno::UNO_QUERY );
775 if( xFlush.is() )
776 xFlush->flush();
777
778 if( bActive )
779 {
780 pActActiveDic[ nActiveDics ] = xDict->getName();
781 ++nActiveDics;
782 }
783
784 ++n;
785 --nCnt;
786 }
787
788 // save configuration
789 aActiveDics.realloc( nActiveDics );
790 Any aTmp;
791 SvtLinguConfig aLngCfg;
792 aTmp <<= aActiveDics;
794
795 aTmp <<= m_xIgnorepostCB->get_active();
797
798 aTmp <<= m_xShowrecentlyfirstCB->get_active();
800
801 aTmp <<= m_xAutoreplaceuniqueCB->get_active();
803
804 m_xDialog->response(RET_OK);
805 }
806
808 {
809 bool bSel = m_xDictsLB->get_selected_index() != -1;
810
811 m_xEditPB->set_sensitive(bSel);
812 m_xDeletePB->set_sensitive(bSel);
813 }
814
816 {
817 OUString aName;
818 HangulHanjaNewDictDialog aNewDlg(m_xDialog.get());
819 aNewDlg.run();
820 if (!aNewDlg.GetName(aName))
821 return;
822
823 if( !m_xConversionDictionaryList.is() )
824 return;
825
826 try
827 {
828 Reference< XConversionDictionary > xDic =
829 m_xConversionDictionaryList->addNewDictionary( aName, LanguageTag::convertToLocale( LANGUAGE_KOREAN ), ConversionDictionaryType::HANGUL_HANJA );
830
831 if( xDic.is() )
832 {
833 //adapt local caches:
834 m_aDictList.push_back( xDic );
835 AddDict( xDic->getName(), xDic->isActive() );
836 }
837 }
838 catch( const ElementExistException& )
839 {
840 }
841 catch( const NoSupportException& )
842 {
843 }
844 }
845
847 {
848 int nEntry = m_xDictsLB->get_selected_index();
849 DBG_ASSERT(nEntry != -1, "+HangulHanjaEditDictDialog::EditDictHdl(): call of edit should not be possible with no selection!");
850 if (nEntry != -1)
851 {
852 HangulHanjaEditDictDialog aEdDlg(m_xDialog.get(), m_aDictList, nEntry);
853 aEdDlg.run();
854 }
855 }
856
858 {
859 int nSelPos = m_xDictsLB->get_selected_index();
860 if (nSelPos == -1)
861 return;
862
863 Reference< XConversionDictionary > xDic( m_aDictList[ nSelPos ] );
864 if( !(m_xConversionDictionaryList.is() && xDic.is()) )
865 return;
866
867 Reference< XNameContainer > xNameCont = m_xConversionDictionaryList->getDictionaryContainer();
868 if( !xNameCont.is() )
869 return;
870
871 try
872 {
873 xNameCont->removeByName( xDic->getName() );
874
875 //adapt local caches:
876 m_aDictList.erase(m_aDictList.begin()+nSelPos );
877 m_xDictsLB->remove(nSelPos);
878 }
879 catch( const ElementExistException& )
880 {
881 }
882 catch( const NoSupportException& )
883 {
884 }
885 }
886
888 : GenericDialogController(pParent, "cui/ui/hangulhanjaoptdialog.ui", "HangulHanjaOptDialog")
889 , m_xDictsLB(m_xBuilder->weld_tree_view("dicts"))
890 , m_xIgnorepostCB(m_xBuilder->weld_check_button("ignorepost"))
891 , m_xShowrecentlyfirstCB(m_xBuilder->weld_check_button("showrecentfirst"))
892 , m_xAutoreplaceuniqueCB(m_xBuilder->weld_check_button("autoreplaceunique"))
893 , m_xNewPB(m_xBuilder->weld_button("new"))
894 , m_xEditPB(m_xBuilder->weld_button("edit"))
895 , m_xDeletePB(m_xBuilder->weld_button("delete"))
896 , m_xOkPB(m_xBuilder->weld_button("ok"))
897 {
898 m_xDictsLB->set_size_request(m_xDictsLB->get_approximate_digit_width() * 32,
899 m_xDictsLB->get_height_rows(5));
900
901 m_xDictsLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
902
903 m_xDictsLB->connect_changed( LINK( this, HangulHanjaOptionsDialog, DictsLB_SelectHdl ) );
904
905 m_xOkPB->connect_clicked( LINK( this, HangulHanjaOptionsDialog, OkHdl ) );
906 m_xNewPB->connect_clicked( LINK( this, HangulHanjaOptionsDialog, NewDictHdl ) );
907 m_xEditPB->connect_clicked( LINK( this, HangulHanjaOptionsDialog, EditDictHdl ) );
908 m_xDeletePB->connect_clicked( LINK( this, HangulHanjaOptionsDialog, DeleteDictHdl ) );
909
910 SvtLinguConfig aLngCfg;
911 Any aTmp;
912 bool bVal = bool();
914 if( aTmp >>= bVal )
915 m_xIgnorepostCB->set_active( bVal );
916
918 if( aTmp >>= bVal )
919 m_xShowrecentlyfirstCB->set_active( bVal );
920
922 if( aTmp >>= bVal )
923 m_xAutoreplaceuniqueCB->set_active( bVal );
924
925 Init();
926 }
927
929 {
930 }
931
932 void HangulHanjaOptionsDialog::AddDict(const OUString& rName, bool bChecked)
933 {
934 m_xDictsLB->append();
935 int nRow = m_xDictsLB->n_children() - 1;
936 m_xDictsLB->set_toggle(nRow, bChecked ? TRISTATE_TRUE : TRISTATE_FALSE);
937 m_xDictsLB->set_text(nRow, rName, 0);
938 m_xDictsLB->set_id(nRow, rName);
939 }
940
942 {
943 OUString aName(comphelper::string::stripEnd(m_xDictNameED->get_text(), ' '));
944
945 m_bEntered = !aName.isEmpty();
946 if (m_bEntered)
947 m_xDictNameED->set_text(aName); // do this in case of trailing chars have been deleted
948
949 m_xDialog->response(RET_OK);
950 }
951
953 {
954 OUString aName(comphelper::string::stripEnd(m_xDictNameED->get_text(), ' '));
955
956 m_xOkBtn->set_sensitive(!aName.isEmpty());
957 }
958
960 : GenericDialogController(pParent, "cui/ui/hangulhanjaadddialog.ui", "HangulHanjaAddDialog")
961 , m_bEntered(false)
962 , m_xOkBtn(m_xBuilder->weld_button("ok"))
963 , m_xDictNameED(m_xBuilder->weld_entry("entry"))
964 {
965 m_xOkBtn->connect_clicked( LINK( this, HangulHanjaNewDictDialog, OKHdl ) );
966 m_xDictNameED->connect_changed( LINK( this, HangulHanjaNewDictDialog, ModifyHdl ) );
967 }
968
970 {
971 }
972
973 bool HangulHanjaNewDictDialog::GetName( OUString& _rRetName ) const
974 {
975 if( m_bEntered )
976 _rRetName = comphelper::string::stripEnd(m_xDictNameED->get_text(), ' ');
977
978 return m_bEntered;
979 }
980
982 {
983 private:
984 protected:
985 std::vector<OUString> m_vElements;
986 sal_uInt16 m_nNumOfEntries;
987 // index of the internal iterator, used for First() and Next() methods
988 sal_uInt16 m_nAct;
989
990 const OUString* Next_();
991 public:
994
995 void Set( const OUString& _rElement, sal_uInt16 _nNumOfElement );
996 void Reset( sal_uInt16 _nNumOfElement );
997 const OUString & Get( sal_uInt16 _nNumOfElement ) const;
998 void Clear();
999
1000 const OUString* First();
1001 const OUString* Next();
1002
1003 sal_uInt16 GetCount() const { return m_nNumOfEntries; }
1004 };
1005
1007 m_vElements(MAXNUM_SUGGESTIONS)
1008 {
1009 m_nAct = m_nNumOfEntries = 0;
1010 }
1011
1013 {
1014 Clear();
1015 }
1016
1017 void SuggestionList::Set( const OUString& _rElement, sal_uInt16 _nNumOfElement )
1018 {
1019 m_vElements[_nNumOfElement] = _rElement;
1021 }
1022
1023 void SuggestionList::Reset( sal_uInt16 _nNumOfElement )
1024 {
1025 m_vElements[_nNumOfElement].clear();
1027 }
1028
1029 const OUString& SuggestionList::Get( sal_uInt16 _nNumOfElement ) const
1030 {
1031 return m_vElements[_nNumOfElement];
1032 }
1033
1035 {
1036 if( m_nNumOfEntries )
1037 {
1038 for (auto & vElement : m_vElements)
1039 vElement.clear();
1040 m_nNumOfEntries = m_nAct = 0;
1041 }
1042 }
1043
1044 const OUString* SuggestionList::Next_()
1045 {
1046 while( m_nAct < m_vElements.size() )
1047 {
1048 auto & s = m_vElements[ m_nAct ];
1049 if (!s.isEmpty())
1050 return &s;
1051 ++m_nAct;
1052 }
1053
1054 return nullptr;
1055 }
1056
1057 const OUString* SuggestionList::First()
1058 {
1059 m_nAct = 0;
1060 return Next_();
1061 }
1062
1063 const OUString* SuggestionList::Next()
1064 {
1065 const OUString* pRet;
1066
1067 if( m_nAct < m_nNumOfEntries )
1068 {
1069 ++m_nAct;
1070 pRet = Next_();
1071 }
1072 else
1073 pRet = nullptr;
1074
1075 return pRet;
1076 }
1077
1078
1079 bool SuggestionEdit::ShouldScroll( bool _bUp ) const
1080 {
1081 bool bRet = false;
1082
1083 if( _bUp )
1084 {
1085 if( !m_pPrev )
1087 }
1088 else
1089 {
1090 if( !m_pNext )
1092 }
1093
1094 return bRet;
1095 }
1096
1097 void SuggestionEdit::DoJump( bool _bUp )
1098 {
1101 }
1102
1103 SuggestionEdit::SuggestionEdit(std::unique_ptr<weld::Entry> xEntry, HangulHanjaEditDictDialog* pParent)
1104 : m_pParent(pParent)
1105 , m_pPrev(nullptr)
1106 , m_pNext(nullptr)
1107 , m_pScrollBar(nullptr)
1108 , m_xEntry(std::move(xEntry))
1109 {
1110 m_xEntry->connect_key_press(LINK(this, SuggestionEdit, KeyInputHdl));
1111 }
1112
1113 IMPL_LINK(SuggestionEdit, KeyInputHdl, const KeyEvent&, rKEvt, bool)
1114 {
1115 bool bHandled = false;
1116
1117 const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
1118 sal_uInt16 nMod = rKeyCode.GetModifier();
1119 sal_uInt16 nCode = rKeyCode.GetCode();
1120 if( nCode == KEY_TAB && ( !nMod || KEY_SHIFT == nMod ) )
1121 {
1122 bool bUp = KEY_SHIFT == nMod;
1123 if( ShouldScroll( bUp ) )
1124 {
1125 DoJump( bUp );
1126 m_xEntry->select_region(0, -1);
1127 // Tab-travel doesn't really happen, so emulate it by setting a selection manually
1128 bHandled = true;
1129 }
1130 }
1131 else if( KEY_UP == nCode || KEY_DOWN == nCode )
1132 {
1133 bool bUp = KEY_UP == nCode;
1134 if( ShouldScroll( bUp ) )
1135 {
1136 DoJump( bUp );
1137 bHandled = true;
1138 }
1139 else if( bUp )
1140 {
1141 if( m_pPrev )
1142 {
1143 m_pPrev->grab_focus();
1144 bHandled = true;
1145 }
1146 }
1147 else if( m_pNext )
1148 {
1149 m_pNext->grab_focus();
1150 bHandled = true;
1151 }
1152 }
1153
1154 return bHandled;
1155 }
1156
1158 {
1159 m_pScrollBar = pScrollBar;
1160 m_pPrev = pPrev;
1161 m_pNext = pNext;
1162 }
1163
1164 namespace
1165 {
1166 bool GetConversions( const Reference< XConversionDictionary >& _xDict,
1167 const OUString& _rOrg,
1168 Sequence< OUString >& _rEntries )
1169 {
1170 bool bRet = false;
1171 if( _xDict.is() && !_rOrg.isEmpty() )
1172 {
1173 try
1174 {
1175 _rEntries = _xDict->getConversions( _rOrg,
1176 0,
1177 _rOrg.getLength(),
1178 ConversionDirection_FROM_LEFT,
1179 css::i18n::TextConversionOption::NONE );
1180 bRet = _rEntries.hasElements();
1181 }
1182 catch( const IllegalArgumentException& )
1183 {
1184 }
1185 }
1186
1187 return bRet;
1188 }
1189 }
1190
1192 {
1193 UpdateScrollbar();
1194 }
1195
1197 {
1198 m_bModifiedOriginal = true;
1199 m_aOriginal = comphelper::string::stripEnd( m_xOriginalLB->get_active_text(), ' ' );
1200
1201 UpdateSuggestions();
1202 UpdateButtonStates();
1203 }
1204
1205 IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl1, weld::Entry&, rEdit, void )
1206 {
1207 EditModify( &rEdit, 0 );
1208 }
1209
1210 IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl2, weld::Entry&, rEdit, void )
1211 {
1212 EditModify( &rEdit, 1 );
1213 }
1214
1215 IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl3, weld::Entry&, rEdit, void )
1216 {
1217 EditModify( &rEdit, 2 );
1218 }
1219
1220 IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl4, weld::Entry&, rEdit, void )
1221 {
1222 EditModify( &rEdit, 3 );
1223 }
1224
1226 {
1227 InitEditDictDialog( m_xBookLB->get_active() );
1228 }
1229
1231 {
1232 DBG_ASSERT( m_xSuggestions, "-HangulHanjaEditDictDialog::NewPBPushHdl(): no suggestions... search in hell..." );
1233 Reference< XConversionDictionary > xDict = m_rDictList[ m_nCurrentDict ];
1234 if( xDict.is() && m_xSuggestions )
1235 {
1236 //delete old entry
1237 bool bRemovedSomething = DeleteEntryFromDictionary( xDict );
1238
1239 OUString aLeft( m_aOriginal );
1240 const OUString* pRight = m_xSuggestions->First();
1241 bool bAddedSomething = false;
1242 while( pRight )
1243 {
1244 try
1245 {
1246 //add new entry
1247 xDict->addEntry( aLeft, *pRight );
1248 bAddedSomething = true;
1249 }
1250 catch( const IllegalArgumentException& )
1251 {
1252 }
1253 catch( const ElementExistException& )
1254 {
1255 }
1256
1257 pRight = m_xSuggestions->Next();
1258 }
1259
1260 if( bAddedSomething || bRemovedSomething )
1261 InitEditDictDialog( m_nCurrentDict );
1262 }
1263 else
1264 {
1265 SAL_INFO( "cui.dialogs", "dictionary faded away..." );
1266 }
1267 }
1268
1269 bool HangulHanjaEditDictDialog::DeleteEntryFromDictionary( const Reference< XConversionDictionary >& xDict )
1270 {
1271 bool bRemovedSomething = false;
1272 if( xDict.is() )
1273 {
1274 OUString aOrg( m_aOriginal );
1276 GetConversions( xDict, m_aOriginal, aEntries );
1277
1278 sal_uInt32 n = aEntries.getLength();
1279 OUString* pEntry = aEntries.getArray();
1280 while( n )
1281 {
1282 try
1283 {
1284 xDict->removeEntry( aOrg, *pEntry );
1285 bRemovedSomething = true;
1286 }
1287 catch( const NoSuchElementException& )
1288 { // can not be...
1289 }
1290
1291 ++pEntry;
1292 --n;
1293 }
1294 }
1295 return bRemovedSomething;
1296 }
1297
1299 {
1300 if( DeleteEntryFromDictionary( m_rDictList[ m_nCurrentDict ] ) )
1301 {
1302 m_aOriginal.clear();
1303 m_bModifiedOriginal = true;
1304 InitEditDictDialog( m_nCurrentDict );
1305 }
1306 }
1307
1309 {
1310 if( m_xSuggestions )
1311 m_xSuggestions->Clear();
1312
1313 if( m_nCurrentDict != nSelDict )
1314 {
1315 m_nCurrentDict = nSelDict;
1316 m_aOriginal.clear();
1317 m_bModifiedOriginal = true;
1318 }
1319
1321
1322 m_xOriginalLB->set_entry_text( !m_aOriginal.isEmpty() ? m_aOriginal : m_aEditHintText);
1323 m_xOriginalLB->select_entry_region(0, -1);
1324 m_xOriginalLB->grab_focus();
1325
1328 }
1329
1331 {
1332 m_xOriginalLB->clear();
1333 Reference< XConversionDictionary > xDict = m_rDictList[ m_nCurrentDict ];
1334 if( xDict.is() )
1335 {
1336 Sequence< OUString > aEntries = xDict->getConversionEntries( ConversionDirection_FROM_LEFT );
1337 sal_uInt32 n = aEntries.getLength();
1338 OUString* pEntry = aEntries.getArray();
1339 while( n )
1340 {
1341 m_xOriginalLB->append_text( *pEntry );
1342
1343 ++pEntry;
1344 --n;
1345 }
1346 }
1347 else
1348 {
1349 SAL_INFO( "cui.dialogs", "dictionary faded away..." );
1350 }
1351 }
1352
1354 {
1355 bool bHaveValidOriginalString = !m_aOriginal.isEmpty() && m_aOriginal != m_aEditHintText;
1356 bool bNew = bHaveValidOriginalString && m_xSuggestions && m_xSuggestions->GetCount() > 0;
1357 bNew = bNew && ( m_bModifiedSuggestions || m_bModifiedOriginal );
1358
1359 m_xNewPB->set_sensitive( bNew );
1360 m_xDeletePB->set_sensitive(!m_bModifiedOriginal && bHaveValidOriginalString);
1361 }
1362
1364 {
1366 bool bFound = GetConversions( m_rDictList[ m_nCurrentDict ], m_aOriginal, aEntries );
1367 if( bFound )
1368 {
1369 m_bModifiedOriginal = false;
1370
1371 if( m_xSuggestions )
1372 m_xSuggestions->Clear();
1373
1374 //fill found entries into boxes
1375 sal_uInt32 nCnt = aEntries.getLength();
1376 if( nCnt )
1377 {
1378 if( !m_xSuggestions )
1379 m_xSuggestions.reset(new SuggestionList);
1380
1381 const OUString* pSugg = aEntries.getConstArray();
1382 sal_uInt32 n = 0;
1383 while( nCnt )
1384 {
1385 m_xSuggestions->Set( pSugg[ n ], sal_uInt16( n ) );
1386 ++n;
1387 --nCnt;
1388 }
1389 }
1390 m_bModifiedSuggestions = false;
1391 }
1392
1393 m_xScrollSB->vadjustment_set_value( 0 );
1394 UpdateScrollbar(); // will force edits to be filled new
1395 }
1396
1398 {
1399 OUString aStr;
1400 if( m_xSuggestions )
1401 {
1402 aStr = m_xSuggestions->Get(nEntryNum);
1403 }
1404
1405 rEdit.set_text(aStr);
1406 }
1407
1409 {
1411
1412 OUString aTxt( pEdit->get_text() );
1413 sal_uInt16 nEntryNum = m_nTopPos + _nEntryOffset;
1414 if( aTxt.isEmpty() )
1415 {
1416 //reset suggestion
1417 if( m_xSuggestions )
1418 m_xSuggestions->Reset( nEntryNum );
1419 }
1420 else
1421 {
1422 //set suggestion
1423 if( !m_xSuggestions )
1424 m_xSuggestions.reset(new SuggestionList);
1425 m_xSuggestions->Set( aTxt, nEntryNum );
1426 }
1427
1429 }
1430
1432 : GenericDialogController(pParent, "cui/ui/hangulhanjaeditdictdialog.ui", "HangulHanjaEditDictDialog")
1433 , m_aEditHintText ( CuiResId(RID_CUISTR_EDITHINT) )
1434 , m_rDictList ( _rDictList )
1435 , m_nCurrentDict ( 0xFFFFFFFF )
1436 , m_nTopPos ( 0 )
1437 , m_bModifiedSuggestions ( false )
1438 , m_bModifiedOriginal ( false )
1439 , m_xBookLB(m_xBuilder->weld_combo_box("book"))
1440 , m_xOriginalLB(m_xBuilder->weld_combo_box("original"))
1441 , m_xEdit1(new SuggestionEdit(m_xBuilder->weld_entry("edit1"), this))
1442 , m_xEdit2(new SuggestionEdit(m_xBuilder->weld_entry("edit2"), this))
1443 , m_xEdit3(new SuggestionEdit(m_xBuilder->weld_entry("edit3"), this))
1444 , m_xEdit4(new SuggestionEdit(m_xBuilder->weld_entry("edit4"), this))
1445 , m_xContents(m_xBuilder->weld_widget("box"))
1446 , m_xScrollSB(m_xBuilder->weld_scrolled_window("scrollbar", true))
1447 , m_xNewPB(m_xBuilder->weld_button("new"))
1448 , m_xDeletePB(m_xBuilder->weld_button("delete"))
1449 {
1450 Size aSize(m_xContents->get_preferred_size());
1451 m_xScrollSB->set_size_request(-1, aSize.Height());
1452
1453 m_xEdit1->init( m_xScrollSB.get(), nullptr, m_xEdit2.get() );
1454 m_xEdit2->init( m_xScrollSB.get(), m_xEdit1.get(), m_xEdit3.get() );
1455 m_xEdit3->init( m_xScrollSB.get(), m_xEdit2.get(), m_xEdit4.get() );
1456 m_xEdit4->init( m_xScrollSB.get(), m_xEdit3.get(), nullptr );
1457
1458 m_xOriginalLB->connect_changed( LINK( this, HangulHanjaEditDictDialog, OriginalModifyHdl ) );
1459
1460 m_xNewPB->connect_clicked( LINK( this, HangulHanjaEditDictDialog, NewPBPushHdl ) );
1461 m_xNewPB->set_sensitive( false );
1462
1463 m_xDeletePB->connect_clicked( LINK( this, HangulHanjaEditDictDialog, DeletePBPushHdl ) );
1464 m_xDeletePB->set_sensitive( false );
1465
1466 static_assert(MAXNUM_SUGGESTIONS >= 5, "number of suggestions should not under-run the value of 5");
1467
1468 // 4 here, because we have 4 edits / page
1469 m_xScrollSB->vadjustment_configure(0, 0, MAXNUM_SUGGESTIONS, 1, 4, 4);
1470 m_xScrollSB->connect_vadjustment_changed(LINK(this, HangulHanjaEditDictDialog, ScrollHdl));
1471
1472 m_xEdit1->connect_changed( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl1 ) );
1473 m_xEdit2->connect_changed( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl2 ) );
1474 m_xEdit3->connect_changed( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl3 ) );
1475 m_xEdit4->connect_changed( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl4 ) );
1476
1477 m_xBookLB->connect_changed( LINK( this, HangulHanjaEditDictDialog, BookLBSelectHdl ) );
1478 sal_uInt32 nDictCnt = m_rDictList.size();
1479 for( sal_uInt32 n = 0 ; n < nDictCnt ; ++n )
1480 {
1481 Reference< XConversionDictionary > xDic( m_rDictList[n] );
1482 OUString aName;
1483 if( xDic.is() )
1484 aName = xDic->getName();
1485 m_xBookLB->append_text( aName );
1486 }
1487 m_xBookLB->set_active(nSelDict);
1488
1489 InitEditDictDialog(nSelDict);
1490 }
1491
1493 {
1494 }
1495
1497 {
1498 sal_uInt16 nPos = m_xScrollSB->vadjustment_get_value();
1499 m_nTopPos = nPos;
1500
1501 SetEditText( *m_xEdit1, nPos++ );
1502 SetEditText( *m_xEdit2, nPos++ );
1503 SetEditText( *m_xEdit3, nPos++ );
1505 }
1506}
1507
1508/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
DrawTextFlags
Reference< XExecutableDialog > m_xDialog
FILE * init(int, char **)
LanguageType getLanguageType(bool bResolveSystem=true) const
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
const vcl::Font & GetFont() const
void SetFont(const vcl::Font &rNewFont)
Size GetOutputSizePixel() const
tools::Rectangle GetTextRect(const tools::Rectangle &rRect, const OUString &rStr, DrawTextFlags nStyle=DrawTextFlags::WordBreak, TextRectInfo *pInfo=nullptr, const vcl::ITextLayout *_pTextLayout=nullptr) const
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, std::vector< tools::Rectangle > *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
constexpr tools::Long Height() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
css::uno::Any GetProperty(std::u16string_view rPropertyName) const
bool SetProperty(std::u16string_view rPropertyName, const css::uno::Any &rValue)
vcl::RenderContext * GetRenderContext() const
const tools::Rectangle & GetRect() const
sal_uInt16 GetItemId() const
void * GetItemData(sal_uInt16 nItemId) const
reference_type * get() const
std::unique_ptr< weld::Button > m_xReplaceAll
editeng::HangulHanjaConversion::ConversionFormat GetConversionFormat() const
void SetChangeHdl(const Link< weld::Button &, void > &_rHdl)
void SetFindHdl(const Link< weld::Button &, void > &_rHdl)
std::unique_ptr< SuggestionDisplay > m_xSuggestions
Link< weld::Toggleable &, void > m_aClickByCharacterLink
editeng::HangulHanjaConversion::ConversionDirection GetDirection(editeng::HangulHanjaConversion::ConversionDirection eDefaultDirection) const
get current conversion direction to use (return argument if GetUseBothDirections is true)
bool GetUseBothDirections() const
should text which does not match the primary conversion direction be ignored?
HangulHanjaConversionDialog(weld::Widget *pParent)
void SetByCharacter(bool _bByCharacter)
std::unique_ptr< RubyRadioButton > m_xHangulAbove
std::unique_ptr< RubyRadioButton > m_xHangulBelow
std::unique_ptr< weld::CheckButton > m_xHanjaOnly
void SetOptionsChangedHdl(const Link< LinkParamNone *, void > &_rHdl)
std::unique_ptr< weld::RadioButton > m_xHangulBracketed
std::unique_ptr< RubyRadioButton > m_xHanjaAbove
void SetConversionFormat(editeng::HangulHanjaConversion::ConversionFormat _eType)
void SetCurrentString(const OUString &_rNewString, const css::uno::Sequence< OUString > &_rSuggestions, bool _bOriginatesFromDocument)
void FillSuggestions(const css::uno::Sequence< OUString > &_rSuggestions)
fill the suggestion list box with suggestions for the actual input
std::unique_ptr< weld::Button > m_xFind
std::unique_ptr< weld::CheckButton > m_xHangulOnly
std::unique_ptr< weld::RadioButton > m_xHanjaBracketed
void SetIgnoreHdl(const Link< weld::Button &, void > &_rHdl)
Link< LinkParamNone *, void > m_aOptionsChangedLink
std::unique_ptr< weld::Entry > m_xWordInput
std::unique_ptr< weld::Button > m_xIgnore
std::unique_ptr< weld::Button > m_xOptions
std::unique_ptr< RubyRadioButton > m_xHanjaBelow
std::unique_ptr< weld::CheckButton > m_xReplaceByChar
void SetChangeAllHdl(const Link< weld::Button &, void > &_rHdl)
void SetConversionDirectionState(bool _bTryBothDirections, editeng::HangulHanjaConversion::ConversionDirection _ePrimaryConversionDirection)
void SetIgnoreAllHdl(const Link< weld::Button &, void > &_rHdl)
std::unique_ptr< weld::Button > m_xReplace
OUString GetCurrentSuggestion() const
retrieves the current suggestion
void EnableRubySupport(bool bVal)
enables or disables the checkboxes for ruby formatted replacements
std::unique_ptr< weld::RadioButton > m_xSimpleConversion
void SetConversionFormatChangedHdl(const Link< weld::Toggleable &, void > &_rHdl)
std::unique_ptr< weld::Label > m_xOriginalWord
bool m_bDocumentMode
are we working for a document? This is normally true, but in case the user uses the "find" functional...
virtual ~HangulHanjaConversionDialog() override
std::unique_ptr< weld::Button > m_xIgnoreAll
void SetClickByCharacterHdl(const Link< weld::Toggleable &, void > &_rHdl)
std::unique_ptr< weld::Button > m_xDeletePB
std::unique_ptr< weld::Widget > m_xContents
std::unique_ptr< SuggestionEdit > m_xEdit4
HangulHanjaEditDictDialog(weld::Window *pParent, HHDictList &rDictList, sal_uInt32 nSelDict)
std::unique_ptr< weld::ComboBox > m_xBookLB
void EditModify(const weld::Entry *pEdit, sal_uInt8 nEntryOffset)
void SetEditText(SuggestionEdit &rEdit, sal_uInt16 nEntryNum)
std::unique_ptr< weld::ScrolledWindow > m_xScrollSB
std::unique_ptr< weld::ComboBox > m_xOriginalLB
std::unique_ptr< SuggestionEdit > m_xEdit2
std::unique_ptr< SuggestionEdit > m_xEdit1
std::unique_ptr< SuggestionList > m_xSuggestions
std::unique_ptr< SuggestionEdit > m_xEdit3
virtual ~HangulHanjaEditDictDialog() override
void InitEditDictDialog(sal_uInt32 nSelDict)
bool DeleteEntryFromDictionary(const css::uno::Reference< css::linguistic2::XConversionDictionary > &xDict)
std::unique_ptr< weld::Button > m_xNewPB
HangulHanjaNewDictDialog(weld::Window *pParent)
virtual ~HangulHanjaNewDictDialog() override
std::unique_ptr< weld::Entry > m_xDictNameED
bool GetName(OUString &_rRetName) const
std::unique_ptr< weld::Button > m_xOkBtn
std::unique_ptr< weld::CheckButton > m_xIgnorepostCB
std::unique_ptr< weld::Button > m_xOkPB
css::uno::Reference< css::linguistic2::XConversionDictionaryList > m_xConversionDictionaryList
void AddDict(const OUString &_rName, bool _bChecked)
std::unique_ptr< weld::Button > m_xNewPB
std::unique_ptr< weld::Button > m_xDeletePB
std::unique_ptr< weld::CheckButton > m_xAutoreplaceuniqueCB
std::unique_ptr< weld::Button > m_xEditPB
void Init()
reads settings from core and init controls
virtual ~HangulHanjaOptionsDialog() override
std::unique_ptr< weld::CheckButton > m_xShowrecentlyfirstCB
std::unique_ptr< weld::TreeView > m_xDictsLB
HangulHanjaOptionsDialog(weld::Window *pParent)
void init(const OUString &rPrimaryText, const OUString &rSecondaryText, const PseudoRubyText::RubyPosition &rPosition)
Size GetOptimalSize() const
std::unique_ptr< weld::RadioButton > m_xControl
void set_sensitive(bool sensitive)
void connect_toggled(const Link< weld::Toggleable &, void > &rLink)
ScopedVclPtr< VirtualDevice > m_xVirDev
void set_active(bool active)
void Paint(vcl::RenderContext &rRenderContext)
std::unique_ptr< weld::Image > m_xImage
PseudoRubyText m_aRubyText
OUString GetSelectedEntry() const
std::unique_ptr< weld::CustomWeld > m_xValueSetWin
void DisplayListBox(bool bDisplayListBox)
SuggestionDisplay(weld::Builder &rBuilder)
weld::Widget & implGetCurrentControl()
Link< SuggestionDisplay &, void > m_aSelectLink
OUString GetEntry(sal_uInt16 nPos) const
void SelectSuggestionHdl(bool bListBox)
std::unique_ptr< weld::TreeView > m_xListBox
void InsertEntry(const OUString &rStr)
void SetSelectHdl(const Link< SuggestionDisplay &, void > &rLink)
std::unique_ptr< SuggestionSet > m_xValueSet
void SelectEntryPos(sal_uInt16 nPos)
sal_uInt16 GetEntryCount() const
std::unique_ptr< weld::Entry > m_xEntry
bool ShouldScroll(bool _bUp) const
void DoJump(bool _bUp)
HangulHanjaEditDictDialog * m_pParent
weld::ScrolledWindow * m_pScrollBar
SuggestionEdit(std::unique_ptr< weld::Entry > xEntry, HangulHanjaEditDictDialog *pParent)
void set_text(const OUString &rText)
SuggestionEdit * m_pPrev
void init(weld::ScrolledWindow *pScrollBar, SuggestionEdit *pPrev, SuggestionEdit *pNext)
SuggestionEdit * m_pNext
const OUString & Get(sal_uInt16 _nNumOfElement) const
const OUString * First()
sal_uInt16 GetCount() const
std::vector< OUString > m_vElements
void Reset(sal_uInt16 _nNumOfElement)
const OUString * Next_()
const OUString * Next()
void Set(const OUString &_rElement, sal_uInt16 _nNumOfElement)
SuggestionSet(std::unique_ptr< weld::ScrolledWindow > xScrolledWindow)
virtual void UserDraw(const UserDrawEvent &rUDEvt) override
constexpr tools::Long GetWidth() const
constexpr void SetLeft(tools::Long v)
constexpr tools::Long Top() const
constexpr void SetRight(tools::Long v)
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
constexpr tools::Long Right() const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
constexpr tools::Long GetHeight() const
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
constexpr tools::Long Left() const
tools::Long GetFontHeight() const
void SetFontHeight(tools::Long nHeight)
sal_uInt16 GetCode() const
sal_uInt16 GetModifier() const
virtual short run()
virtual OUString get_text() const=0
std::shared_ptr< weld::Dialog > m_xDialog
virtual int vadjustment_get_lower() const=0
virtual void vadjustment_set_value(int value)=0
virtual int vadjustment_get_upper() const=0
virtual int vadjustment_get_value() const=0
virtual bool get_active() const=0
virtual void set_active(bool active)=0
virtual void grab_focus()=0
virtual void set_sensitive(bool sensitive)=0
virtual bool has_focus() const=0
OUString CuiResId(TranslateId aKey)
Definition: cuiresmgr.cxx:23
int nCount
#define DBG_ASSERT(sCon, aError)
ScXMLEditAttributeMap::Entry const aEntries[]
TRISTATE_FALSE
TRISTATE_TRUE
#define MAXNUM_SUGGESTIONS
RubyPosition m_ePosition
OUString m_sSecondaryText
OutputDevice & m_rDev
#define LINE_CNT
OUString m_sPrimaryText
constexpr OUStringLiteral HID_HANGULDLG_SUGGESTIONS_GRID
Definition: helpids.h:35
constexpr OUStringLiteral HID_HANGULDLG_SUGGESTIONS_LIST
Definition: helpids.h:37
OUString aName
sal_Int64 n
constexpr sal_uInt16 KEY_TAB
constexpr sal_uInt16 KEY_UP
constexpr sal_uInt16 KEY_DOWN
constexpr sal_uInt16 KEY_SHIFT
#define LANGUAGE_KOREAN
#define UPH_ACTIVE_CONVERSION_DICTIONARIES
#define UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST
#define UPH_IS_IGNORE_POST_POSITIONAL_WORD
#define UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES
sal_uInt16 nPos
#define SAL_INFO(area, stream)
aStr
OString stripEnd(const OString &rIn, char c)
int i
IMPL_LINK(ClassificationDialog, SelectClassificationHdl, weld::ComboBox &, rBox, void)
IMPL_LINK_NOARG(ClassificationDialog, OnAsyncExpandHdl, void *, void)
std::vector< css::uno::Reference< css::linguistic2::XConversionDictionary > > HHDictList
long Long
void SetPointFont(OutputDevice &rDevice, const vcl::Font &rFont)
RubyPosition
unsigned char sal_uInt8
#define SAL_MAX_INT32
#define WB_ITEMBORDER
RET_OK
Reference< XControl > m_xControl
WinBits const WB_VSCROLL