LibreOffice Module svx (master) 1
fontworkgallery.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
21#include <com/sun/star/text/WritingMode.hpp>
22
23#include <comphelper/lok.hxx>
25
26#include <vcl/toolbox.hxx>
27#include <vcl/virdev.hxx>
28
29#include <sfx2/viewsh.hxx>
30
31#include <svl/itempool.hxx>
32
35
36#include <svx/fmmodel.hxx>
37#include <svx/svdpage.hxx>
38#include <svx/svdobj.hxx>
39#include <svx/svdview.hxx>
40
41#include <svx/gallery.hxx>
43
45
46#include <algorithm>
47#include <memory>
48
49using namespace ::com::sun::star::uno;
50using namespace ::com::sun::star::lang;
51using namespace ::com::sun::star::beans;
52
53namespace svx
54{
55
57 : GenericDialogController(pParent, "svx/ui/fontworkgallerydialog.ui", "FontworkGalleryDialog")
58 , mnThemeId(0xffff)
59 , mrSdrView(rSdrView)
60 , mbInsertIntoPage(true)
61 , mpDestModel(nullptr)
62 , maCtlFavorites(m_xBuilder->weld_icon_view("ctlFavoriteswin"))
63 , mxOKButton(m_xBuilder->weld_button("ok"))
64{
65 Size aSize(530, 400);
66 maCtlFavorites->set_size_request(aSize.Width(), aSize.Height());
67
68 maCtlFavorites->connect_item_activated( LINK( this, FontWorkGalleryDialog, DoubleClickFavoriteHdl ) );
69 mxOKButton->connect_clicked(LINK(this, FontWorkGalleryDialog, ClickOKHdl));
70
73}
74
76{
77}
78
79void FontWorkGalleryDialog::initFavorites(sal_uInt16 nThemeId)
80{
81 // the favorites are read via the gallery
82 sal_uInt32 nFavCount = GalleryExplorer::GetSdrObjCount( nThemeId );
83
84 // lock gallery theme
86
87 sal_uInt32 nModelPos;
88 FmFormModel *pModel = nullptr;
89
90 for( nModelPos = 0; nModelPos < nFavCount; nModelPos++ )
91 {
92 BitmapEx aThumb;
93
94 if (GalleryExplorer::GetSdrObj(nThemeId, nModelPos, pModel, &aThumb) && !aThumb.IsEmpty())
95 {
97 const Point aNull(0, 0);
98
99 if (pVDev->GetDPIScaleFactor() > 1)
100 aThumb.Scale(pVDev->GetDPIScaleFactor(), pVDev->GetDPIScaleFactor());
101
102 const Size aSize(aThumb.GetSizePixel());
103
104 pVDev->SetOutputSizePixel(aSize);
105
106 static const sal_uInt32 nLen(8);
107 static const Color aW(COL_WHITE);
108 static const Color aG(0xef, 0xef, 0xef);
109
110 pVDev->DrawCheckered(aNull, aSize, nLen, aW, aG);
111
112 pVDev->DrawBitmapEx(aNull, aThumb);
113 maFavoritesHorizontal.emplace_back(pVDev);
114 }
115 }
116
117 // release gallery theme
119}
120
122{
123 mnThemeId = nThemeId;
124
125 auto nFavCount = maFavoritesHorizontal.size();
126
127 maCtlFavorites->clear();
128
129 for( size_t nFavorite = 1; nFavorite <= nFavCount; nFavorite++ )
130 {
131 OUString sId = OUString::number(static_cast<sal_uInt16>(nFavorite));
132 maCtlFavorites->insert(-1, nullptr, &sId, maFavoritesHorizontal[nFavorite - 1], nullptr);
133 }
134
135 if (maCtlFavorites->n_children())
136 maCtlFavorites->select(0);
137}
138
140{
141 mbInsertIntoPage = false;
142 mpDestModel = pModel;
143}
144
146{
147 OUString sItemId = maCtlFavorites->get_selected_id();
148 if (sItemId.isEmpty())
149 return;
150
151 sal_Int32 nItemId = sItemId.toInt32();
152
153 if (nItemId == 0)
154 return;
155
156 FmFormModel aModel;
157 aModel.GetItemPool().FreezeIdRanges();
158
159 if( !GalleryExplorer::GetSdrObj( mnThemeId, nItemId-1, &aModel ) )
160 return;
161
162 SdrPage* pPage = aModel.GetPage(0);
163 if( !(pPage && pPage->GetObjCount()) )
164 return;
165
166 // tdf#116993 Calc uses a 'special' mode for this dialog in being the
167 // only caller of ::SetSdrObjectRef. Only in that case mpDestModel seems
168 // to be the correct target SdrModel.
169 // If this is not used, the correct SdrModel seems to be the one from
170 // the mrSdrView that is used to insert (InsertObjectAtView below) the
171 // cloned SdrObject.
172 const bool bUseSpecialCalcMode(!mbInsertIntoPage && nullptr != mpDestModel);
173
174 // center shape on current view
176
177 if (!pOutDev)
178 return;
179
180 // Clone directly to target SdrModel (may be different due to user/caller (!))
181 rtl::Reference<SdrObject> pNewObject(
182 pPage->GetObj(0)->CloneSdrObject(
183 bUseSpecialCalcMode ? *mpDestModel : mrSdrView.getSdrModelFromSdrView()));
184
185 pNewObject->MakeNameUnique();
186
187 // tdf#117629
188 // Since the 'old' ::CloneSdrObject also copies the SdrPage* the
189 // SdrObject::getUnoShape() *will* create the wrong UNO API object
190 // early. This IS one of the reasons I do change these things - this
191 // error does not happen with my next change I am working on already
192 // ARGH! For now, reset the SdrPage* to nullptr.
193 // What sense does it have to copy the SdrPage* of the original SdrObject ?!?
194 // TTTT: This also *might* be the hidden reason for the strange code at the
195 // end of SdrObject::SetPage that tries to delete the SvxShape under some
196 // circumstances...
197 // pNewObject->SetPage(nullptr);
198
199 tools::Rectangle aObjRect( pNewObject->GetLogicRect() );
200 Point aPagePos;
201 Size aFontworkSize = aObjRect.GetSize();
202
204 {
205 SfxViewShell* pViewShell = SfxViewShell::Current();
206
207 aPagePos = pViewShell->getLOKVisibleArea().Center();
208
209 aPagePos.setX(convertTwipToMm100(aPagePos.X()));
210 aPagePos.setY(convertTwipToMm100(aPagePos.Y()));
211
212 sal_Int32 nLOKViewWidth = 0.8 * convertTwipToMm100(pViewShell->getLOKVisibleArea().getOpenWidth());
213 if (aFontworkSize.getWidth() > nLOKViewWidth)
214 {
215 double fScale = static_cast<double>(aFontworkSize.getWidth()) / nLOKViewWidth;
216 aFontworkSize.setWidth(aFontworkSize.getWidth() / fScale);
217 aFontworkSize.setHeight(aFontworkSize.getHeight() / fScale);
218 }
219 }
220 else
221 {
222 Size aSize = pOutDev->GetOutputSizePixel();
223 tools::Rectangle aPixelVisRect(Point(0,0), aSize);
224 tools::Rectangle aVisArea = pOutDev->PixelToLogic(aPixelVisRect);
225
226 aPagePos = aVisArea.Center();
227 }
228
229 if (aPagePos.getX() > aFontworkSize.getWidth() / 2)
230 aPagePos.AdjustX( -(aFontworkSize.getWidth() / 2) );
231 if (aPagePos.getY() > aFontworkSize.getHeight() / 2)
232 aPagePos.AdjustY( -(aFontworkSize.getHeight() / 2) );
233
234 tools::Rectangle aNewObjectRectangle(aPagePos, aFontworkSize);
235 pNewObject->SetLogicRect(aNewObjectRectangle);
236
237 if (bUseSpecialCalcMode)
238 {
239 mxSdrObject = pNewObject;
240 }
241 else
242 {
244
245 if (nullptr != pPV)
246 {
247 mrSdrView.InsertObjectAtView( pNewObject.get(), *pPV );
248 }
249 }
250}
251
253{
254 insertSelectedFontwork();
255 m_xDialog->response(RET_OK);
256}
257
259{
260 insertSelectedFontwork();
261 m_xDialog->response(RET_OK);
262 return true;
263}
264
265namespace {
266
267class FontworkAlignmentWindow final : public WeldToolbarPopup
268{
269public:
270 FontworkAlignmentWindow(svt::PopupWindowController* pControl, weld::Widget* pParentWindow);
271 virtual void GrabFocus() override
272 {
273 mxLeft->grab_focus();
274 }
275 virtual void statusChanged( const css::frame::FeatureStateEvent& Event ) override;
276
277private:
279 std::unique_ptr<weld::RadioButton> mxLeft;
280 std::unique_ptr<weld::RadioButton> mxCenter;
281 std::unique_ptr<weld::RadioButton> mxRight;
282 std::unique_ptr<weld::RadioButton> mxStretch;
283 bool mbSettingValue;
284
285 DECL_LINK( SelectHdl, weld::Toggleable&, void );
286
287 void implSetAlignment( int nAlignmentMode, bool bEnabled );
288};
289
290}
291
292constexpr OUStringLiteral gsFontworkAlignment(u".uno:FontworkAlignment");
293
294FontworkAlignmentWindow::FontworkAlignmentWindow(svt::PopupWindowController* pControl, weld::Widget* pParent)
295 : WeldToolbarPopup(pControl->getFrameInterface(), pParent, "svx/ui/fontworkalignmentcontrol.ui", "FontworkAlignmentControl")
296 , mxControl(pControl)
297 , mxLeft(m_xBuilder->weld_radio_button("left"))
298 , mxCenter(m_xBuilder->weld_radio_button("center"))
299 , mxRight(m_xBuilder->weld_radio_button("right"))
300 , mxStretch(m_xBuilder->weld_radio_button("stretch"))
301 , mbSettingValue(false)
302{
303 mxLeft->connect_toggled(LINK(this, FontworkAlignmentWindow, SelectHdl));
304 mxCenter->connect_toggled(LINK(this, FontworkAlignmentWindow, SelectHdl));
305 mxRight->connect_toggled(LINK(this, FontworkAlignmentWindow, SelectHdl));
306 mxStretch->connect_toggled(LINK(this, FontworkAlignmentWindow, SelectHdl));
307
308 AddStatusListener( gsFontworkAlignment );
309}
310
311void FontworkAlignmentWindow::implSetAlignment( int nSurface, bool bEnabled )
312{
313 bool bSettingValue = mbSettingValue;
314 mbSettingValue = true;
315 mxLeft->set_active(nSurface == 0 && bEnabled);
316 mxLeft->set_sensitive(bEnabled);
317 mxCenter->set_active(nSurface == 1 && bEnabled);
318 mxCenter->set_sensitive(bEnabled);
319 mxRight->set_active(nSurface == 2 && bEnabled);
320 mxRight->set_sensitive(bEnabled);
321 //Refer https://bugs.documentfoundation.org/show_bug.cgi?id=145092 for why following lines are commented
322 //mxWord->set_active(nSurface == 3 && bEnabled);
323 //mxWord->set_sensitive(bEnabled);
324 mxStretch->set_active(nSurface == 4 && bEnabled);
325 mxStretch->set_sensitive(bEnabled);
326 mbSettingValue = bSettingValue;
327}
328
329void FontworkAlignmentWindow::statusChanged( const css::frame::FeatureStateEvent& Event )
330{
331 if( Event.FeatureURL.Main != gsFontworkAlignment )
332 return;
333
334 if( !Event.IsEnabled )
335 {
336 implSetAlignment( 0, false );
337 }
338 else
339 {
340 sal_Int32 nValue = 0;
341 if( Event.State >>= nValue )
342 implSetAlignment( nValue, true );
343 }
344}
345
346IMPL_LINK(FontworkAlignmentWindow, SelectHdl, weld::Toggleable&, rButton, void)
347{
348 if (mbSettingValue || !rButton.get_active())
349 return;
350
351 sal_Int32 nAlignment;
352 if (mxLeft->get_active())
353 nAlignment = 0;
354 else if (mxCenter->get_active())
355 nAlignment = 1;
356 else if (mxRight->get_active())
357 nAlignment = 2;
358 //Refer https://bugs.documentfoundation.org/show_bug.cgi?id=145092 for why following lines are commented
359 //else if (mxWord->get_active())
360 // nAlignment = 3;
361 else
362 nAlignment = 4;
363
364 Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue(
365 OUString(gsFontworkAlignment).copy(5), nAlignment) };
366
367 mxControl->dispatchCommand( gsFontworkAlignment, aArgs );
368
369 implSetAlignment( nAlignment, true );
370
371 mxControl->EndPopupMode();
372}
373
374namespace {
375
376class FontworkAlignmentControl : public svt::PopupWindowController
377{
378public:
379 explicit FontworkAlignmentControl( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
380
381 virtual std::unique_ptr<WeldToolbarPopup> weldPopupWindow() override;
382 virtual VclPtr<vcl::Window> createVclPopupWindow( vcl::Window* pParent ) override;
383
384 // XInitialization
385 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
386
387 // XServiceInfo
388 virtual OUString SAL_CALL getImplementationName() override;
389 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
390};
391
392}
393
394FontworkAlignmentControl::FontworkAlignmentControl( const Reference< XComponentContext >& rxContext )
395: svt::PopupWindowController( rxContext, Reference< css::frame::XFrame >(), ".uno:FontworkAlignment" )
396{
397}
398
399std::unique_ptr<WeldToolbarPopup> FontworkAlignmentControl::weldPopupWindow()
400{
401 return std::make_unique<FontworkAlignmentWindow>(this, m_pToolbar);
402}
403
404VclPtr<vcl::Window> FontworkAlignmentControl::createVclPopupWindow( vcl::Window* pParent )
405{
406 mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
407 std::make_unique<FontworkAlignmentWindow>(this, pParent->GetFrameWeld()));
408
409 mxInterimPopover->Show();
410
411 return mxInterimPopover;
412}
413
414// XInitialization
415void SAL_CALL FontworkAlignmentControl::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
416{
417 svt::PopupWindowController::initialize( aArguments );
418
419 if (m_pToolbar)
420 {
421 mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar));
422 m_pToolbar->set_item_popover(m_aCommandURL.toUtf8(), mxPopoverContainer->getTopLevel());
423 }
424
425 ToolBox* pToolBox = nullptr;
427 if ( getToolboxId( nId, &pToolBox ) )
428 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ToolBoxItemBits::DROPDOWNONLY );
429}
430
431// XServiceInfo
432
433
434OUString FontworkAlignmentControl::getImplementationName()
435{
436 return "com.sun.star.comp.svx.FontworkAlignmentController";
437}
438
439
440Sequence< OUString > FontworkAlignmentControl::getSupportedServiceNames()
441{
442 return { "com.sun.star.frame.ToolbarController" };
443}
444
445
446extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
448 css::uno::XComponentContext* xContext,
449 css::uno::Sequence<css::uno::Any> const &)
450{
451 return cppu::acquire(new FontworkAlignmentControl(xContext));
452}
453
454namespace {
455
456class FontworkCharacterSpacingWindow final : public WeldToolbarPopup
457{
458public:
459 FontworkCharacterSpacingWindow(svt::PopupWindowController* pControl, weld::Widget* pParentWindow);
460 virtual void GrabFocus() override;
461
462 virtual void statusChanged( const css::frame::FeatureStateEvent& Event ) override;
463private:
465 std::unique_ptr<weld::RadioButton> mxVeryTight;
466 std::unique_ptr<weld::RadioButton> mxTight;
467 std::unique_ptr<weld::RadioButton> mxNormal;
468 std::unique_ptr<weld::RadioButton> mxLoose;
469 std::unique_ptr<weld::RadioButton> mxVeryLoose;
470 std::unique_ptr<weld::RadioButton> mxCustom;
471 std::unique_ptr<weld::CheckButton> mxKernPairs;
472 sal_Int32 mnCharacterSpacing;
473 bool mbSettingValue;
474 bool mbCommandDispatched;
475
476 DECL_LINK( KernSelectHdl, weld::Toggleable&, void );
477 DECL_LINK( SelectHdl, weld::Toggleable&, void );
478 DECL_LINK( MouseReleaseHdl, const MouseEvent&, bool );
479
480 void implSetCharacterSpacing( sal_Int32 nCharacterSpacing, bool bEnabled );
481 void implSetKernCharacterPairs(bool bKernOnOff, bool bEnabled);
482 void DispatchSpacingDialog();
483};
484
485}
486
487constexpr OUStringLiteral gsFontworkCharacterSpacing(u".uno:FontworkCharacterSpacing");
488constexpr OUStringLiteral gsFontworkKernCharacterPairs(u".uno:FontworkKernCharacterPairs");
489
490FontworkCharacterSpacingWindow::FontworkCharacterSpacingWindow(svt::PopupWindowController* pControl, weld::Widget* pParent)
491 : WeldToolbarPopup(pControl->getFrameInterface(), pParent, "svx/ui/fontworkcharacterspacingcontrol.ui", "FontworkCharacterSpacingControl")
492 , mxControl(pControl)
493 , mxVeryTight(m_xBuilder->weld_radio_button("verytight"))
494 , mxTight(m_xBuilder->weld_radio_button("tight"))
495 , mxNormal(m_xBuilder->weld_radio_button("normal"))
496 , mxLoose(m_xBuilder->weld_radio_button("loose"))
497 , mxVeryLoose(m_xBuilder->weld_radio_button("veryloose"))
498 , mxCustom(m_xBuilder->weld_radio_button("custom"))
499 , mxKernPairs(m_xBuilder->weld_check_button("kernpairs"))
500 , mnCharacterSpacing(0)
501 , mbSettingValue(false)
502 , mbCommandDispatched(false)
503{
504 mxVeryTight->connect_toggled(LINK(this, FontworkCharacterSpacingWindow, SelectHdl));
505 mxTight->connect_toggled(LINK(this, FontworkCharacterSpacingWindow, SelectHdl));
506 mxNormal->connect_toggled(LINK(this, FontworkCharacterSpacingWindow, SelectHdl));
507 mxLoose->connect_toggled(LINK(this, FontworkCharacterSpacingWindow, SelectHdl));
508 mxVeryLoose->connect_toggled(LINK(this, FontworkCharacterSpacingWindow, SelectHdl));
509 mxCustom->connect_toggled(LINK(this, FontworkCharacterSpacingWindow, SelectHdl));
510 mxCustom->connect_mouse_release(LINK(this, FontworkCharacterSpacingWindow, MouseReleaseHdl));
511
512 mxKernPairs->connect_toggled(LINK(this, FontworkCharacterSpacingWindow, KernSelectHdl));
513
514 AddStatusListener( gsFontworkCharacterSpacing );
515 AddStatusListener( gsFontworkKernCharacterPairs );
516
517 // See TODO in svx/source/toolbars/fontworkbar.cxx for SID_FONTWORK_KERN_CHARACTER_PAIRS,
518 // the kernpairs setting is ignored, so hide the widget entirely
519 mxKernPairs->hide();
520}
521
522void FontworkCharacterSpacingWindow::GrabFocus()
523{
524 mxVeryTight->grab_focus();
525}
526
527void FontworkCharacterSpacingWindow::implSetCharacterSpacing( sal_Int32 nCharacterSpacing, bool bEnabled )
528{
529 bool bSettingValue = mbSettingValue;
530 mbSettingValue = true;
531
532 mxVeryTight->set_sensitive(bEnabled);
533 mxTight->set_sensitive(bEnabled);
534 mxNormal->set_sensitive(bEnabled);
535 mxLoose->set_sensitive(bEnabled);
536 mxVeryLoose->set_sensitive(bEnabled);
537 mxCustom->set_sensitive(bEnabled);
538
539 mxVeryTight->set_active(false);
540 mxTight->set_active(false);
541 mxNormal->set_active(false);
542 mxLoose->set_active(false);
543 mxVeryLoose->set_active(false);
544 mxCustom->set_active(true);
545
546 switch(nCharacterSpacing)
547 {
548 case 80:
549 mxVeryTight->set_active(true);
550 break;
551 case 90:
552 mxTight->set_active(true);
553 break;
554 case 100:
555 mxNormal->set_active(true);
556 break;
557 case 120:
558 mxLoose->set_active(true);
559 break;
560 case 150:
561 mxVeryLoose->set_active(true);
562 break;
563 }
564
565 mnCharacterSpacing = nCharacterSpacing;
566
567 mbSettingValue = bSettingValue;
568}
569
570void FontworkCharacterSpacingWindow::implSetKernCharacterPairs(bool bKernOnOff, bool bEnabled)
571{
572 mxKernPairs->set_sensitive(bEnabled);
573 mxKernPairs->set_active(bKernOnOff);
574}
575
576void FontworkCharacterSpacingWindow::statusChanged( const css::frame::FeatureStateEvent& Event )
577{
578 if( Event.FeatureURL.Main == gsFontworkCharacterSpacing )
579 {
580 if( !Event.IsEnabled )
581 {
582 implSetCharacterSpacing( 0, false );
583 }
584 else
585 {
586 sal_Int32 nValue = 0;
587 if( Event.State >>= nValue )
588 implSetCharacterSpacing( nValue, true );
589 }
590 }
591 else if( Event.FeatureURL.Main == gsFontworkKernCharacterPairs )
592 {
593 if( !Event.IsEnabled )
594 {
595 implSetKernCharacterPairs(false, false);
596 }
597 else
598 {
599 bool bValue = false;
600 if( Event.State >>= bValue )
601 implSetKernCharacterPairs(bValue, true);
602 }
603 }
604}
605
606IMPL_LINK_NOARG(FontworkCharacterSpacingWindow, KernSelectHdl, weld::Toggleable&, void)
607{
608 if (mbSettingValue)
609 return;
610
611 bool bKernOnOff = mxKernPairs->get_active();
612 Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue(
613 OUString(gsFontworkKernCharacterPairs).copy(5), bKernOnOff) };
614
615 mxControl->dispatchCommand( gsFontworkKernCharacterPairs, aArgs );
616 mbCommandDispatched = true;
617
618 implSetKernCharacterPairs(bKernOnOff, true);
619
620 mxControl->EndPopupMode();
621}
622
623void FontworkCharacterSpacingWindow::DispatchSpacingDialog()
624{
625 Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue(
626 OUString(gsFontworkCharacterSpacing).copy(5), mnCharacterSpacing) };
627
629 xControl->EndPopupMode();
630 xControl->dispatchCommand(".uno:FontworkCharacterSpacingDialog", aArgs);
631 mbCommandDispatched = true;
632}
633
634IMPL_LINK(FontworkCharacterSpacingWindow, SelectHdl, weld::Toggleable&, rButton, void)
635{
636 if (!rButton.get_active())
637 return;
638
639 if (mbSettingValue)
640 return;
641
642 // see MouseReleaseHdl for mbCommandDispatched check, there's no guarantee
643 // this toggle will happen before that mouse release though it does in
644 // practice for vcl and gtk
645 if (mbCommandDispatched)
646 return;
647
648 if (mxCustom->get_active())
649 DispatchSpacingDialog();
650 else
651 {
652 sal_Int32 nCharacterSpacing;
653 if (mxVeryTight->get_active())
654 nCharacterSpacing = 80;
655 else if (mxTight->get_active())
656 nCharacterSpacing = 90;
657 else if (mxLoose->get_active())
658 nCharacterSpacing = 120;
659 else if (mxVeryLoose->get_active())
660 nCharacterSpacing = 150;
661 else
662 nCharacterSpacing = 100;
663
664 Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue(
665 OUString(gsFontworkCharacterSpacing).copy(5), nCharacterSpacing) };
666
667 mxControl->dispatchCommand( gsFontworkCharacterSpacing, aArgs );
668 mbCommandDispatched = true;
669
670 implSetCharacterSpacing( nCharacterSpacing, true );
671 }
672
673 mxControl->EndPopupMode();
674}
675
676IMPL_LINK_NOARG(FontworkCharacterSpacingWindow, MouseReleaseHdl, const MouseEvent&, bool)
677{
678 /*
679 tdf#145296 if the "custom" radiobutton was presented preselected as
680 toggled on and the user clicked on it then there's no toggled signal sent
681 because the item was already toggled on and didn't change state.
682
683 So if that happens launch the custom spacing dialog explicitly here on
684 mouse release.
685 */
686 if (mxCustom->get_active() && !mbCommandDispatched)
687 {
688 DispatchSpacingDialog();
689 return true;
690 }
691 return false;
692}
693
694namespace {
695
696class FontworkCharacterSpacingControl : public svt::PopupWindowController
697{
698public:
699 explicit FontworkCharacterSpacingControl( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
700
701 virtual std::unique_ptr<WeldToolbarPopup> weldPopupWindow() override;
702 virtual VclPtr<vcl::Window> createVclPopupWindow( vcl::Window* pParent ) override;
703
704 // XInitialization
705 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
706
707 // XServiceInfo
708 virtual OUString SAL_CALL getImplementationName() override;
709 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
710};
711
712}
713
714FontworkCharacterSpacingControl::FontworkCharacterSpacingControl( const Reference< XComponentContext >& rxContext )
715: svt::PopupWindowController( rxContext, Reference< css::frame::XFrame >(), ".uno:FontworkCharacterSpacingFloater" )
716{
717}
718
719std::unique_ptr<WeldToolbarPopup> FontworkCharacterSpacingControl::weldPopupWindow()
720{
721 return std::make_unique<FontworkCharacterSpacingWindow>(this, m_pToolbar);
722}
723
724VclPtr<vcl::Window> FontworkCharacterSpacingControl::createVclPopupWindow( vcl::Window* pParent )
725{
726 mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
727 std::make_unique<FontworkCharacterSpacingWindow>(this, pParent->GetFrameWeld()));
728
729 mxInterimPopover->Show();
730
731 return mxInterimPopover;
732}
733
734// XInitialization
735void SAL_CALL FontworkCharacterSpacingControl::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
736{
737 svt::PopupWindowController::initialize( aArguments );
738
739 if (m_pToolbar)
740 {
741 mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar));
742 m_pToolbar->set_item_popover(m_aCommandURL.toUtf8(), mxPopoverContainer->getTopLevel());
743 }
744
745 ToolBox* pToolBox = nullptr;
747 if ( getToolboxId( nId, &pToolBox ) )
748 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ToolBoxItemBits::DROPDOWNONLY );
749}
750
751// XServiceInfo
752
753
754OUString FontworkCharacterSpacingControl::getImplementationName()
755{
756 return "com.sun.star.comp.svx.FontworkCharacterSpacingController";
757}
758
759
760Sequence< OUString > FontworkCharacterSpacingControl::getSupportedServiceNames()
761{
762 Sequence<OUString> aSNS { "com.sun.star.frame.ToolbarController" };
763 return aSNS;
764}
765
766
767extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
769 css::uno::XComponentContext* xContext,
770 css::uno::Sequence<css::uno::Any> const &)
771{
772 return cppu::acquire(new FontworkCharacterSpacingControl(xContext));
773}
774
775FontworkCharacterSpacingDialog::FontworkCharacterSpacingDialog(weld::Window* pParent, sal_Int32 nScale)
776 : GenericDialogController(pParent, "svx/ui/fontworkspacingdialog.ui", "FontworkSpacingDialog")
777 , m_xMtrScale(m_xBuilder->weld_metric_spin_button("entry", FieldUnit::PERCENT))
778{
779 m_xMtrScale->set_value(nScale, FieldUnit::PERCENT);
780}
781
783{
784}
785
787{
788 return static_cast<sal_Int32>(m_xMtrScale->get_value(FieldUnit::PERCENT));
789}
790
791}
792
793/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr auto convertTwipToMm100(N n)
Reference< XExecutableDialog > m_xDialog
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
bool IsEmpty() const
const Size & GetSizePixel() const
static bool EndLocking(std::u16string_view rThemeName)
Definition: galexpl.cxx:264
static sal_uInt32 GetSdrObjCount(std::u16string_view rThemeName)
Definition: galexpl.cxx:168
static bool GetSdrObj(std::u16string_view rThemeName, sal_uInt32 nSdrModelPos, SdrModel *pModel, BitmapEx *pThumb=nullptr)
Definition: galexpl.cxx:197
static bool BeginLocking(std::u16string_view rThemeName)
Definition: galexpl.cxx:239
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
Size GetOutputSizePixel() const
bool InsertObjectAtView(SdrObject *pObj, SdrPageView &rPV, SdrInsertFlags nOptions=SdrInsertFlags::NONE)
Definition: svdedtv.cxx:981
const SfxItemPool & GetItemPool() const
Definition: svdmodel.hxx:318
const SdrPage * GetPage(sal_uInt16 nPgNum) const
Definition: svdmodel.cxx:1790
SdrObject * GetObj(size_t nNum) const
Definition: svdpage.cxx:822
size_t GetObjCount() const
Definition: svdpage.cxx:816
virtual rtl::Reference< SdrObject > CloneSdrObject(SdrModel &rTargetModel) const
Definition: svdobj.cxx:1047
A SdrPage contains exactly one SdrObjList and a description of the physical page dimensions (size / m...
Definition: svdpage.hxx:377
OutputDevice * GetFirstOutputDevice() const
Definition: svdpntv.cxx:91
SdrModel & getSdrModelFromSdrView() const
Definition: svdpntv.hxx:258
SdrPageView * GetSdrPageView() const
Definition: svdpntv.hxx:300
void FreezeIdRanges()
static SfxViewShell * Current()
virtual tools::Rectangle getLOKVisibleArea() const
constexpr tools::Long getHeight() const
constexpr tools::Long Height() const
constexpr tools::Long getWidth() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
ToolBoxItemBits GetItemBits(ToolBoxItemId nItemId) const
void SetItemBits(ToolBoxItemId nItemId, ToolBoxItemBits nBits)
static VclPtr< reference_type > Create(Arg &&... arg)
virtual void GrabFocus()=0
virtual void statusChanged(const css::frame::FeatureStateEvent &Event)
virtual std::unique_ptr< WeldToolbarPopup > weldPopupWindow()=0
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override=0
virtual VclPtr< vcl::Window > createVclPopupWindow(vcl::Window *pParent)
virtual OUString SAL_CALL getImplementationName() override=0
std::unique_ptr< weld::IconView > maCtlFavorites
FontWorkGalleryDialog(weld::Window *pParent, SdrView &rView)
void initFavorites(sal_uInt16 nThemeId)
void SetSdrObjectRef(SdrModel *pModel)
std::unique_ptr< weld::Button > mxOKButton
void fillFavorites(sal_uInt16 nThemeId)
std::vector< VclPtr< VirtualDevice > > maFavoritesHorizontal
rtl::Reference< SdrObject > mxSdrObject
virtual ~FontWorkGalleryDialog() override
virtual ~FontworkCharacterSpacingDialog() override
std::unique_ptr< weld::MetricSpinButton > m_xMtrScale
constexpr Point Center() const
constexpr Size GetSize() const
tools::Long getOpenWidth() const
weld::Window * GetFrameWeld() const
constexpr ::Color COL_WHITE(0xFF, 0xFF, 0xFF)
DECL_LINK(CheckNameHdl, SvxNameDialog &, bool)
FieldUnit
sal_Int16 nValue
Definition: fmsrccfg.cxx:81
#define GALLERY_THEME_FONTWORK
Definition: gallery.hxx:38
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
Reference
void copy(const fs::path &src, const fs::path &dest)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_svx_FontworkAlignmentControl_get_implementation(css::uno::XComponentContext *xContext, css::uno::Sequence< css::uno::Any > const &)
IMPL_LINK(FontworkCharacterSpacingWindow, SelectHdl, weld::Toggleable &, rButton, void)
constexpr OUStringLiteral gsFontworkCharacterSpacing(u".uno:FontworkCharacterSpacing")
constexpr OUStringLiteral gsFontworkKernCharacterPairs(u".uno:FontworkKernCharacterPairs")
IMPL_LINK_NOARG(FontworkCharacterSpacingWindow, MouseReleaseHdl, const MouseEvent &, bool)
IMPL_LINK_NOARG(SuggestionDisplay, SelectSuggestionValueSetHdl, ValueSet *, void)
constexpr OUStringLiteral gsFontworkAlignment(u".uno:FontworkAlignment")
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_svx_FontworkCharacterSpacingControl_get_implementation(css::uno::XComponentContext *xContext, css::uno::Sequence< css::uno::Any > const &)
sal_Int16 nId
OUString sId
constexpr OUStringLiteral PERCENT(u"Percent")
RET_OK