2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
21 #include <tools/debug.hxx>
22 #include <tools/diagnose_ex.h>
24 #include <svx/rubydialog.hxx>
25 #include <sfx2/dispatch.hxx>
26 #include <sfx2/sfxsids.hrc>
27 #include <sfx2/viewfrm.hxx>
28 #include <sfx2/viewsh.hxx>
29 #include <svl/eitem.hxx>
30 #include <com/sun/star/frame/XController.hpp>
31 #include <com/sun/star/style/XStyle.hpp>
32 #include <com/sun/star/text/XRubySelection.hpp>
33 #include <com/sun/star/beans/PropertyValues.hpp>
34 #include <com/sun/star/beans/XPropertySet.hpp>
35 #include <com/sun/star/beans/XPropertySetInfo.hpp>
36 #include <com/sun/star/container/XNameContainer.hpp>
37 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
38 #include <com/sun/star/text/RubyAdjust.hpp>
39 #include <com/sun/star/view/XSelectionChangeListener.hpp>
40 #include <com/sun/star/view/XSelectionSupplier.hpp>
41 #include <cppuhelper/implbase.hxx>
42 #include <svtools/colorcfg.hxx>
43 #include <vcl/event.hxx>
44 #include <vcl/settings.hxx>
45 #include <vcl/svapp.hxx>
47 using namespace css::uno
;
48 using namespace css::frame
;
49 using namespace css::text
;
50 using namespace css::beans
;
51 using namespace css::style
;
52 using namespace css::view
;
53 using namespace css::lang
;
54 using namespace css::container
;
56 SFX_IMPL_CHILDWINDOW(SvxRubyChildWindow
, SID_RUBY_DIALOG
);
60 constexpr OUStringLiteral cRubyBaseText
= u
"RubyBaseText";
61 constexpr OUStringLiteral cRubyText
= u
"RubyText";
62 constexpr OUStringLiteral cRubyAdjust
= u
"RubyAdjust";
63 constexpr OUStringLiteral cRubyPosition
= u
"RubyPosition";
64 constexpr OUStringLiteral cRubyCharStyleName
= u
"RubyCharStyleName";
66 } // end anonymous namespace
68 SvxRubyChildWindow::SvxRubyChildWindow(vcl::Window
* _pParent
, sal_uInt16 nId
,
69 SfxBindings
* pBindings
, SfxChildWinInfo
const* pInfo
)
70 : SfxChildWindow(_pParent
, nId
)
72 auto xDlg
= std::make_shared
<SvxRubyDialog
>(pBindings
, this, _pParent
->GetFrameWeld());
74 xDlg
->Initialize(pInfo
);
77 SfxChildWinInfo
SvxRubyChildWindow::GetInfo() const { return SfxChildWindow::GetInfo(); }
79 class SvxRubyData_Impl
: public cppu::WeakImplHelper
<css::view::XSelectionChangeListener
>
81 Reference
<XModel
> xModel
;
82 Reference
<XRubySelection
> xSelection
;
83 Sequence
<PropertyValues
> aRubyValues
;
84 Reference
<XController
> xController
;
85 bool bHasSelectionChanged
;
89 virtual ~SvxRubyData_Impl() override
;
91 void SetController(const Reference
<XController
>& xCtrl
);
92 Reference
<XModel
> const& GetModel()
94 if (!xController
.is())
97 xModel
= xController
->getModel();
100 bool HasSelectionChanged() const { return bHasSelectionChanged
; }
101 Reference
<XRubySelection
> const& GetRubySelection()
103 xSelection
.set(xController
, UNO_QUERY
);
106 void UpdateRubyValues()
108 if (!xSelection
.is())
109 aRubyValues
.realloc(0);
111 aRubyValues
= xSelection
->getRubyList(false);
112 bHasSelectionChanged
= false;
114 Sequence
<PropertyValues
>& GetRubyValues() { return aRubyValues
; }
115 void AssertOneEntry();
117 virtual void SAL_CALL
selectionChanged(const css::lang::EventObject
& aEvent
) override
;
118 virtual void SAL_CALL
disposing(const css::lang::EventObject
& Source
) override
;
121 SvxRubyData_Impl::SvxRubyData_Impl()
122 : bHasSelectionChanged(false)
126 SvxRubyData_Impl::~SvxRubyData_Impl() {}
128 void SvxRubyData_Impl::SetController(const Reference
<XController
>& xCtrl
)
130 if (xCtrl
.get() == xController
.get())
135 Reference
<XSelectionSupplier
> xSelSupp(xController
, UNO_QUERY
);
137 xSelSupp
->removeSelectionChangeListener(this);
139 bHasSelectionChanged
= true;
141 xSelSupp
.set(xController
, UNO_QUERY
);
143 xSelSupp
->addSelectionChangeListener(this);
145 catch (const Exception
&)
150 void SvxRubyData_Impl::selectionChanged(const EventObject
&) { bHasSelectionChanged
= true; }
152 void SvxRubyData_Impl::disposing(const EventObject
&)
156 Reference
<XSelectionSupplier
> xSelSupp(xController
, UNO_QUERY
);
158 xSelSupp
->removeSelectionChangeListener(this);
160 catch (const Exception
&)
163 xController
= nullptr;
166 void SvxRubyData_Impl::AssertOneEntry()
169 if (!aRubyValues
.hasElements())
171 aRubyValues
.realloc(1);
172 Sequence
<PropertyValue
>& rValues
= aRubyValues
.getArray()[0];
174 PropertyValue
* pValues
= rValues
.getArray();
175 pValues
[0].Name
= cRubyBaseText
;
176 pValues
[1].Name
= cRubyText
;
177 pValues
[2].Name
= cRubyAdjust
;
178 pValues
[3].Name
= cRubyPosition
;
179 pValues
[4].Name
= cRubyCharStyleName
;
183 SvxRubyDialog::SvxRubyDialog(SfxBindings
* pBind
, SfxChildWindow
* pCW
, weld::Window
* pParent
)
184 : SfxModelessDialogController(pBind
, pCW
, pParent
, "svx/ui/asianphoneticguidedialog.ui",
185 "AsianPhoneticGuideDialog")
190 , m_pImpl(new SvxRubyData_Impl
)
191 , m_xLeftFT(m_xBuilder
->weld_label("basetextft"))
192 , m_xRightFT(m_xBuilder
->weld_label("rubytextft"))
193 , m_xLeft1ED(m_xBuilder
->weld_entry("Left1ED"))
194 , m_xRight1ED(m_xBuilder
->weld_entry("Right1ED"))
195 , m_xLeft2ED(m_xBuilder
->weld_entry("Left2ED"))
196 , m_xRight2ED(m_xBuilder
->weld_entry("Right2ED"))
197 , m_xLeft3ED(m_xBuilder
->weld_entry("Left3ED"))
198 , m_xRight3ED(m_xBuilder
->weld_entry("Right3ED"))
199 , m_xLeft4ED(m_xBuilder
->weld_entry("Left4ED"))
200 , m_xRight4ED(m_xBuilder
->weld_entry("Right4ED"))
201 , m_xScrolledWindow(m_xBuilder
->weld_scrolled_window("scrolledwindow", true))
202 , m_xAdjustLB(m_xBuilder
->weld_combo_box("adjustlb"))
203 , m_xPositionLB(m_xBuilder
->weld_combo_box("positionlb"))
204 , m_xCharStyleFT(m_xBuilder
->weld_label("styleft"))
205 , m_xCharStyleLB(m_xBuilder
->weld_combo_box("stylelb"))
206 , m_xStylistPB(m_xBuilder
->weld_button("styles"))
207 , m_xApplyPB(m_xBuilder
->weld_button("ok"))
208 , m_xClosePB(m_xBuilder
->weld_button("close"))
209 , m_xContentArea(m_xDialog
->weld_content_area())
210 , m_xGrid(m_xBuilder
->weld_widget("grid"))
211 , m_xPreviewWin(new RubyPreview
)
212 , m_xPreview(new weld::CustomWeld(*m_xBuilder
, "preview", *m_xPreviewWin
))
214 m_xCharStyleLB
->make_sorted();
215 m_xPreviewWin
->setRubyDialog(this);
216 m_xScrolledWindow
->set_size_request(-1, m_xGrid
->get_preferred_size().Height());
217 m_xScrolledWindow
->set_vpolicy(VclPolicyType::NEVER
);
219 aEditArr
[0] = m_xLeft1ED
.get();
220 aEditArr
[1] = m_xRight1ED
.get();
221 aEditArr
[2] = m_xLeft2ED
.get();
222 aEditArr
[3] = m_xRight2ED
.get();
223 aEditArr
[4] = m_xLeft3ED
.get();
224 aEditArr
[5] = m_xRight3ED
.get();
225 aEditArr
[6] = m_xLeft4ED
.get();
226 aEditArr
[7] = m_xRight4ED
.get();
228 m_xApplyPB
->connect_clicked(LINK(this, SvxRubyDialog
, ApplyHdl_Impl
));
229 m_xClosePB
->connect_clicked(LINK(this, SvxRubyDialog
, CloseHdl_Impl
));
230 m_xStylistPB
->connect_clicked(LINK(this, SvxRubyDialog
, StylistHdl_Impl
));
231 m_xAdjustLB
->connect_changed(LINK(this, SvxRubyDialog
, AdjustHdl_Impl
));
232 m_xPositionLB
->connect_changed(LINK(this, SvxRubyDialog
, PositionHdl_Impl
));
233 m_xCharStyleLB
->connect_changed(LINK(this, SvxRubyDialog
, CharStyleHdl_Impl
));
235 Link
<weld::ScrolledWindow
&, void> aScrLk(LINK(this, SvxRubyDialog
, ScrollHdl_Impl
));
236 m_xScrolledWindow
->connect_vadjustment_changed(aScrLk
);
238 Link
<weld::Entry
&, void> aEditLk(LINK(this, SvxRubyDialog
, EditModifyHdl_Impl
));
239 Link
<weld::Widget
&, void> aFocusLk(LINK(this, SvxRubyDialog
, EditFocusHdl_Impl
));
240 Link
<const KeyEvent
&, bool> aKeyUpDownLk(LINK(this, SvxRubyDialog
, KeyUpDownHdl_Impl
));
241 Link
<const KeyEvent
&, bool> aKeyTabUpDownLk(LINK(this, SvxRubyDialog
, KeyUpDownTabHdl_Impl
));
242 for (sal_uInt16 i
= 0; i
< 8; i
++)
244 aEditArr
[i
]->connect_changed(aEditLk
);
245 aEditArr
[i
]->connect_focus_in(aFocusLk
);
247 aEditArr
[i
]->connect_key_press(aKeyTabUpDownLk
);
249 aEditArr
[i
]->connect_key_press(aKeyUpDownLk
);
253 SvxRubyDialog::~SvxRubyDialog()
255 ClearCharStyleList();
257 m_pImpl
->disposing(aEvent
);
260 void SvxRubyDialog::ClearCharStyleList() { m_xCharStyleLB
->clear(); }
262 void SvxRubyDialog::Close()
266 SfxViewFrame
* pViewFrame
= SfxViewFrame::Current();
268 pViewFrame
->ToggleChildWindow(SID_RUBY_DIALOG
);
271 void SvxRubyDialog::Activate()
273 SfxModelessDialogController::Activate();
276 // tdf#141967 if Activate is called during tear down bail early
279 //get selection from current view frame
280 SfxViewFrame
* pCurFrm
= SfxViewFrame::Current();
281 Reference
<XController
> xCtrl
= pCurFrm
->GetFrame().GetController();
282 m_pImpl
->SetController(xCtrl
);
283 if (!m_pImpl
->HasSelectionChanged())
286 Reference
<XRubySelection
> xRubySel
= m_pImpl
->GetRubySelection();
287 m_pImpl
->UpdateRubyValues();
288 EnableControls(xRubySel
.is());
291 Reference
<XModel
> xModel
= m_pImpl
->GetModel();
292 const OUString sCharStyleSelect
= m_xCharStyleLB
->get_active_text();
293 ClearCharStyleList();
294 Reference
<XStyleFamiliesSupplier
> xSupplier(xModel
, UNO_QUERY
);
299 Reference
<XNameAccess
> xFam
= xSupplier
->getStyleFamilies();
300 Any aChar
= xFam
->getByName("CharacterStyles");
301 Reference
<XNameContainer
> xChar
;
303 Reference
<XIndexAccess
> xCharIdx(xChar
, UNO_QUERY
);
306 OUString
sUIName("DisplayName");
307 for (sal_Int32 nStyle
= 0; nStyle
< xCharIdx
->getCount(); nStyle
++)
309 Any aStyle
= xCharIdx
->getByIndex(nStyle
);
310 Reference
<XStyle
> xStyle
;
312 Reference
<XPropertySet
> xPrSet(xStyle
, UNO_QUERY
);
313 OUString sName
, sCoreName
;
316 Reference
<XPropertySetInfo
> xInfo
= xPrSet
->getPropertySetInfo();
317 if (xInfo
->hasPropertyByName(sUIName
))
319 Any aName
= xPrSet
->getPropertyValue(sUIName
);
325 sCoreName
= xStyle
->getName();
329 if (!sName
.isEmpty())
331 m_xCharStyleLB
->append(sCoreName
, sName
);
336 catch (const Exception
&)
338 TOOLS_WARN_EXCEPTION("svx.dialog", "exception in style access");
340 if (!sCharStyleSelect
.isEmpty())
341 m_xCharStyleLB
->set_active_text(sCharStyleSelect
);
343 m_xCharStyleLB
->set_sensitive(xSupplier
.is());
344 m_xCharStyleFT
->set_sensitive(xSupplier
.is());
347 m_xPreviewWin
->Invalidate();
350 void SvxRubyDialog::SetRubyText(sal_Int32 nPos
, weld::Entry
& rLeft
, weld::Entry
& rRight
)
352 OUString sLeft
, sRight
;
353 const Sequence
<PropertyValues
>& aRubyValues
= m_pImpl
->GetRubyValues();
354 bool bEnable
= aRubyValues
.getLength() > nPos
;
357 const Sequence
<PropertyValue
> aProps
= aRubyValues
.getConstArray()[nPos
];
358 for (const PropertyValue
& rProp
: aProps
)
360 if (rProp
.Name
== cRubyBaseText
)
361 rProp
.Value
>>= sLeft
;
362 else if (rProp
.Name
== cRubyText
)
363 rProp
.Value
>>= sRight
;
370 rLeft
.set_sensitive(bEnable
);
371 rRight
.set_sensitive(bEnable
);
372 rLeft
.set_text(sLeft
);
373 rRight
.set_text(sRight
);
378 void SvxRubyDialog::GetRubyText()
380 tools::Long nTempLastPos
= GetLastPos();
381 for (int i
= 0; i
< 8; i
+= 2)
383 if (aEditArr
[i
]->get_sensitive()
384 && (aEditArr
[i
]->get_value_changed_from_saved()
385 || aEditArr
[i
+ 1]->get_value_changed_from_saved()))
387 Sequence
<PropertyValues
>& aRubyValues
= m_pImpl
->GetRubyValues();
388 DBG_ASSERT(aRubyValues
.getLength() > (i
/ 2 + nTempLastPos
), "wrong index");
390 for (PropertyValue
& propVal
: asNonConstRange(aRubyValues
[i
/ 2 + nTempLastPos
]))
392 if (propVal
.Name
== cRubyBaseText
)
393 propVal
.Value
<<= aEditArr
[i
]->get_text();
394 else if (propVal
.Name
== cRubyText
)
395 propVal
.Value
<<= aEditArr
[i
+ 1]->get_text();
401 void SvxRubyDialog::Update()
403 const Sequence
<PropertyValues
>& aRubyValues
= m_pImpl
->GetRubyValues();
404 sal_Int32 nLen
= aRubyValues
.getLength();
405 m_xScrolledWindow
->vadjustment_configure(0, 0, !nLen
? 1 : nLen
, 1, 4, 4);
407 m_xScrolledWindow
->set_vpolicy(VclPolicyType::ALWAYS
);
409 m_xScrolledWindow
->set_vpolicy(VclPolicyType::NEVER
);
413 sal_Int16 nAdjust
= -1;
414 sal_Int16 nPosition
= -1;
415 OUString sCharStyleName
, sTmp
;
416 bool bCharStyleEqual
= true;
417 for (sal_Int32 nRuby
= 0; nRuby
< nLen
; nRuby
++)
419 const Sequence
<PropertyValue
>& rProps
= aRubyValues
.getConstArray()[nRuby
];
420 for (const PropertyValue
& rProp
: rProps
)
422 if (nAdjust
> -2 && rProp
.Name
== cRubyAdjust
)
424 sal_Int16 nTmp
= sal_Int16();
425 rProp
.Value
>>= nTmp
;
428 else if (nAdjust
!= nTmp
)
431 if (nPosition
> -2 && rProp
.Name
== cRubyPosition
)
433 sal_Int16 nTmp
= sal_Int16();
434 rProp
.Value
>>= nTmp
;
437 else if (nPosition
!= nTmp
)
440 if (bCharStyleEqual
&& rProp
.Name
== cRubyCharStyleName
)
442 rProp
.Value
>>= sTmp
;
444 sCharStyleName
= sTmp
;
445 else if (sCharStyleName
!= sTmp
)
446 bCharStyleEqual
= false;
452 //enable selection if the ruby list is empty
457 m_xAdjustLB
->set_active(nAdjust
);
459 m_xAdjustLB
->set_active(-1);
461 m_xPositionLB
->set_active(nPosition
);
462 if (!nLen
|| (bCharStyleEqual
&& sCharStyleName
.isEmpty()))
463 sCharStyleName
= "Rubies";
464 if (!sCharStyleName
.isEmpty())
466 for (int i
= 0, nEntryCount
= m_xCharStyleLB
->get_count(); i
< nEntryCount
; i
++)
468 OUString sCoreName
= m_xCharStyleLB
->get_id(i
);
469 if (sCharStyleName
== sCoreName
)
471 m_xCharStyleLB
->set_active(i
);
477 m_xCharStyleLB
->set_active(-1);
479 ScrollHdl_Impl(*m_xScrolledWindow
);
482 void SvxRubyDialog::GetCurrentText(OUString
& rBase
, OUString
& rRuby
)
484 rBase
= aEditArr
[nCurrentEdit
* 2]->get_text();
485 rRuby
= aEditArr
[nCurrentEdit
* 2 + 1]->get_text();
488 IMPL_LINK(SvxRubyDialog
, ScrollHdl_Impl
, weld::ScrolledWindow
&, rScroll
, void)
490 int nPos
= rScroll
.vadjustment_get_value();
491 if (GetLastPos() != nPos
)
495 SetRubyText(nPos
++, *m_xLeft1ED
, *m_xRight1ED
);
496 SetRubyText(nPos
++, *m_xLeft2ED
, *m_xRight2ED
);
497 SetRubyText(nPos
++, *m_xLeft3ED
, *m_xRight3ED
);
498 SetRubyText(nPos
, *m_xLeft4ED
, *m_xRight4ED
);
499 SetLastPos(nPos
- 3);
500 m_xPreviewWin
->Invalidate();
503 IMPL_LINK_NOARG(SvxRubyDialog
, ApplyHdl_Impl
, weld::Button
&, void)
505 const Sequence
<PropertyValues
>& aRubyValues
= m_pImpl
->GetRubyValues();
506 if (!aRubyValues
.hasElements())
509 PositionHdl_Impl(*m_xPositionLB
);
510 AdjustHdl_Impl(*m_xAdjustLB
);
511 CharStyleHdl_Impl(*m_xCharStyleLB
);
514 //reset all edit fields - SaveValue is called
515 ScrollHdl_Impl(*m_xScrolledWindow
);
517 Reference
<XRubySelection
> xSelection
= m_pImpl
->GetRubySelection();
518 if (IsModified() && xSelection
.is())
522 xSelection
->setRubyList(aRubyValues
, false);
524 catch (const Exception
&)
526 TOOLS_WARN_EXCEPTION("svx.dialog", "");
531 IMPL_LINK_NOARG(SvxRubyDialog
, CloseHdl_Impl
, weld::Button
&, void) { Close(); }
533 IMPL_LINK_NOARG(SvxRubyDialog
, StylistHdl_Impl
, weld::Button
&, void)
535 std::unique_ptr
<SfxPoolItem
> pState
;
536 SfxItemState eState
= pBindings
->QueryState(SID_STYLE_DESIGNER
, pState
);
537 if (eState
<= SfxItemState::SET
|| !pState
538 || !static_cast<SfxBoolItem
*>(pState
.get())->GetValue())
540 pBindings
->GetDispatcher()->Execute(SID_STYLE_DESIGNER
,
541 SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
);
545 IMPL_LINK(SvxRubyDialog
, AdjustHdl_Impl
, weld::ComboBox
&, rBox
, void)
548 sal_Int16 nAdjust
= rBox
.get_active();
549 for (PropertyValues
& rProps
: asNonConstRange(m_pImpl
->GetRubyValues()))
551 for (PropertyValue
& propVal
: asNonConstRange(rProps
))
553 if (propVal
.Name
== cRubyAdjust
)
554 propVal
.Value
<<= nAdjust
;
558 m_xPreviewWin
->Invalidate();
561 IMPL_LINK(SvxRubyDialog
, PositionHdl_Impl
, weld::ComboBox
&, rBox
, void)
564 sal_Int16 nPosition
= rBox
.get_active();
565 for (PropertyValues
& rProps
: asNonConstRange(m_pImpl
->GetRubyValues()))
567 for (PropertyValue
& propVal
: asNonConstRange(rProps
))
569 if (propVal
.Name
== cRubyPosition
)
570 propVal
.Value
<<= nPosition
;
574 m_xPreviewWin
->Invalidate();
577 IMPL_LINK_NOARG(SvxRubyDialog
, CharStyleHdl_Impl
, weld::ComboBox
&, void)
581 if (m_xCharStyleLB
->get_active() != -1)
582 sStyleName
= m_xCharStyleLB
->get_active_id();
583 for (PropertyValues
& rProps
: asNonConstRange(m_pImpl
->GetRubyValues()))
585 for (PropertyValue
& propVal
: asNonConstRange(rProps
))
587 if (propVal
.Name
== cRubyCharStyleName
)
589 propVal
.Value
<<= sStyleName
;
596 IMPL_LINK(SvxRubyDialog
, EditFocusHdl_Impl
, weld::Widget
&, rEdit
, void)
598 for (sal_uInt16 i
= 0; i
< 8; i
++)
600 if (&rEdit
== aEditArr
[i
])
602 nCurrentEdit
= i
/ 2;
606 m_xPreviewWin
->Invalidate();
609 IMPL_LINK(SvxRubyDialog
, EditModifyHdl_Impl
, weld::Entry
&, rEdit
, void)
611 EditFocusHdl_Impl(rEdit
);
614 bool SvxRubyDialog::EditScrollHdl_Impl(sal_Int32 nParam
)
618 if (nParam
> 0 && (aEditArr
[7]->has_focus() || aEditArr
[6]->has_focus()))
620 if (m_xScrolledWindow
->vadjustment_get_upper()
621 > m_xScrolledWindow
->vadjustment_get_value()
622 + m_xScrolledWindow
->vadjustment_get_page_size())
624 m_xScrolledWindow
->vadjustment_set_value(m_xScrolledWindow
->vadjustment_get_value()
626 aEditArr
[6]->grab_focus();
631 else if (m_xScrolledWindow
->vadjustment_get_value()
632 && (aEditArr
[0]->has_focus() || aEditArr
[1]->has_focus()))
634 m_xScrolledWindow
->vadjustment_set_value(m_xScrolledWindow
->vadjustment_get_value() - 1);
635 aEditArr
[1]->grab_focus();
639 ScrollHdl_Impl(*m_xScrolledWindow
);
643 bool SvxRubyDialog::EditJumpHdl_Impl(sal_Int32 nParam
)
645 bool bHandled
= false;
646 sal_uInt16 nIndex
= USHRT_MAX
;
647 for (sal_uInt16 i
= 0; i
< 8; i
++)
649 if (aEditArr
[i
]->has_focus())
657 aEditArr
[nIndex
+ 2]->grab_focus();
658 else if (EditScrollHdl_Impl(nParam
))
659 aEditArr
[nIndex
]->grab_focus();
664 aEditArr
[nIndex
- 2]->grab_focus();
665 else if (EditScrollHdl_Impl(nParam
))
666 aEditArr
[nIndex
]->grab_focus();
673 void SvxRubyDialog::AssertOneEntry() { m_pImpl
->AssertOneEntry(); }
675 void SvxRubyDialog::EnableControls(bool bEnable
)
677 m_xContentArea
->set_sensitive(bEnable
);
678 m_xApplyPB
->set_sensitive(bEnable
);
681 RubyPreview::RubyPreview()
682 : m_pParentDlg(nullptr)
686 RubyPreview::~RubyPreview() {}
688 void RubyPreview::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& /*rRect*/)
690 rRenderContext
.Push(vcl::PushFlags::ALL
);
692 rRenderContext
.SetMapMode(MapMode(MapUnit::MapTwip
));
694 Size aWinSize
= rRenderContext
.GetOutputSize();
696 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
697 svtools::ColorConfig aColorConfig
;
699 Color
aNewTextColor(aColorConfig
.GetColorValue(svtools::FONTCOLOR
).nColor
);
700 Color
aNewFillColor(rStyleSettings
.GetWindowColor());
702 vcl::Font aFont
= rRenderContext
.GetFont();
703 aFont
.SetFontHeight(aWinSize
.Height() / 4);
704 aFont
.SetFillColor(aNewFillColor
);
705 aFont
.SetColor(aNewTextColor
);
706 rRenderContext
.SetFont(aFont
);
708 tools::Rectangle
aRect(Point(0, 0), aWinSize
);
709 rRenderContext
.SetLineColor();
710 rRenderContext
.SetFillColor(aFont
.GetFillColor());
711 rRenderContext
.DrawRect(aRect
);
713 OUString sBaseText
, sRubyText
;
714 m_pParentDlg
->GetCurrentText(sBaseText
, sRubyText
);
716 tools::Long nTextHeight
= rRenderContext
.GetTextHeight();
717 tools::Long nBaseWidth
= rRenderContext
.GetTextWidth(sBaseText
);
719 vcl::Font
aRubyFont(aFont
);
720 aRubyFont
.SetFontHeight(aRubyFont
.GetFontHeight() * 70 / 100);
721 rRenderContext
.SetFont(aRubyFont
);
722 tools::Long nRubyWidth
= rRenderContext
.GetTextWidth(sRubyText
);
723 rRenderContext
.SetFont(aFont
);
725 RubyAdjust nAdjust
= static_cast<RubyAdjust
>(m_pParentDlg
->m_xAdjustLB
->get_active());
726 //use center if no adjustment is available
727 if (nAdjust
> RubyAdjust_INDENT_BLOCK
)
728 nAdjust
= RubyAdjust_CENTER
;
730 //which part is stretched ?
731 bool bRubyStretch
= nBaseWidth
>= nRubyWidth
;
733 tools::Long nCenter
= aWinSize
.Width() / 2;
734 tools::Long nHalfWidth
= std::max(nBaseWidth
, nRubyWidth
) / 2;
735 tools::Long nLeftStart
= nCenter
- nHalfWidth
;
736 tools::Long nRightEnd
= nCenter
+ nHalfWidth
;
738 // Default values for TOP or no selection
739 tools::Long nYRuby
= aWinSize
.Height() / 4 - nTextHeight
/ 2;
740 tools::Long nYBase
= aWinSize
.Height() * 3 / 4 - nTextHeight
/ 2;
742 sal_Int16 nRubyPos
= m_pParentDlg
->m_xPositionLB
->get_active();
743 if (nRubyPos
== 1) // BOTTOM
745 tools::Long nTmp
= nYRuby
;
749 else if (nRubyPos
== 2) // RIGHT ( vertically )
751 // Align the ruby text and base text to the vertical center.
752 nYBase
= (aWinSize
.Height() - nTextHeight
) / 2;
753 nYRuby
= (aWinSize
.Height() - nRubyWidth
) / 2;
755 // Align the ruby text at the right side of the base text
756 nAdjust
= RubyAdjust_RIGHT
;
757 nHalfWidth
= nBaseWidth
/ 2;
758 nLeftStart
= nCenter
- nHalfWidth
;
759 nRightEnd
= nCenter
+ nHalfWidth
+ nRubyWidth
+ nTextHeight
;
760 // Render base text first, then render ruby text on the right.
763 aRubyFont
.SetVertical(true);
764 aRubyFont
.SetOrientation(2700_deg10
);
767 tools::Long nYOutput
;
768 tools::Long nOutTextWidth
;
769 OUString sOutputText
;
773 rRenderContext
.DrawText(Point(nLeftStart
, nYBase
), sBaseText
);
775 sOutputText
= sRubyText
;
776 nOutTextWidth
= nRubyWidth
;
777 rRenderContext
.SetFont(aRubyFont
);
781 rRenderContext
.SetFont(aRubyFont
);
782 rRenderContext
.DrawText(Point(nLeftStart
, nYRuby
), sRubyText
);
784 sOutputText
= sBaseText
;
785 nOutTextWidth
= nBaseWidth
;
786 rRenderContext
.SetFont(aFont
);
791 case RubyAdjust_LEFT
:
792 rRenderContext
.DrawText(Point(nLeftStart
, nYOutput
), sOutputText
);
794 case RubyAdjust_RIGHT
:
795 rRenderContext
.DrawText(Point(nRightEnd
- nOutTextWidth
, nYOutput
), sOutputText
);
797 case RubyAdjust_INDENT_BLOCK
:
799 tools::Long nCharWidth
= rRenderContext
.GetTextWidth("X");
800 if (nOutTextWidth
< (nRightEnd
- nLeftStart
- nCharWidth
))
803 nLeftStart
+= nCharWidth
;
804 nRightEnd
-= nCharWidth
;
808 case RubyAdjust_BLOCK
:
810 if (sOutputText
.getLength() > 1)
812 sal_Int32 nCount
= sOutputText
.getLength();
814 = ((nRightEnd
- nLeftStart
) - rRenderContext
.GetTextWidth(sOutputText
))
816 for (sal_Int32 i
= 0; i
< nCount
; i
++)
818 OUString
sChar(sOutputText
[i
]);
819 rRenderContext
.DrawText(Point(nLeftStart
, nYOutput
), sChar
);
820 tools::Long nCharWidth
= rRenderContext
.GetTextWidth(sChar
);
821 nLeftStart
+= nCharWidth
+ nSpace
;
827 case RubyAdjust_CENTER
:
828 rRenderContext
.DrawText(Point(nCenter
- nOutTextWidth
/ 2, nYOutput
), sOutputText
);
833 rRenderContext
.Pop();
836 void RubyPreview::SetDrawingArea(weld::DrawingArea
* pDrawingArea
)
838 pDrawingArea
->set_size_request(pDrawingArea
->get_approximate_digit_width() * 40,
839 pDrawingArea
->get_text_height() * 7);
840 CustomWidgetController::SetDrawingArea(pDrawingArea
);
843 IMPL_LINK(SvxRubyDialog
, KeyUpDownHdl_Impl
, const KeyEvent
&, rKEvt
, bool)
845 bool bHandled
= false;
846 const vcl::KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
847 sal_uInt16 nCode
= rKeyCode
.GetCode();
848 if (KEY_UP
== nCode
|| KEY_DOWN
== nCode
)
850 sal_Int32 nParam
= KEY_UP
== nCode
? -1 : 1;
851 bHandled
= EditJumpHdl_Impl(nParam
);
856 IMPL_LINK(SvxRubyDialog
, KeyUpDownTabHdl_Impl
, const KeyEvent
&, rKEvt
, bool)
858 bool bHandled
= false;
859 const vcl::KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
860 sal_uInt16 nMod
= rKeyCode
.GetModifier();
861 sal_uInt16 nCode
= rKeyCode
.GetCode();
862 if (nCode
== KEY_TAB
&& (!nMod
|| KEY_SHIFT
== nMod
))
864 sal_Int32 nParam
= KEY_SHIFT
== nMod
? -1 : 1;
865 if (EditScrollHdl_Impl(nParam
))
869 bHandled
= KeyUpDownHdl_Impl(rKEvt
);
873 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */