1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
21 #include <com/sun/star/text/WritingMode.hpp>
23 #include <comphelper/lok.hxx>
24 #include <comphelper/propertyvalue.hxx>
26 #include <vcl/toolbox.hxx>
27 #include <vcl/virdev.hxx>
29 #include <sfx2/viewsh.hxx>
31 #include <svl/itempool.hxx>
33 #include <svtools/toolbarmenu.hxx>
34 #include <svtools/popupwindowcontroller.hxx>
36 #include <svx/fmmodel.hxx>
37 #include <svx/svdpage.hxx>
38 #include <svx/svdobj.hxx>
39 #include <svx/svdview.hxx>
41 #include <svx/gallery.hxx>
42 #include <svx/fontworkgallery.hxx>
44 #include <tools/UnitConversion.hxx>
49 using namespace ::com::sun::star::uno
;
50 using namespace ::com::sun::star::lang
;
51 using namespace ::com::sun::star::beans
;
56 FontWorkGalleryDialog::FontWorkGalleryDialog(weld::Window
* pParent
, SdrView
& rSdrView
)
57 : GenericDialogController(pParent
, "svx/ui/fontworkgallerydialog.ui", "FontworkGalleryDialog")
60 , mbInsertIntoPage(true)
61 , mpDestModel(nullptr)
62 , maCtlFavorites(m_xBuilder
->weld_icon_view("ctlFavoriteswin"))
63 , mxOKButton(m_xBuilder
->weld_button("ok"))
66 maCtlFavorites
->set_size_request(aSize
.Width(), aSize
.Height());
68 maCtlFavorites
->connect_item_activated( LINK( this, FontWorkGalleryDialog
, DoubleClickFavoriteHdl
) );
69 maCtlFavorites
->connect_query_tooltip(LINK(this, FontWorkGalleryDialog
, QueryTooltipHandler
));
70 mxOKButton
->connect_clicked(LINK(this, FontWorkGalleryDialog
, ClickOKHdl
));
72 initFavorites( GALLERY_THEME_FONTWORK
);
73 fillFavorites( GALLERY_THEME_FONTWORK
);
76 FontWorkGalleryDialog::~FontWorkGalleryDialog()
80 void FontWorkGalleryDialog::initFavorites(sal_uInt16 nThemeId
)
82 // the favorites are read via the gallery
83 sal_uInt32 nFavCount
= GalleryExplorer::GetSdrObjCount( nThemeId
);
86 GalleryExplorer::BeginLocking(nThemeId
);
89 FmFormModel
*pModel
= nullptr;
91 for( nModelPos
= 0; nModelPos
< nFavCount
; nModelPos
++ )
95 if (GalleryExplorer::GetSdrObj(nThemeId
, nModelPos
, pModel
, &aThumb
) && !aThumb
.IsEmpty())
97 VclPtr
< VirtualDevice
> pVDev
= VclPtr
<VirtualDevice
>::Create();
98 const Point
aNull(0, 0);
100 if (pVDev
->GetDPIScaleFactor() > 1)
101 aThumb
.Scale(pVDev
->GetDPIScaleFactor(), pVDev
->GetDPIScaleFactor());
103 const Size
aSize(aThumb
.GetSizePixel());
105 pVDev
->SetOutputSizePixel(aSize
);
107 static const sal_uInt32
nLen(8);
108 static const Color
aW(COL_WHITE
);
109 static const Color
aG(0xef, 0xef, 0xef);
111 pVDev
->DrawCheckered(aNull
, aSize
, nLen
, aW
, aG
);
113 pVDev
->DrawBitmapEx(aNull
, aThumb
);
114 maFavoritesHorizontal
.emplace_back(pVDev
);
118 // release gallery theme
119 GalleryExplorer::EndLocking(nThemeId
);
122 void FontWorkGalleryDialog::fillFavorites(sal_uInt16 nThemeId
)
124 mnThemeId
= nThemeId
;
126 auto nFavCount
= maFavoritesHorizontal
.size();
128 maCtlFavorites
->clear();
129 maIdToTitleMap
.clear();
131 std::vector
<OUString
> aTitles
;
132 (void)GalleryExplorer::FillObjListTitle(nThemeId
, aTitles
);
133 assert(aTitles
.size() == nFavCount
);
135 for( size_t nFavorite
= 1; nFavorite
<= nFavCount
; nFavorite
++ )
137 OUString sId
= OUString::number(static_cast<sal_uInt16
>(nFavorite
));
138 maIdToTitleMap
.emplace(sId
, aTitles
.at(nFavorite
- 1));
139 maCtlFavorites
->insert(-1, nullptr, &sId
, maFavoritesHorizontal
[nFavorite
- 1], nullptr);
142 if (maCtlFavorites
->n_children())
143 maCtlFavorites
->select(0);
146 void FontWorkGalleryDialog::SetSdrObjectRef( SdrModel
* pModel
)
148 mbInsertIntoPage
= false;
149 mpDestModel
= pModel
;
152 void FontWorkGalleryDialog::insertSelectedFontwork()
154 OUString sItemId
= maCtlFavorites
->get_selected_id();
155 if (sItemId
.isEmpty())
158 sal_Int32 nItemId
= sItemId
.toInt32();
164 aModel
.GetItemPool().FreezeIdRanges();
166 if( !GalleryExplorer::GetSdrObj( mnThemeId
, nItemId
-1, &aModel
) )
169 SdrPage
* pPage
= aModel
.GetPage(0);
170 if( !(pPage
&& pPage
->GetObjCount()) )
173 // tdf#116993 Calc uses a 'special' mode for this dialog in being the
174 // only caller of ::SetSdrObjectRef. Only in that case mpDestModel seems
175 // to be the correct target SdrModel.
176 // If this is not used, the correct SdrModel seems to be the one from
177 // the mrSdrView that is used to insert (InsertObjectAtView below) the
179 const bool bUseSpecialCalcMode(!mbInsertIntoPage
&& nullptr != mpDestModel
);
181 // center shape on current view
182 OutputDevice
* pOutDev(mrSdrView
.GetFirstOutputDevice());
187 // Clone directly to target SdrModel (may be different due to user/caller (!))
188 rtl::Reference
<SdrObject
> pNewObject(
189 pPage
->GetObj(0)->CloneSdrObject(
190 bUseSpecialCalcMode
? *mpDestModel
: mrSdrView
.getSdrModelFromSdrView()));
192 pNewObject
->MakeNameUnique();
195 // Since the 'old' ::CloneSdrObject also copies the SdrPage* the
196 // SdrObject::getUnoShape() *will* create the wrong UNO API object
197 // early. This IS one of the reasons I do change these things - this
198 // error does not happen with my next change I am working on already
199 // ARGH! For now, reset the SdrPage* to nullptr.
200 // What sense does it have to copy the SdrPage* of the original SdrObject ?!?
201 // TTTT: This also *might* be the hidden reason for the strange code at the
202 // end of SdrObject::SetPage that tries to delete the SvxShape under some
204 // pNewObject->SetPage(nullptr);
206 tools::Rectangle
aObjRect( pNewObject
->GetLogicRect() );
208 Size aFontworkSize
= aObjRect
.GetSize();
210 if (comphelper::LibreOfficeKit::isActive())
212 SfxViewShell
* pViewShell
= SfxViewShell::Current();
214 aPagePos
= pViewShell
->getLOKVisibleArea().Center();
216 aPagePos
.setX(convertTwipToMm100(aPagePos
.X()));
217 aPagePos
.setY(convertTwipToMm100(aPagePos
.Y()));
219 sal_Int32 nLOKViewWidth
= 0.8 * convertTwipToMm100(pViewShell
->getLOKVisibleArea().getOpenWidth());
220 if (aFontworkSize
.getWidth() > nLOKViewWidth
)
222 double fScale
= static_cast<double>(aFontworkSize
.getWidth()) / nLOKViewWidth
;
223 aFontworkSize
.setWidth(aFontworkSize
.getWidth() / fScale
);
224 aFontworkSize
.setHeight(aFontworkSize
.getHeight() / fScale
);
229 Size aSize
= pOutDev
->GetOutputSizePixel();
230 tools::Rectangle
aPixelVisRect(Point(0,0), aSize
);
231 tools::Rectangle aVisArea
= pOutDev
->PixelToLogic(aPixelVisRect
);
233 aPagePos
= aVisArea
.Center();
236 if (aPagePos
.getX() > aFontworkSize
.getWidth() / 2)
237 aPagePos
.AdjustX( -(aFontworkSize
.getWidth() / 2) );
238 if (aPagePos
.getY() > aFontworkSize
.getHeight() / 2)
239 aPagePos
.AdjustY( -(aFontworkSize
.getHeight() / 2) );
241 tools::Rectangle
aNewObjectRectangle(aPagePos
, aFontworkSize
);
242 pNewObject
->SetLogicRect(aNewObjectRectangle
);
244 if (bUseSpecialCalcMode
)
246 mxSdrObject
= pNewObject
;
250 SdrPageView
* pPV(mrSdrView
.GetSdrPageView());
254 mrSdrView
.InsertObjectAtView( pNewObject
.get(), *pPV
);
259 IMPL_LINK_NOARG(FontWorkGalleryDialog
, ClickOKHdl
, weld::Button
&, void)
261 insertSelectedFontwork();
262 m_xDialog
->response(RET_OK
);
265 IMPL_LINK_NOARG(FontWorkGalleryDialog
, DoubleClickFavoriteHdl
, weld::IconView
&, bool)
267 insertSelectedFontwork();
268 m_xDialog
->response(RET_OK
);
272 IMPL_LINK(FontWorkGalleryDialog
, QueryTooltipHandler
, const weld::TreeIter
&, iter
, OUString
)
274 const OUString id
= maCtlFavorites
->get_id(iter
);
275 auto it
= maIdToTitleMap
.find(id
);
276 return it
!= maIdToTitleMap
.end() ? it
->second
: OUString();
281 class FontworkAlignmentWindow final
: public WeldToolbarPopup
284 FontworkAlignmentWindow(svt::PopupWindowController
* pControl
, weld::Widget
* pParentWindow
);
285 virtual void GrabFocus() override
287 mxLeft
->grab_focus();
289 virtual void statusChanged( const css::frame::FeatureStateEvent
& Event
) override
;
292 rtl::Reference
<svt::PopupWindowController
> mxControl
;
293 std::unique_ptr
<weld::RadioButton
> mxLeft
;
294 std::unique_ptr
<weld::RadioButton
> mxCenter
;
295 std::unique_ptr
<weld::RadioButton
> mxRight
;
296 std::unique_ptr
<weld::RadioButton
> mxStretch
;
299 DECL_LINK( SelectHdl
, weld::Toggleable
&, void );
301 void implSetAlignment( int nAlignmentMode
, bool bEnabled
);
306 constexpr OUStringLiteral
gsFontworkAlignment(u
".uno:FontworkAlignment");
308 FontworkAlignmentWindow::FontworkAlignmentWindow(svt::PopupWindowController
* pControl
, weld::Widget
* pParent
)
309 : WeldToolbarPopup(pControl
->getFrameInterface(), pParent
, "svx/ui/fontworkalignmentcontrol.ui", "FontworkAlignmentControl")
310 , mxControl(pControl
)
311 , mxLeft(m_xBuilder
->weld_radio_button("left"))
312 , mxCenter(m_xBuilder
->weld_radio_button("center"))
313 , mxRight(m_xBuilder
->weld_radio_button("right"))
314 , mxStretch(m_xBuilder
->weld_radio_button("stretch"))
315 , mbSettingValue(false)
317 mxLeft
->connect_toggled(LINK(this, FontworkAlignmentWindow
, SelectHdl
));
318 mxCenter
->connect_toggled(LINK(this, FontworkAlignmentWindow
, SelectHdl
));
319 mxRight
->connect_toggled(LINK(this, FontworkAlignmentWindow
, SelectHdl
));
320 mxStretch
->connect_toggled(LINK(this, FontworkAlignmentWindow
, SelectHdl
));
322 AddStatusListener( gsFontworkAlignment
);
325 void FontworkAlignmentWindow::implSetAlignment( int nSurface
, bool bEnabled
)
327 bool bSettingValue
= mbSettingValue
;
328 mbSettingValue
= true;
329 mxLeft
->set_active(nSurface
== 0 && bEnabled
);
330 mxLeft
->set_sensitive(bEnabled
);
331 mxCenter
->set_active(nSurface
== 1 && bEnabled
);
332 mxCenter
->set_sensitive(bEnabled
);
333 mxRight
->set_active(nSurface
== 2 && bEnabled
);
334 mxRight
->set_sensitive(bEnabled
);
335 //Refer https://bugs.documentfoundation.org/show_bug.cgi?id=145092 for why following lines are commented
336 //mxWord->set_active(nSurface == 3 && bEnabled);
337 //mxWord->set_sensitive(bEnabled);
338 mxStretch
->set_active(nSurface
== 4 && bEnabled
);
339 mxStretch
->set_sensitive(bEnabled
);
340 mbSettingValue
= bSettingValue
;
343 void FontworkAlignmentWindow::statusChanged( const css::frame::FeatureStateEvent
& Event
)
345 if( Event
.FeatureURL
.Main
!= gsFontworkAlignment
)
348 if( !Event
.IsEnabled
)
350 implSetAlignment( 0, false );
354 sal_Int32 nValue
= 0;
355 if( Event
.State
>>= nValue
)
356 implSetAlignment( nValue
, true );
360 IMPL_LINK(FontworkAlignmentWindow
, SelectHdl
, weld::Toggleable
&, rButton
, void)
362 if (mbSettingValue
|| !rButton
.get_active())
365 sal_Int32 nAlignment
;
366 if (mxLeft
->get_active())
368 else if (mxCenter
->get_active())
370 else if (mxRight
->get_active())
372 //Refer https://bugs.documentfoundation.org/show_bug.cgi?id=145092 for why following lines are commented
373 //else if (mxWord->get_active())
378 Sequence
< PropertyValue
> aArgs
{ comphelper::makePropertyValue(
379 OUString(gsFontworkAlignment
).copy(5), nAlignment
) };
381 mxControl
->dispatchCommand( gsFontworkAlignment
, aArgs
);
383 implSetAlignment( nAlignment
, true );
385 mxControl
->EndPopupMode();
390 class FontworkAlignmentControl
: public svt::PopupWindowController
393 explicit FontworkAlignmentControl( const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
);
395 virtual std::unique_ptr
<WeldToolbarPopup
> weldPopupWindow() override
;
396 virtual VclPtr
<vcl::Window
> createVclPopupWindow( vcl::Window
* pParent
) override
;
399 virtual void SAL_CALL
initialize( const css::uno::Sequence
< css::uno::Any
>& aArguments
) override
;
402 virtual OUString SAL_CALL
getImplementationName() override
;
403 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
408 FontworkAlignmentControl::FontworkAlignmentControl( const Reference
< XComponentContext
>& rxContext
)
409 : svt::PopupWindowController( rxContext
, Reference
< css::frame::XFrame
>(), ".uno:FontworkAlignment" )
413 std::unique_ptr
<WeldToolbarPopup
> FontworkAlignmentControl::weldPopupWindow()
415 return std::make_unique
<FontworkAlignmentWindow
>(this, m_pToolbar
);
418 VclPtr
<vcl::Window
> FontworkAlignmentControl::createVclPopupWindow( vcl::Window
* pParent
)
420 mxInterimPopover
= VclPtr
<InterimToolbarPopup
>::Create(getFrameInterface(), pParent
,
421 std::make_unique
<FontworkAlignmentWindow
>(this, pParent
->GetFrameWeld()));
423 mxInterimPopover
->Show();
425 return mxInterimPopover
;
429 void SAL_CALL
FontworkAlignmentControl::initialize( const css::uno::Sequence
< css::uno::Any
>& aArguments
)
431 svt::PopupWindowController::initialize( aArguments
);
435 mxPopoverContainer
.reset(new ToolbarPopupContainer(m_pToolbar
));
436 m_pToolbar
->set_item_popover(m_aCommandURL
, mxPopoverContainer
->getTopLevel());
439 ToolBox
* pToolBox
= nullptr;
441 if ( getToolboxId( nId
, &pToolBox
) )
442 pToolBox
->SetItemBits( nId
, pToolBox
->GetItemBits( nId
) | ToolBoxItemBits::DROPDOWNONLY
);
448 OUString
FontworkAlignmentControl::getImplementationName()
450 return "com.sun.star.comp.svx.FontworkAlignmentController";
454 Sequence
< OUString
> FontworkAlignmentControl::getSupportedServiceNames()
456 return { "com.sun.star.frame.ToolbarController" };
460 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
461 com_sun_star_comp_svx_FontworkAlignmentControl_get_implementation(
462 css::uno::XComponentContext
* xContext
,
463 css::uno::Sequence
<css::uno::Any
> const &)
465 return cppu::acquire(new FontworkAlignmentControl(xContext
));
470 class FontworkCharacterSpacingWindow final
: public WeldToolbarPopup
473 FontworkCharacterSpacingWindow(svt::PopupWindowController
* pControl
, weld::Widget
* pParentWindow
);
474 virtual void GrabFocus() override
;
476 virtual void statusChanged( const css::frame::FeatureStateEvent
& Event
) override
;
478 rtl::Reference
<svt::PopupWindowController
> mxControl
;
479 std::unique_ptr
<weld::RadioButton
> mxVeryTight
;
480 std::unique_ptr
<weld::RadioButton
> mxTight
;
481 std::unique_ptr
<weld::RadioButton
> mxNormal
;
482 std::unique_ptr
<weld::RadioButton
> mxLoose
;
483 std::unique_ptr
<weld::RadioButton
> mxVeryLoose
;
484 std::unique_ptr
<weld::RadioButton
> mxCustom
;
485 std::unique_ptr
<weld::CheckButton
> mxKernPairs
;
486 sal_Int32 mnCharacterSpacing
;
488 bool mbCommandDispatched
;
490 DECL_LINK( KernSelectHdl
, weld::Toggleable
&, void );
491 DECL_LINK( SelectHdl
, weld::Toggleable
&, void );
492 DECL_LINK( MouseReleaseHdl
, const MouseEvent
&, bool );
494 void implSetCharacterSpacing( sal_Int32 nCharacterSpacing
, bool bEnabled
);
495 void implSetKernCharacterPairs(bool bKernOnOff
, bool bEnabled
);
496 void DispatchSpacingDialog();
501 constexpr OUStringLiteral
gsFontworkCharacterSpacing(u
".uno:FontworkCharacterSpacing");
502 constexpr OUStringLiteral
gsFontworkKernCharacterPairs(u
".uno:FontworkKernCharacterPairs");
504 FontworkCharacterSpacingWindow::FontworkCharacterSpacingWindow(svt::PopupWindowController
* pControl
, weld::Widget
* pParent
)
505 : WeldToolbarPopup(pControl
->getFrameInterface(), pParent
, "svx/ui/fontworkcharacterspacingcontrol.ui", "FontworkCharacterSpacingControl")
506 , mxControl(pControl
)
507 , mxVeryTight(m_xBuilder
->weld_radio_button("verytight"))
508 , mxTight(m_xBuilder
->weld_radio_button("tight"))
509 , mxNormal(m_xBuilder
->weld_radio_button("normal"))
510 , mxLoose(m_xBuilder
->weld_radio_button("loose"))
511 , mxVeryLoose(m_xBuilder
->weld_radio_button("veryloose"))
512 , mxCustom(m_xBuilder
->weld_radio_button("custom"))
513 , mxKernPairs(m_xBuilder
->weld_check_button("kernpairs"))
514 , mnCharacterSpacing(0)
515 , mbSettingValue(false)
516 , mbCommandDispatched(false)
518 mxVeryTight
->connect_toggled(LINK(this, FontworkCharacterSpacingWindow
, SelectHdl
));
519 mxTight
->connect_toggled(LINK(this, FontworkCharacterSpacingWindow
, SelectHdl
));
520 mxNormal
->connect_toggled(LINK(this, FontworkCharacterSpacingWindow
, SelectHdl
));
521 mxLoose
->connect_toggled(LINK(this, FontworkCharacterSpacingWindow
, SelectHdl
));
522 mxVeryLoose
->connect_toggled(LINK(this, FontworkCharacterSpacingWindow
, SelectHdl
));
523 mxCustom
->connect_toggled(LINK(this, FontworkCharacterSpacingWindow
, SelectHdl
));
524 mxCustom
->connect_mouse_release(LINK(this, FontworkCharacterSpacingWindow
, MouseReleaseHdl
));
526 mxKernPairs
->connect_toggled(LINK(this, FontworkCharacterSpacingWindow
, KernSelectHdl
));
528 AddStatusListener( gsFontworkCharacterSpacing
);
529 AddStatusListener( gsFontworkKernCharacterPairs
);
531 // See TODO in svx/source/toolbars/fontworkbar.cxx for SID_FONTWORK_KERN_CHARACTER_PAIRS,
532 // the kernpairs setting is ignored, so hide the widget entirely
536 void FontworkCharacterSpacingWindow::GrabFocus()
538 mxVeryTight
->grab_focus();
541 void FontworkCharacterSpacingWindow::implSetCharacterSpacing( sal_Int32 nCharacterSpacing
, bool bEnabled
)
543 bool bSettingValue
= mbSettingValue
;
544 mbSettingValue
= true;
546 mxVeryTight
->set_sensitive(bEnabled
);
547 mxTight
->set_sensitive(bEnabled
);
548 mxNormal
->set_sensitive(bEnabled
);
549 mxLoose
->set_sensitive(bEnabled
);
550 mxVeryLoose
->set_sensitive(bEnabled
);
551 mxCustom
->set_sensitive(bEnabled
);
553 mxVeryTight
->set_active(false);
554 mxTight
->set_active(false);
555 mxNormal
->set_active(false);
556 mxLoose
->set_active(false);
557 mxVeryLoose
->set_active(false);
558 mxCustom
->set_active(true);
560 switch(nCharacterSpacing
)
563 mxVeryTight
->set_active(true);
566 mxTight
->set_active(true);
569 mxNormal
->set_active(true);
572 mxLoose
->set_active(true);
575 mxVeryLoose
->set_active(true);
579 mnCharacterSpacing
= nCharacterSpacing
;
581 mbSettingValue
= bSettingValue
;
584 void FontworkCharacterSpacingWindow::implSetKernCharacterPairs(bool bKernOnOff
, bool bEnabled
)
586 mxKernPairs
->set_sensitive(bEnabled
);
587 mxKernPairs
->set_active(bKernOnOff
);
590 void FontworkCharacterSpacingWindow::statusChanged( const css::frame::FeatureStateEvent
& Event
)
592 if( Event
.FeatureURL
.Main
== gsFontworkCharacterSpacing
)
594 if( !Event
.IsEnabled
)
596 implSetCharacterSpacing( 0, false );
600 sal_Int32 nValue
= 0;
601 if( Event
.State
>>= nValue
)
602 implSetCharacterSpacing( nValue
, true );
605 else if( Event
.FeatureURL
.Main
== gsFontworkKernCharacterPairs
)
607 if( !Event
.IsEnabled
)
609 implSetKernCharacterPairs(false, false);
614 if( Event
.State
>>= bValue
)
615 implSetKernCharacterPairs(bValue
, true);
620 IMPL_LINK_NOARG(FontworkCharacterSpacingWindow
, KernSelectHdl
, weld::Toggleable
&, void)
625 bool bKernOnOff
= mxKernPairs
->get_active();
626 Sequence
< PropertyValue
> aArgs
{ comphelper::makePropertyValue(
627 OUString(gsFontworkKernCharacterPairs
).copy(5), bKernOnOff
) };
629 mxControl
->dispatchCommand( gsFontworkKernCharacterPairs
, aArgs
);
630 mbCommandDispatched
= true;
632 implSetKernCharacterPairs(bKernOnOff
, true);
634 mxControl
->EndPopupMode();
637 void FontworkCharacterSpacingWindow::DispatchSpacingDialog()
639 Sequence
< PropertyValue
> aArgs
{ comphelper::makePropertyValue(
640 OUString(gsFontworkCharacterSpacing
).copy(5), mnCharacterSpacing
) };
642 rtl::Reference
<svt::PopupWindowController
> xControl(mxControl
);
643 xControl
->EndPopupMode();
644 xControl
->dispatchCommand(".uno:FontworkCharacterSpacingDialog", aArgs
);
645 mbCommandDispatched
= true;
648 IMPL_LINK(FontworkCharacterSpacingWindow
, SelectHdl
, weld::Toggleable
&, rButton
, void)
650 if (!rButton
.get_active())
656 // see MouseReleaseHdl for mbCommandDispatched check, there's no guarantee
657 // this toggle will happen before that mouse release though it does in
658 // practice for vcl and gtk
659 if (mbCommandDispatched
)
662 if (mxCustom
->get_active())
663 DispatchSpacingDialog();
666 sal_Int32 nCharacterSpacing
;
667 if (mxVeryTight
->get_active())
668 nCharacterSpacing
= 80;
669 else if (mxTight
->get_active())
670 nCharacterSpacing
= 90;
671 else if (mxLoose
->get_active())
672 nCharacterSpacing
= 120;
673 else if (mxVeryLoose
->get_active())
674 nCharacterSpacing
= 150;
676 nCharacterSpacing
= 100;
678 Sequence
< PropertyValue
> aArgs
{ comphelper::makePropertyValue(
679 OUString(gsFontworkCharacterSpacing
).copy(5), nCharacterSpacing
) };
681 mxControl
->dispatchCommand( gsFontworkCharacterSpacing
, aArgs
);
682 mbCommandDispatched
= true;
684 implSetCharacterSpacing( nCharacterSpacing
, true );
687 mxControl
->EndPopupMode();
690 IMPL_LINK_NOARG(FontworkCharacterSpacingWindow
, MouseReleaseHdl
, const MouseEvent
&, bool)
693 tdf#145296 if the "custom" radiobutton was presented preselected as
694 toggled on and the user clicked on it then there's no toggled signal sent
695 because the item was already toggled on and didn't change state.
697 So if that happens launch the custom spacing dialog explicitly here on
700 if (mxCustom
->get_active() && !mbCommandDispatched
)
702 DispatchSpacingDialog();
710 class FontworkCharacterSpacingControl
: public svt::PopupWindowController
713 explicit FontworkCharacterSpacingControl( const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
);
715 virtual std::unique_ptr
<WeldToolbarPopup
> weldPopupWindow() override
;
716 virtual VclPtr
<vcl::Window
> createVclPopupWindow( vcl::Window
* pParent
) override
;
719 virtual void SAL_CALL
initialize( const css::uno::Sequence
< css::uno::Any
>& aArguments
) override
;
722 virtual OUString SAL_CALL
getImplementationName() override
;
723 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
728 FontworkCharacterSpacingControl::FontworkCharacterSpacingControl( const Reference
< XComponentContext
>& rxContext
)
729 : svt::PopupWindowController( rxContext
, Reference
< css::frame::XFrame
>(), ".uno:FontworkCharacterSpacingFloater" )
733 std::unique_ptr
<WeldToolbarPopup
> FontworkCharacterSpacingControl::weldPopupWindow()
735 return std::make_unique
<FontworkCharacterSpacingWindow
>(this, m_pToolbar
);
738 VclPtr
<vcl::Window
> FontworkCharacterSpacingControl::createVclPopupWindow( vcl::Window
* pParent
)
740 mxInterimPopover
= VclPtr
<InterimToolbarPopup
>::Create(getFrameInterface(), pParent
,
741 std::make_unique
<FontworkCharacterSpacingWindow
>(this, pParent
->GetFrameWeld()));
743 mxInterimPopover
->Show();
745 return mxInterimPopover
;
749 void SAL_CALL
FontworkCharacterSpacingControl::initialize( const css::uno::Sequence
< css::uno::Any
>& aArguments
)
751 svt::PopupWindowController::initialize( aArguments
);
755 mxPopoverContainer
.reset(new ToolbarPopupContainer(m_pToolbar
));
756 m_pToolbar
->set_item_popover(m_aCommandURL
, mxPopoverContainer
->getTopLevel());
759 ToolBox
* pToolBox
= nullptr;
761 if ( getToolboxId( nId
, &pToolBox
) )
762 pToolBox
->SetItemBits( nId
, pToolBox
->GetItemBits( nId
) | ToolBoxItemBits::DROPDOWNONLY
);
768 OUString
FontworkCharacterSpacingControl::getImplementationName()
770 return "com.sun.star.comp.svx.FontworkCharacterSpacingController";
774 Sequence
< OUString
> FontworkCharacterSpacingControl::getSupportedServiceNames()
776 Sequence
<OUString
> aSNS
{ "com.sun.star.frame.ToolbarController" };
781 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
782 com_sun_star_comp_svx_FontworkCharacterSpacingControl_get_implementation(
783 css::uno::XComponentContext
* xContext
,
784 css::uno::Sequence
<css::uno::Any
> const &)
786 return cppu::acquire(new FontworkCharacterSpacingControl(xContext
));
789 FontworkCharacterSpacingDialog::FontworkCharacterSpacingDialog(weld::Window
* pParent
, sal_Int32 nScale
)
790 : GenericDialogController(pParent
, "svx/ui/fontworkspacingdialog.ui", "FontworkSpacingDialog")
791 , m_xMtrScale(m_xBuilder
->weld_metric_spin_button("entry", FieldUnit::PERCENT
))
793 m_xMtrScale
->set_value(nScale
, FieldUnit::PERCENT
);
796 FontworkCharacterSpacingDialog::~FontworkCharacterSpacingDialog()
800 sal_Int32
FontworkCharacterSpacingDialog::getScale() const
802 return static_cast<sal_Int32
>(m_xMtrScale
->get_value(FieldUnit::PERCENT
));
807 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */