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