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>
25 #include <comphelper/servicehelper.hxx>
26 #include <comphelper/processfactory.hxx>
27 #include <com/sun/star/frame/ModuleManager.hpp>
29 #include <vcl/toolbox.hxx>
30 #include <vcl/virdev.hxx>
32 #include <sfx2/viewsh.hxx>
34 #include <svl/itempool.hxx>
36 #include <svtools/toolbarmenu.hxx>
37 #include <svtools/popupwindowcontroller.hxx>
39 #include <svx/fmmodel.hxx>
40 #include <svx/svdpage.hxx>
41 #include <svx/svdobj.hxx>
42 #include <svx/svdview.hxx>
44 #include <svx/gallery.hxx>
45 #include <svx/fontworkgallery.hxx>
47 #include <tools/UnitConversion.hxx>
51 #include <svx/strings.hrc>
52 #include <svx/dialmgr.hxx>
54 using namespace ::com::sun::star::uno
;
55 using namespace ::com::sun::star::beans
;
60 FontWorkGalleryDialog::FontWorkGalleryDialog(weld::Window
* pParent
, SdrView
& rSdrView
,
61 Reference
<css::frame::XFrame
> xFrame
)
62 : GenericDialogController(pParent
, u
"svx/ui/fontworkgallerydialog.ui"_ustr
, u
"FontworkGalleryDialog"_ustr
)
65 , mbInsertIntoPage(true)
66 , mpDestModel(nullptr)
67 , maCtlFavorites(m_xBuilder
->weld_icon_view(u
"ctlFavoriteswin"_ustr
))
68 , mxOKButton(m_xBuilder
->weld_button(u
"ok"_ustr
))
69 , mxFrame(std::move(xFrame
))
72 maCtlFavorites
->set_size_request(aSize
.Width(), aSize
.Height());
74 maCtlFavorites
->connect_item_activated( LINK( this, FontWorkGalleryDialog
, DoubleClickFavoriteHdl
) );
75 maCtlFavorites
->connect_query_tooltip(LINK(this, FontWorkGalleryDialog
, QueryTooltipHandler
));
76 mxOKButton
->connect_clicked(LINK(this, FontWorkGalleryDialog
, ClickOKHdl
));
78 initFavorites( GALLERY_THEME_FONTWORK
);
79 fillFavorites( GALLERY_THEME_FONTWORK
);
82 FontWorkGalleryDialog::~FontWorkGalleryDialog()
86 void FontWorkGalleryDialog::initFavorites(sal_uInt16 nThemeId
)
88 // the favorites are read via the gallery
89 sal_uInt32 nFavCount
= GalleryExplorer::GetSdrObjCount( nThemeId
);
92 GalleryExplorer::BeginLocking(nThemeId
);
95 FmFormModel
*pModel
= nullptr;
97 for( nModelPos
= 0; nModelPos
< nFavCount
; nModelPos
++ )
101 if (GalleryExplorer::GetSdrObj(nThemeId
, nModelPos
, pModel
, &aThumb
) && !aThumb
.IsEmpty())
103 VclPtr
< VirtualDevice
> pVDev
= VclPtr
<VirtualDevice
>::Create();
104 const Point
aNull(0, 0);
106 if (pVDev
->GetDPIScaleFactor() > 1)
107 aThumb
.Scale(pVDev
->GetDPIScaleFactor(), pVDev
->GetDPIScaleFactor());
109 const Size
aSize(aThumb
.GetSizePixel());
111 pVDev
->SetOutputSizePixel(aSize
);
113 static const sal_uInt32
nLen(8);
114 static const Color
aW(COL_WHITE
);
115 static const Color
aG(0xef, 0xef, 0xef);
117 pVDev
->DrawCheckered(aNull
, aSize
, nLen
, aW
, aG
);
119 pVDev
->DrawBitmapEx(aNull
, aThumb
);
120 maFavoritesHorizontal
.emplace_back(pVDev
);
124 // release gallery theme
125 GalleryExplorer::EndLocking(nThemeId
);
128 void FontWorkGalleryDialog::fillFavorites(sal_uInt16 nThemeId
)
130 mnThemeId
= nThemeId
;
132 auto nFavCount
= maFavoritesHorizontal
.size();
134 maCtlFavorites
->clear();
135 maIdToTitleMap
.clear();
137 std::vector
<OUString
> aTitles
;
138 (void)GalleryExplorer::FillObjListTitle(nThemeId
, aTitles
);
139 assert(aTitles
.size() == nFavCount
);
141 for( size_t nFavorite
= 1; nFavorite
<= nFavCount
; nFavorite
++ )
143 OUString sId
= OUString::number(static_cast<sal_uInt16
>(nFavorite
));
144 maIdToTitleMap
.emplace(sId
, aTitles
.at(nFavorite
- 1));
145 maCtlFavorites
->insert(-1, nullptr, &sId
, maFavoritesHorizontal
[nFavorite
- 1], nullptr);
148 if (maCtlFavorites
->n_children())
149 maCtlFavorites
->select(0);
152 void FontWorkGalleryDialog::SetSdrObjectRef( SdrModel
* pModel
)
154 mbInsertIntoPage
= false;
155 mpDestModel
= pModel
;
158 void FontWorkGalleryDialog::insertSelectedFontwork()
160 OUString sItemId
= maCtlFavorites
->get_selected_id();
161 if (sItemId
.isEmpty())
164 sal_Int32 nItemId
= sItemId
.toInt32();
171 if( !GalleryExplorer::GetSdrObj( mnThemeId
, nItemId
-1, &aModel
) )
174 SdrPage
* pPage
= aModel
.GetPage(0);
175 if( !(pPage
&& pPage
->GetObjCount()) )
178 // tdf#116993 Calc uses a 'special' mode for this dialog in being the
179 // only caller of ::SetSdrObjectRef. Only in that case mpDestModel seems
180 // to be the correct target SdrModel.
181 // If this is not used, the correct SdrModel seems to be the one from
182 // the mrSdrView that is used to insert (InsertObjectAtView below) the
184 const bool bUseSpecialCalcMode(!mbInsertIntoPage
&& nullptr != mpDestModel
);
186 // center shape on current view
187 OutputDevice
* pOutDev(mrSdrView
.GetFirstOutputDevice());
192 // Clone directly to target SdrModel (may be different due to user/caller (!))
193 rtl::Reference
<SdrObject
> xNewObject(
194 pPage
->GetObj(0)->CloneSdrObject(
195 bUseSpecialCalcMode
? *mpDestModel
: mrSdrView
.getSdrModelFromSdrView()));
197 const Reference
<XComponentContext
>& xContext
= comphelper::getProcessComponentContext();
198 css::uno::Reference
<css::frame::XModuleManager
> xModuleManager
=
199 css::frame::ModuleManager::create(xContext
);
200 OUString aModuleIdentifier
= xModuleManager
->identify(mxFrame
);
202 if (aModuleIdentifier
!= "com.sun.star.drawing.DrawingDocument" &&
203 aModuleIdentifier
!= "com.sun.star.presentation.PresentationDocument" )
205 xNewObject
->SetName(SvxResId(STR_ObjNameSingulFONTWORK
) + u
" 1");
206 xNewObject
->MakeNameUnique();
209 xNewObject
->SetName(OUString());
212 // Since the 'old' ::CloneSdrObject also copies the SdrPage* the
213 // SdrObject::getUnoShape() *will* create the wrong UNO API object
214 // early. This IS one of the reasons I do change these things - this
215 // error does not happen with my next change I am working on already
216 // ARGH! For now, reset the SdrPage* to nullptr.
217 // What sense does it have to copy the SdrPage* of the original SdrObject ?!?
218 // TTTT: This also *might* be the hidden reason for the strange code at the
219 // end of SdrObject::SetPage that tries to delete the SvxShape under some
221 // xNewObject->SetPage(nullptr);
223 tools::Rectangle
aObjRect( xNewObject
->GetLogicRect() );
225 Size aFontworkSize
= aObjRect
.GetSize();
227 SfxViewShell
* pKitViewShell
= comphelper::LibreOfficeKit::isActive() ?
228 SfxViewShell::Current() : nullptr;
231 aPagePos
= convertTwipToMm100(pKitViewShell
->getLOKVisibleArea().Center());
233 sal_Int32 nLOKViewWidth
= 0.8 * convertTwipToMm100(pKitViewShell
->getLOKVisibleArea().getOpenWidth());
234 if (aFontworkSize
.getWidth() > nLOKViewWidth
)
236 double fScale
= static_cast<double>(aFontworkSize
.getWidth()) / nLOKViewWidth
;
237 aFontworkSize
.setWidth(aFontworkSize
.getWidth() / fScale
);
238 aFontworkSize
.setHeight(aFontworkSize
.getHeight() / fScale
);
243 Size aSize
= pOutDev
->GetOutputSizePixel();
244 tools::Rectangle
aPixelVisRect(Point(0,0), aSize
);
245 tools::Rectangle aVisArea
= pOutDev
->PixelToLogic(aPixelVisRect
);
247 aPagePos
= aVisArea
.Center();
250 if (aPagePos
.getX() > aFontworkSize
.getWidth() / 2)
251 aPagePos
.AdjustX( -(aFontworkSize
.getWidth() / 2) );
252 if (aPagePos
.getY() > aFontworkSize
.getHeight() / 2)
253 aPagePos
.AdjustY( -(aFontworkSize
.getHeight() / 2) );
255 tools::Rectangle
aNewObjectRectangle(aPagePos
, aFontworkSize
);
256 xNewObject
->SetLogicRect(aNewObjectRectangle
);
258 if (bUseSpecialCalcMode
)
260 mxSdrObject
= std::move(xNewObject
);
264 SdrPageView
* pPV(mrSdrView
.GetSdrPageView());
268 mrSdrView
.InsertObjectAtView( xNewObject
.get(), *pPV
);
273 IMPL_LINK_NOARG(FontWorkGalleryDialog
, ClickOKHdl
, weld::Button
&, void)
275 insertSelectedFontwork();
276 m_xDialog
->response(RET_OK
);
279 IMPL_LINK_NOARG(FontWorkGalleryDialog
, DoubleClickFavoriteHdl
, weld::IconView
&, bool)
281 insertSelectedFontwork();
282 m_xDialog
->response(RET_OK
);
286 IMPL_LINK(FontWorkGalleryDialog
, QueryTooltipHandler
, const weld::TreeIter
&, iter
, OUString
)
288 const OUString id
= maCtlFavorites
->get_id(iter
);
289 auto it
= maIdToTitleMap
.find(id
);
290 return it
!= maIdToTitleMap
.end() ? it
->second
: OUString();
295 class FontworkAlignmentWindow final
: public WeldToolbarPopup
298 FontworkAlignmentWindow(svt::PopupWindowController
* pControl
, weld::Widget
* pParentWindow
);
299 virtual void GrabFocus() override
301 mxLeft
->grab_focus();
303 virtual void statusChanged( const css::frame::FeatureStateEvent
& Event
) override
;
306 rtl::Reference
<svt::PopupWindowController
> mxControl
;
307 std::unique_ptr
<weld::RadioButton
> mxLeft
;
308 std::unique_ptr
<weld::RadioButton
> mxCenter
;
309 std::unique_ptr
<weld::RadioButton
> mxRight
;
310 std::unique_ptr
<weld::RadioButton
> mxStretch
;
313 DECL_LINK( SelectHdl
, weld::Toggleable
&, void );
315 void implSetAlignment( int nAlignmentMode
, bool bEnabled
);
320 constexpr OUString
gsFontworkAlignment(u
".uno:FontworkAlignment"_ustr
);
322 FontworkAlignmentWindow::FontworkAlignmentWindow(svt::PopupWindowController
* pControl
, weld::Widget
* pParent
)
323 : WeldToolbarPopup(pControl
->getFrameInterface(), pParent
, u
"svx/ui/fontworkalignmentcontrol.ui"_ustr
, u
"FontworkAlignmentControl"_ustr
)
324 , mxControl(pControl
)
325 , mxLeft(m_xBuilder
->weld_radio_button(u
"left"_ustr
))
326 , mxCenter(m_xBuilder
->weld_radio_button(u
"center"_ustr
))
327 , mxRight(m_xBuilder
->weld_radio_button(u
"right"_ustr
))
328 , mxStretch(m_xBuilder
->weld_radio_button(u
"stretch"_ustr
))
329 , mbSettingValue(false)
331 mxLeft
->connect_toggled(LINK(this, FontworkAlignmentWindow
, SelectHdl
));
332 mxCenter
->connect_toggled(LINK(this, FontworkAlignmentWindow
, SelectHdl
));
333 mxRight
->connect_toggled(LINK(this, FontworkAlignmentWindow
, SelectHdl
));
334 mxStretch
->connect_toggled(LINK(this, FontworkAlignmentWindow
, SelectHdl
));
336 AddStatusListener( gsFontworkAlignment
);
339 void FontworkAlignmentWindow::implSetAlignment( int nSurface
, bool bEnabled
)
341 bool bSettingValue
= mbSettingValue
;
342 mbSettingValue
= true;
343 mxLeft
->set_active(nSurface
== 0 && bEnabled
);
344 mxLeft
->set_sensitive(bEnabled
);
345 mxCenter
->set_active(nSurface
== 1 && bEnabled
);
346 mxCenter
->set_sensitive(bEnabled
);
347 mxRight
->set_active(nSurface
== 2 && bEnabled
);
348 mxRight
->set_sensitive(bEnabled
);
349 //Refer https://bugs.documentfoundation.org/show_bug.cgi?id=145092 for why following lines are commented
350 //mxWord->set_active(nSurface == 3 && bEnabled);
351 //mxWord->set_sensitive(bEnabled);
352 mxStretch
->set_active(nSurface
== 4 && bEnabled
);
353 mxStretch
->set_sensitive(bEnabled
);
354 mbSettingValue
= bSettingValue
;
357 void FontworkAlignmentWindow::statusChanged( const css::frame::FeatureStateEvent
& Event
)
359 if( Event
.FeatureURL
.Main
!= gsFontworkAlignment
)
362 if( !Event
.IsEnabled
)
364 implSetAlignment( 0, false );
368 sal_Int32 nValue
= 0;
369 if( Event
.State
>>= nValue
)
370 implSetAlignment( nValue
, true );
374 IMPL_LINK(FontworkAlignmentWindow
, SelectHdl
, weld::Toggleable
&, rButton
, void)
376 if (mbSettingValue
|| !rButton
.get_active())
379 sal_Int32 nAlignment
;
380 if (mxLeft
->get_active())
382 else if (mxCenter
->get_active())
384 else if (mxRight
->get_active())
386 //Refer https://bugs.documentfoundation.org/show_bug.cgi?id=145092 for why following lines are commented
387 //else if (mxWord->get_active())
392 Sequence
< PropertyValue
> aArgs
{ comphelper::makePropertyValue(
393 gsFontworkAlignment
.copy(5), nAlignment
) };
395 mxControl
->dispatchCommand( gsFontworkAlignment
, aArgs
);
397 implSetAlignment( nAlignment
, true );
399 mxControl
->EndPopupMode();
404 class FontworkAlignmentControl
: public svt::PopupWindowController
407 explicit FontworkAlignmentControl( const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
);
409 virtual std::unique_ptr
<WeldToolbarPopup
> weldPopupWindow() override
;
410 virtual VclPtr
<vcl::Window
> createVclPopupWindow( vcl::Window
* pParent
) override
;
413 virtual void SAL_CALL
initialize( const css::uno::Sequence
< css::uno::Any
>& aArguments
) override
;
416 virtual OUString SAL_CALL
getImplementationName() override
;
417 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
422 FontworkAlignmentControl::FontworkAlignmentControl( const Reference
< XComponentContext
>& rxContext
)
423 : svt::PopupWindowController( rxContext
, Reference
< css::frame::XFrame
>(), u
".uno:FontworkAlignment"_ustr
)
427 std::unique_ptr
<WeldToolbarPopup
> FontworkAlignmentControl::weldPopupWindow()
429 return std::make_unique
<FontworkAlignmentWindow
>(this, m_pToolbar
);
432 VclPtr
<vcl::Window
> FontworkAlignmentControl::createVclPopupWindow( vcl::Window
* pParent
)
434 mxInterimPopover
= VclPtr
<InterimToolbarPopup
>::Create(getFrameInterface(), pParent
,
435 std::make_unique
<FontworkAlignmentWindow
>(this, pParent
->GetFrameWeld()));
437 mxInterimPopover
->Show();
439 return mxInterimPopover
;
443 void SAL_CALL
FontworkAlignmentControl::initialize( const css::uno::Sequence
< css::uno::Any
>& aArguments
)
445 svt::PopupWindowController::initialize( aArguments
);
449 mxPopoverContainer
.reset(new ToolbarPopupContainer(m_pToolbar
));
450 m_pToolbar
->set_item_popover(m_aCommandURL
, mxPopoverContainer
->getTopLevel());
453 ToolBox
* pToolBox
= nullptr;
455 if ( getToolboxId( nId
, &pToolBox
) )
456 pToolBox
->SetItemBits( nId
, pToolBox
->GetItemBits( nId
) | ToolBoxItemBits::DROPDOWNONLY
);
462 OUString
FontworkAlignmentControl::getImplementationName()
464 return u
"com.sun.star.comp.svx.FontworkAlignmentController"_ustr
;
468 Sequence
< OUString
> FontworkAlignmentControl::getSupportedServiceNames()
470 return { u
"com.sun.star.frame.ToolbarController"_ustr
};
474 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
475 com_sun_star_comp_svx_FontworkAlignmentControl_get_implementation(
476 css::uno::XComponentContext
* xContext
,
477 css::uno::Sequence
<css::uno::Any
> const &)
479 return cppu::acquire(new FontworkAlignmentControl(xContext
));
484 class FontworkCharacterSpacingWindow final
: public WeldToolbarPopup
487 FontworkCharacterSpacingWindow(svt::PopupWindowController
* pControl
, weld::Widget
* pParentWindow
);
488 virtual void GrabFocus() override
;
490 virtual void statusChanged( const css::frame::FeatureStateEvent
& Event
) override
;
492 rtl::Reference
<svt::PopupWindowController
> mxControl
;
493 std::unique_ptr
<weld::RadioButton
> mxVeryTight
;
494 std::unique_ptr
<weld::RadioButton
> mxTight
;
495 std::unique_ptr
<weld::RadioButton
> mxNormal
;
496 std::unique_ptr
<weld::RadioButton
> mxLoose
;
497 std::unique_ptr
<weld::RadioButton
> mxVeryLoose
;
498 std::unique_ptr
<weld::RadioButton
> mxCustom
;
499 std::unique_ptr
<weld::CheckButton
> mxKernPairs
;
500 sal_Int32 mnCharacterSpacing
;
502 bool mbCommandDispatched
;
504 DECL_LINK( KernSelectHdl
, weld::Toggleable
&, void );
505 DECL_LINK( SelectHdl
, weld::Toggleable
&, void );
506 DECL_LINK( MouseReleaseHdl
, const MouseEvent
&, bool );
508 void implSetCharacterSpacing( sal_Int32 nCharacterSpacing
, bool bEnabled
);
509 void implSetKernCharacterPairs(bool bKernOnOff
, bool bEnabled
);
510 void DispatchSpacingDialog();
515 constexpr OUString
gsFontworkCharacterSpacing(u
".uno:FontworkCharacterSpacing"_ustr
);
516 constexpr OUString
gsFontworkKernCharacterPairs(u
".uno:FontworkKernCharacterPairs"_ustr
);
518 FontworkCharacterSpacingWindow::FontworkCharacterSpacingWindow(svt::PopupWindowController
* pControl
, weld::Widget
* pParent
)
519 : WeldToolbarPopup(pControl
->getFrameInterface(), pParent
, u
"svx/ui/fontworkcharacterspacingcontrol.ui"_ustr
, u
"FontworkCharacterSpacingControl"_ustr
)
520 , mxControl(pControl
)
521 , mxVeryTight(m_xBuilder
->weld_radio_button(u
"verytight"_ustr
))
522 , mxTight(m_xBuilder
->weld_radio_button(u
"tight"_ustr
))
523 , mxNormal(m_xBuilder
->weld_radio_button(u
"normal"_ustr
))
524 , mxLoose(m_xBuilder
->weld_radio_button(u
"loose"_ustr
))
525 , mxVeryLoose(m_xBuilder
->weld_radio_button(u
"veryloose"_ustr
))
526 , mxCustom(m_xBuilder
->weld_radio_button(u
"custom"_ustr
))
527 , mxKernPairs(m_xBuilder
->weld_check_button(u
"kernpairs"_ustr
))
528 , mnCharacterSpacing(0)
529 , mbSettingValue(false)
530 , mbCommandDispatched(false)
532 mxVeryTight
->connect_toggled(LINK(this, FontworkCharacterSpacingWindow
, SelectHdl
));
533 mxTight
->connect_toggled(LINK(this, FontworkCharacterSpacingWindow
, SelectHdl
));
534 mxNormal
->connect_toggled(LINK(this, FontworkCharacterSpacingWindow
, SelectHdl
));
535 mxLoose
->connect_toggled(LINK(this, FontworkCharacterSpacingWindow
, SelectHdl
));
536 mxVeryLoose
->connect_toggled(LINK(this, FontworkCharacterSpacingWindow
, SelectHdl
));
537 mxCustom
->connect_toggled(LINK(this, FontworkCharacterSpacingWindow
, SelectHdl
));
538 mxCustom
->connect_mouse_release(LINK(this, FontworkCharacterSpacingWindow
, MouseReleaseHdl
));
540 mxKernPairs
->connect_toggled(LINK(this, FontworkCharacterSpacingWindow
, KernSelectHdl
));
542 AddStatusListener( gsFontworkCharacterSpacing
);
543 AddStatusListener( gsFontworkKernCharacterPairs
);
545 // See TODO in svx/source/toolbars/fontworkbar.cxx for SID_FONTWORK_KERN_CHARACTER_PAIRS,
546 // the kernpairs setting is ignored, so hide the widget entirely
550 void FontworkCharacterSpacingWindow::GrabFocus()
552 mxVeryTight
->grab_focus();
555 void FontworkCharacterSpacingWindow::implSetCharacterSpacing( sal_Int32 nCharacterSpacing
, bool bEnabled
)
557 bool bSettingValue
= mbSettingValue
;
558 mbSettingValue
= true;
560 mxVeryTight
->set_sensitive(bEnabled
);
561 mxTight
->set_sensitive(bEnabled
);
562 mxNormal
->set_sensitive(bEnabled
);
563 mxLoose
->set_sensitive(bEnabled
);
564 mxVeryLoose
->set_sensitive(bEnabled
);
565 mxCustom
->set_sensitive(bEnabled
);
567 mxVeryTight
->set_active(false);
568 mxTight
->set_active(false);
569 mxNormal
->set_active(false);
570 mxLoose
->set_active(false);
571 mxVeryLoose
->set_active(false);
572 mxCustom
->set_active(true);
574 switch(nCharacterSpacing
)
577 mxVeryTight
->set_active(true);
580 mxTight
->set_active(true);
583 mxNormal
->set_active(true);
586 mxLoose
->set_active(true);
589 mxVeryLoose
->set_active(true);
593 mnCharacterSpacing
= nCharacterSpacing
;
595 mbSettingValue
= bSettingValue
;
598 void FontworkCharacterSpacingWindow::implSetKernCharacterPairs(bool bKernOnOff
, bool bEnabled
)
600 mxKernPairs
->set_sensitive(bEnabled
);
601 mxKernPairs
->set_active(bKernOnOff
);
604 void FontworkCharacterSpacingWindow::statusChanged( const css::frame::FeatureStateEvent
& Event
)
606 if( Event
.FeatureURL
.Main
== gsFontworkCharacterSpacing
)
608 if( !Event
.IsEnabled
)
610 implSetCharacterSpacing( 0, false );
614 sal_Int32 nValue
= 0;
615 if( Event
.State
>>= nValue
)
616 implSetCharacterSpacing( nValue
, true );
619 else if( Event
.FeatureURL
.Main
== gsFontworkKernCharacterPairs
)
621 if( !Event
.IsEnabled
)
623 implSetKernCharacterPairs(false, false);
628 if( Event
.State
>>= bValue
)
629 implSetKernCharacterPairs(bValue
, true);
634 IMPL_LINK_NOARG(FontworkCharacterSpacingWindow
, KernSelectHdl
, weld::Toggleable
&, void)
639 bool bKernOnOff
= mxKernPairs
->get_active();
640 Sequence
< PropertyValue
> aArgs
{ comphelper::makePropertyValue(
641 gsFontworkKernCharacterPairs
.copy(5), bKernOnOff
) };
643 mxControl
->dispatchCommand( gsFontworkKernCharacterPairs
, aArgs
);
644 mbCommandDispatched
= true;
646 implSetKernCharacterPairs(bKernOnOff
, true);
648 mxControl
->EndPopupMode();
651 void FontworkCharacterSpacingWindow::DispatchSpacingDialog()
653 Sequence
< PropertyValue
> aArgs
{ comphelper::makePropertyValue(
654 gsFontworkCharacterSpacing
.copy(5), mnCharacterSpacing
) };
656 rtl::Reference
<svt::PopupWindowController
> xControl(mxControl
);
657 xControl
->EndPopupMode();
658 xControl
->dispatchCommand(u
".uno:FontworkCharacterSpacingDialog"_ustr
, aArgs
);
659 mbCommandDispatched
= true;
662 IMPL_LINK(FontworkCharacterSpacingWindow
, SelectHdl
, weld::Toggleable
&, rButton
, void)
664 if (!rButton
.get_active())
670 // see MouseReleaseHdl for mbCommandDispatched check, there's no guarantee
671 // this toggle will happen before that mouse release though it does in
672 // practice for vcl and gtk
673 if (mbCommandDispatched
)
676 if (mxCustom
->get_active())
677 DispatchSpacingDialog();
680 sal_Int32 nCharacterSpacing
;
681 if (mxVeryTight
->get_active())
682 nCharacterSpacing
= 80;
683 else if (mxTight
->get_active())
684 nCharacterSpacing
= 90;
685 else if (mxLoose
->get_active())
686 nCharacterSpacing
= 120;
687 else if (mxVeryLoose
->get_active())
688 nCharacterSpacing
= 150;
690 nCharacterSpacing
= 100;
692 Sequence
< PropertyValue
> aArgs
{ comphelper::makePropertyValue(
693 gsFontworkCharacterSpacing
.copy(5), nCharacterSpacing
) };
695 mxControl
->dispatchCommand( gsFontworkCharacterSpacing
, aArgs
);
696 mbCommandDispatched
= true;
698 implSetCharacterSpacing( nCharacterSpacing
, true );
701 mxControl
->EndPopupMode();
704 IMPL_LINK_NOARG(FontworkCharacterSpacingWindow
, MouseReleaseHdl
, const MouseEvent
&, bool)
707 tdf#145296 if the "custom" radiobutton was presented preselected as
708 toggled on and the user clicked on it then there's no toggled signal sent
709 because the item was already toggled on and didn't change state.
711 So if that happens launch the custom spacing dialog explicitly here on
714 if (mxCustom
->get_active() && !mbCommandDispatched
)
716 DispatchSpacingDialog();
724 class FontworkCharacterSpacingControl
: public svt::PopupWindowController
727 explicit FontworkCharacterSpacingControl( const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
);
729 virtual std::unique_ptr
<WeldToolbarPopup
> weldPopupWindow() override
;
730 virtual VclPtr
<vcl::Window
> createVclPopupWindow( vcl::Window
* pParent
) override
;
733 virtual void SAL_CALL
initialize( const css::uno::Sequence
< css::uno::Any
>& aArguments
) override
;
736 virtual OUString SAL_CALL
getImplementationName() override
;
737 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
742 FontworkCharacterSpacingControl::FontworkCharacterSpacingControl( const Reference
< XComponentContext
>& rxContext
)
743 : svt::PopupWindowController( rxContext
, Reference
< css::frame::XFrame
>(), u
".uno:FontworkCharacterSpacingFloater"_ustr
)
747 std::unique_ptr
<WeldToolbarPopup
> FontworkCharacterSpacingControl::weldPopupWindow()
749 return std::make_unique
<FontworkCharacterSpacingWindow
>(this, m_pToolbar
);
752 VclPtr
<vcl::Window
> FontworkCharacterSpacingControl::createVclPopupWindow( vcl::Window
* pParent
)
754 mxInterimPopover
= VclPtr
<InterimToolbarPopup
>::Create(getFrameInterface(), pParent
,
755 std::make_unique
<FontworkCharacterSpacingWindow
>(this, pParent
->GetFrameWeld()));
757 mxInterimPopover
->Show();
759 return mxInterimPopover
;
763 void SAL_CALL
FontworkCharacterSpacingControl::initialize( const css::uno::Sequence
< css::uno::Any
>& aArguments
)
765 svt::PopupWindowController::initialize( aArguments
);
769 mxPopoverContainer
.reset(new ToolbarPopupContainer(m_pToolbar
));
770 m_pToolbar
->set_item_popover(m_aCommandURL
, mxPopoverContainer
->getTopLevel());
773 ToolBox
* pToolBox
= nullptr;
775 if ( getToolboxId( nId
, &pToolBox
) )
776 pToolBox
->SetItemBits( nId
, pToolBox
->GetItemBits( nId
) | ToolBoxItemBits::DROPDOWNONLY
);
782 OUString
FontworkCharacterSpacingControl::getImplementationName()
784 return u
"com.sun.star.comp.svx.FontworkCharacterSpacingController"_ustr
;
788 Sequence
< OUString
> FontworkCharacterSpacingControl::getSupportedServiceNames()
790 Sequence
<OUString
> aSNS
{ u
"com.sun.star.frame.ToolbarController"_ustr
};
795 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
796 com_sun_star_comp_svx_FontworkCharacterSpacingControl_get_implementation(
797 css::uno::XComponentContext
* xContext
,
798 css::uno::Sequence
<css::uno::Any
> const &)
800 return cppu::acquire(new FontworkCharacterSpacingControl(xContext
));
803 FontworkCharacterSpacingDialog::FontworkCharacterSpacingDialog(weld::Window
* pParent
, sal_Int32 nScale
)
804 : GenericDialogController(pParent
, u
"svx/ui/fontworkspacingdialog.ui"_ustr
, u
"FontworkSpacingDialog"_ustr
)
805 , m_xMtrScale(m_xBuilder
->weld_metric_spin_button(u
"entry"_ustr
, FieldUnit::PERCENT
))
807 m_xMtrScale
->set_value(nScale
, FieldUnit::PERCENT
);
810 FontworkCharacterSpacingDialog::~FontworkCharacterSpacingDialog()
814 sal_Int32
FontworkCharacterSpacingDialog::getScale() const
816 return static_cast<sal_Int32
>(m_xMtrScale
->get_value(FieldUnit::PERCENT
));
821 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */