LibreOffice Module svx (master)  1
fillctrl.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 #include <sfx2/dispatch.hxx>
21 #include <sfx2/objsh.hxx>
22 #include <sfx2/viewfrm.hxx>
23 #include <sfx2/viewsh.hxx>
24 #include <rtl/ustring.hxx>
25 #include <vcl/event.hxx>
26 #include <vcl/settings.hxx>
27 #include <vcl/toolbox.hxx>
28 #include <vcl/virdev.hxx>
29 #include <svx/svxids.hrc>
30 #include <tools/json_writer.hxx>
31 
32 constexpr OUStringLiteral TMP_STR_BEGIN = u"[";
33 constexpr OUStringLiteral TMP_STR_END = u"]";
34 
35 #include <svx/drawitem.hxx>
36 #include <svx/xfillit0.hxx>
37 #include <svx/xtable.hxx>
38 #include <svx/fillctrl.hxx>
39 #include <svx/itemwin.hxx>
40 #include <svx/xflclit.hxx>
41 #include <svx/xflgrit.hxx>
42 #include <svx/xflhtit.hxx>
43 #include <svx/xbtmpit.hxx>
44 #include <memory>
45 
46 using namespace ::com::sun::star;
47 using namespace ::com::sun::star::uno;
48 using namespace ::com::sun::star::util;
49 using namespace ::com::sun::star::beans;
50 using namespace ::com::sun::star::lang;
51 
52 namespace {
53 
55 {
56  NONE,
57  SOLID,
58  GRADIENT,
59  HATCH,
60  BITMAP,
61  PATTERN
62 };
63 
64 drawing::FillStyle toCssFillStyle( eFillStyle eXFS )
65 {
66  if (eXFS == PATTERN)
67  {
68  return drawing::FillStyle_BITMAP;
69  }
70 
71  return static_cast<drawing::FillStyle>(eXFS);
72 }
73 
74 }
75 
77 
79  sal_uInt16 nSlotId,
80  ToolBoxItemId nId,
81  ToolBox& rTbx )
82  : SfxToolBoxControl( nSlotId, nId, rTbx )
83  , mxFillControl(nullptr)
84  , mpLbFillType(nullptr)
85  , mpToolBoxColor(nullptr)
86  , mpLbFillAttr(nullptr)
87  , mnLastXFS(-1)
88  , mnLastPosGradient(0)
89  , mnLastPosHatch(0)
90  , mnLastPosBitmap(0)
91  , mnLastPosPattern(0)
92 {
93  addStatusListener( ".uno:FillColor");
94  addStatusListener( ".uno:FillGradient");
95  addStatusListener( ".uno:FillHatch");
96  addStatusListener( ".uno:FillBitmap");
97  addStatusListener( ".uno:ColorTableState");
98  addStatusListener( ".uno:GradientListState");
99  addStatusListener( ".uno:HatchListState");
100  addStatusListener( ".uno:BitmapListState");
101 }
102 
104 {
105 }
106 
108  sal_uInt16 nSID,
109  SfxItemState eState,
110  const SfxPoolItem* pState)
111 {
112  const bool bDisabled(SfxItemState::DISABLED == eState);
113 
114  switch(nSID)
115  {
116  case SID_ATTR_FILL_STYLE:
117  {
118  if(bDisabled)
119  {
120  mpLbFillType->set_sensitive(false);
122  mpLbFillAttr->show();
123  mpLbFillAttr->set_sensitive(false);
125  mpToolBoxColor->hide();
126  mnLastXFS = -1;
127  mpStyleItem.reset();
128  }
129 
130  if(eState >= SfxItemState::DEFAULT)
131  {
132  const XFillStyleItem* pItem = dynamic_cast< const XFillStyleItem* >(pState);
133 
134  if(pItem)
135  {
136  mpStyleItem.reset(pItem->Clone());
138  drawing::FillStyle eXFS = mpStyleItem->GetValue();
139  mnLastXFS = sal::static_int_cast< sal_Int32 >(eXFS);
141 
142  if(drawing::FillStyle_NONE == eXFS)
143  {
145  mpLbFillAttr->set_sensitive(false);
146  }
147 
148  Update();
149  break;
150  }
151  }
152 
154  mpLbFillAttr->show();
155  mpLbFillAttr->set_sensitive(false);
157  mpToolBoxColor->hide();
158  mnLastXFS = -1;
159  mpStyleItem.reset();
161  break;
162  }
163  case SID_ATTR_FILL_COLOR:
164  {
165  if(SfxItemState::DEFAULT == eState)
166  {
167  mpColorItem.reset(pState ? static_cast<XFillColorItem*>(pState->Clone()) : nullptr);
168  }
169 
170  if(mpStyleItem && drawing::FillStyle_SOLID == mpStyleItem->GetValue())
171  {
172  mpLbFillAttr->hide();
173  mpToolBoxColor->show();
175 
176  Update();
177  }
178  break;
179  }
180  case SID_ATTR_FILL_GRADIENT:
181  {
182  if(SfxItemState::DEFAULT == eState)
183  {
184  mpFillGradientItem.reset(pState ? static_cast<XFillGradientItem*>(pState->Clone()) : nullptr);
185  }
186 
187  if(mpStyleItem && drawing::FillStyle_GRADIENT == mpStyleItem->GetValue())
188  {
189  mpLbFillAttr->show();
190  mpToolBoxColor->hide();
192 
193  if(SfxItemState::DEFAULT == eState)
194  {
196  Update();
197  }
198  else if(SfxItemState::DISABLED == eState )
199  {
200  mpLbFillAttr->set_sensitive(false);
202  }
203  else
204  {
206  }
207  }
208  break;
209  }
210  case SID_ATTR_FILL_HATCH:
211  {
212  if(SfxItemState::DEFAULT == eState)
213  {
214  mpHatchItem.reset(pState ? static_cast<XFillHatchItem*>(pState->Clone()) : nullptr);
215  }
216 
217  if(mpStyleItem && drawing::FillStyle_HATCH == mpStyleItem->GetValue())
218  {
219  mpLbFillAttr->show();
220  mpToolBoxColor->hide();
222 
223  if(SfxItemState::DEFAULT == eState)
224  {
226  Update();
227  }
228  else if(SfxItemState::DISABLED == eState )
229  {
230  mpLbFillAttr->set_sensitive(false);
232  }
233  else
234  {
236  }
237  }
238  break;
239  }
240  case SID_ATTR_FILL_BITMAP:
241  {
242  if(SfxItemState::DEFAULT == eState)
243  {
244  mpBitmapItem.reset(pState ? static_cast<XFillBitmapItem*>(pState->Clone()) : nullptr);
245  }
246 
247  if(mpStyleItem && drawing::FillStyle_BITMAP == mpStyleItem->GetValue())
248  {
249  mpLbFillAttr->show();
250  mpToolBoxColor->hide();
252 
253  if(SfxItemState::DEFAULT == eState)
254  {
256  Update();
257  }
258  else if(SfxItemState::DISABLED == eState )
259  {
260  mpLbFillAttr->set_sensitive(false);
262  }
263  else
264  {
266  }
267  }
268  break;
269  }
270  case SID_GRADIENT_LIST:
271  {
272  if(SfxItemState::DEFAULT == eState)
273  {
274  if(mpStyleItem && drawing::FillStyle_GRADIENT == mpStyleItem->GetValue())
275  {
277  {
278  const OUString aString( mpFillGradientItem->GetName() );
280 
281  mpLbFillAttr->clear();
283  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
284  mpLbFillAttr->set_active_text(aString);
285  }
286  else
287  {
289  }
290  }
291  }
292  break;
293  }
294  case SID_HATCH_LIST:
295  {
296  if(SfxItemState::DEFAULT == eState)
297  {
298  if(mpStyleItem && drawing::FillStyle_HATCH == mpStyleItem->GetValue())
299  {
300  if(mpHatchItem)
301  {
302  const OUString aString( mpHatchItem->GetName() );
304 
305  mpLbFillAttr->clear();
307  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
308  mpLbFillAttr->set_active_text(aString);
309  }
310  else
311  {
313  }
314  }
315  }
316  break;
317  }
318  case SID_BITMAP_LIST:
319  {
320  if(SfxItemState::DEFAULT == eState)
321  {
322  if(mpStyleItem && drawing::FillStyle_BITMAP == mpStyleItem->GetValue())
323  {
324  if(mpBitmapItem)
325  {
326  const OUString aString( mpBitmapItem->GetName() );
328 
329  mpLbFillAttr->clear();
331  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
332  mpLbFillAttr->set_active_text(aString);
333  }
334  else
335  {
337  }
338  }
339  }
340  break;
341  }
342  }
343 }
344 
346 {
347  if(!mpStyleItem)
348  return;
349 
350  const drawing::FillStyle eXFS = mpStyleItem->GetValue();
352 
353  switch( eXFS )
354  {
355  case drawing::FillStyle_NONE:
356  {
357  mpLbFillAttr->show();
358  mpToolBoxColor->hide();
360  break;
361  }
362  case drawing::FillStyle_SOLID:
363  {
364  if(mpColorItem)
365  {
366  mpLbFillAttr->hide();
367  mpToolBoxColor->show();
369  }
370  break;
371  }
372  case drawing::FillStyle_GRADIENT:
373  {
374  mpLbFillAttr->show();
375  mpToolBoxColor->hide();
377 
378  if(pSh && pSh->GetItem(SID_GRADIENT_LIST))
379  {
381  mpLbFillAttr->clear();
382  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
383 
385  {
386  const OUString aString(mpFillGradientItem->GetName());
387 
388  mpLbFillAttr->set_active_text(aString);
389 
390  // Check if the entry is not in the list
391  if (mpLbFillAttr->get_active_text() != aString)
392  {
393  sal_Int32 nCount = mpLbFillAttr->get_count();
394  OUString aTmpStr;
395  if( nCount > 0 )
396  {
397  // Last entry gets tested against temporary entry
398  aTmpStr = mpLbFillAttr->get_text( nCount - 1 );
399  if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
400  aTmpStr.endsWith(TMP_STR_END) )
401  {
402  mpLbFillAttr->remove(nCount - 1);
403  }
404  }
405  aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
406 
407  rtl::Reference<XGradientList> xGradientList = new XGradientList( "", ""/*TODO?*/ );
408  xGradientList->Insert(std::make_unique<XGradientEntry>(mpFillGradientItem->GetGradientValue(), aTmpStr));
409  xGradientList->SetDirty( false );
410  const BitmapEx aBmp = xGradientList->GetUiBitmap( 0 );
411 
412  if (!aBmp.IsEmpty())
413  {
415  const Size aBmpSize(aBmp.GetSizePixel());
416  pVD->SetOutputSizePixel(aBmpSize, false);
417  pVD->DrawBitmapEx(Point(), aBmp);
418  mpLbFillAttr->append("", xGradientList->Get(0)->GetName(), *pVD);
420  }
421  }
422 
423  }
424  else
425  {
427  }
428  }
429  else
430  {
432  }
433  break;
434  }
435  case drawing::FillStyle_HATCH:
436  {
437  mpLbFillAttr->show();
438  mpToolBoxColor->hide();
440 
441  if(pSh && pSh->GetItem(SID_HATCH_LIST))
442  {
444  mpLbFillAttr->clear();
445  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
446 
447  if(mpHatchItem)
448  {
449  const OUString aString(mpHatchItem->GetName());
450 
451  mpLbFillAttr->set_active_text( aString );
452 
453  // Check if the entry is not in the list
454  if( mpLbFillAttr->get_active_text() != aString )
455  {
456  const sal_Int32 nCount = mpLbFillAttr->get_count();
457  OUString aTmpStr;
458  if( nCount > 0 )
459  {
460  // Last entry gets tested against temporary entry
461  aTmpStr = mpLbFillAttr->get_text( nCount - 1 );
462  if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
463  aTmpStr.endsWith(TMP_STR_END) )
464  {
465  mpLbFillAttr->remove( nCount - 1 );
466  }
467  }
468  aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
469 
470  rtl::Reference<XHatchList> xHatchList = new XHatchList( "", ""/*TODO?*/ );
471  xHatchList->Insert(std::make_unique<XHatchEntry>(mpHatchItem->GetHatchValue(), aTmpStr));
472  xHatchList->SetDirty( false );
473  const BitmapEx & aBmp = xHatchList->GetUiBitmap( 0 );
474 
475  if( !aBmp.IsEmpty() )
476  {
478  const Size aBmpSize(aBmp.GetSizePixel());
479  pVD->SetOutputSizePixel(aBmpSize, false);
480  pVD->DrawBitmapEx(Point(), aBmp);
481  mpLbFillAttr->append("", xHatchList->GetHatch(0)->GetName(), *pVD);
483  }
484  }
485  }
486  else
487  {
489  }
490  }
491  else
492  {
494  }
495  break;
496  }
497  case drawing::FillStyle_BITMAP:
498  {
499  mpLbFillAttr->show();
500  mpToolBoxColor->hide();
502 
503  if(pSh)
504  {
506  mpLbFillAttr->clear();
507 
508  if(mpBitmapItem && !mpBitmapItem->isPattern() && pSh->GetItem(SID_BITMAP_LIST))
509  {
510  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
511 
512  const OUString aString(mpBitmapItem->GetName());
513 
514  mpLbFillAttr->set_active_text(aString);
515 
516  // Check if the entry is not in the list
517  if (mpLbFillAttr->get_active_text() != aString)
518  {
519  sal_Int32 nCount = mpLbFillAttr->get_count();
520  OUString aTmpStr;
521  if( nCount > 0 )
522  {
523  // Last entry gets tested against temporary entry
524  aTmpStr = mpLbFillAttr->get_text(nCount - 1);
525  if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
526  aTmpStr.endsWith(TMP_STR_END) )
527  {
528  mpLbFillAttr->remove(nCount - 1);
529  }
530  }
531  aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
532 
533  XBitmapListRef xBitmapList =
536  XPropertyListType::Bitmap, "TmpList", ""/*TODO?*/));
537  xBitmapList->Insert(std::make_unique<XBitmapEntry>(mpBitmapItem->GetGraphicObject(), aTmpStr));
538  xBitmapList->SetDirty( false );
539  SvxFillAttrBox::Fill(*mpLbFillAttr, xBitmapList);
541  }
542 
543  }
544  else if (mpBitmapItem && mpBitmapItem->isPattern() && pSh->GetItem(SID_PATTERN_LIST))
545  {
546  mnLastXFS = sal::static_int_cast<sal_Int32>(PATTERN);
548 
549  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_PATTERN_LIST)->GetPatternList());
550  const OUString aString(mpBitmapItem->GetName());
551 
552  mpLbFillAttr->set_active_text(aString);
553  }
554  else
555  {
557  }
558  }
559  else
560  {
562  }
563  break;
564  }
565  default:
566  OSL_ENSURE(false, "Non supported FillType (!)");
567  break;
568  }
569 
570 }
571 
573 {
574  if(GetSlotId() == SID_ATTR_FILL_STYLE)
575  {
577 
581 
582  mpLbFillType->connect_changed(LINK(this,SvxFillToolBoxControl,SelectFillTypeHdl));
583  mpLbFillAttr->connect_changed(LINK(this,SvxFillToolBoxControl,SelectFillAttrHdl));
584 
585 
586  return mxFillControl;
587  }
588  return VclPtr<InterimItemWindow>();
589 }
590 
591 FillControl::FillControl(vcl::Window* pParent, const css::uno::Reference<css::frame::XFrame>& rFrame)
592  : InterimItemWindow(pParent, "svx/ui/fillctrlbox.ui", "FillCtrlBox")
593  , mxLbFillType(m_xBuilder->weld_combo_box("type"))
594  , mxToolBoxColor(m_xBuilder->weld_toolbar("color"))
595  , mxColorDispatch(new ToolbarUnoDispatcher(*mxToolBoxColor, *m_xBuilder, rFrame))
596  , mxLbFillAttr(m_xBuilder->weld_combo_box("attr"))
597  , mnTypeCurPos(0)
598  , mnAttrCurPos(0)
599 {
601 
602  mxLbFillAttr->connect_key_press(LINK(this, FillControl, AttrKeyInputHdl));
603  mxLbFillType->connect_key_press(LINK(this, FillControl, TypeKeyInputHdl));
604  mxToolBoxColor->connect_key_press(LINK(this, FillControl, ColorKeyInputHdl));
605 
606  mxLbFillType->connect_get_property_tree(LINK(this, FillControl, DumpAsPropertyTreeHdl));
607 
608  mxLbFillType->connect_focus_in(LINK(this, FillControl, TypeFocusHdl));
609  mxLbFillAttr->connect_focus_in(LINK(this, FillControl, AttrFocusHdl));
610 
612 
613  SetOptimalSize();
614 }
615 
616 IMPL_STATIC_LINK(FillControl, DumpAsPropertyTreeHdl, tools::JsonWriter&, rJsonWriter, void)
617 {
618  rJsonWriter.put("command", ".uno:FillStyle");
619 }
620 
622 {
624  if (pCurSh)
625  {
626  vcl::Window* pShellWnd = pCurSh->GetWindow();
627  if (pShellWnd)
628  pShellWnd->GrabFocus();
629  }
630 }
631 
632 IMPL_LINK(FillControl, TypeKeyInputHdl, const KeyEvent&, rKEvt, bool)
633 {
634  const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
635  sal_uInt16 nCode = rKeyCode.GetCode();
636 
637  if (nCode == KEY_ESCAPE)
638  {
639  mxLbFillType->set_active(mnTypeCurPos);
640  ReleaseFocus_Impl();
641  return true;
642  }
643 
644  if (nCode != KEY_TAB)
645  return false;
646  if (rKeyCode.IsShift())
647  return ChildKeyInput(rKEvt);
648  if (mxLbFillAttr->get_visible() && !mxLbFillAttr->get_sensitive())
649  return ChildKeyInput(rKEvt);
650  return false;
651 }
652 
654 {
655  mnTypeCurPos = mxLbFillType->get_active();
656 }
657 
659 {
660  mnAttrCurPos = mxLbFillAttr->get_active();
661 }
662 
663 IMPL_LINK(FillControl, AttrKeyInputHdl, const KeyEvent&, rKEvt, bool)
664 {
665  const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
666  sal_uInt16 nCode = rKeyCode.GetCode();
667 
668  if (nCode == KEY_ESCAPE)
669  {
670  mxLbFillAttr->set_active(mnAttrCurPos);
671  ReleaseFocus_Impl();
672  return true;
673  }
674 
675  return ChildKeyInput(rKEvt);
676 }
677 
678 IMPL_LINK(FillControl, ColorKeyInputHdl, const KeyEvent&, rKEvt, bool)
679 {
680  return ChildKeyInput(rKEvt);
681 }
682 
684 {
685  disposeOnce();
686 }
687 
689 {
690  mxLbFillAttr.reset();
691  mxColorDispatch.reset();
692  mxToolBoxColor.reset();
693  mxLbFillType.reset();
695 }
696 
698 {
699  sal_Int32 nXFS = mpLbFillType->get_active();
700 
701  if(mnLastXFS == nXFS)
702  return;
703 
704  eFillStyle eXFS = static_cast<eFillStyle>(nXFS);
705  mpLbFillAttr->clear();
707  const XFillStyleItem aXFillStyleItem(toCssFillStyle(eXFS));
708 
709  // #i122676# Do no longer trigger two Execute calls, one for SID_ATTR_FILL_STYLE
710  // and one for setting the fill attribute itself, but add two SfxPoolItems to the
711  // call to get just one action at the SdrObject and to create only one Undo action, too.
712  // Checked that this works in all apps.
713  switch( eXFS )
714  {
715  default:
716  case NONE:
717  {
718  mpLbFillAttr->show();
719  mpToolBoxColor->hide();
720  mpLbFillAttr->set_sensitive(false);
721  if (pSh)
722  {
723  // #i122676# need to call a single SID_ATTR_FILL_STYLE change
724  pSh->GetDispatcher()->ExecuteList(
725  SID_ATTR_FILL_STYLE, SfxCallMode::RECORD,
726  { &aXFillStyleItem });
727  }
728  break;
729  }
730  case SOLID:
731  {
732  mpLbFillAttr->hide();
733  mpToolBoxColor->show();
734  if (pSh)
735  {
736  const ::Color aColor = mpColorItem ? mpColorItem->GetColorValue() : COL_AUTO;
737  const XFillColorItem aXFillColorItem( "", aColor );
738 
739  // #i122676# change FillStyle and Color in one call
740  pSh->GetDispatcher()->ExecuteList(
741  SID_ATTR_FILL_COLOR, SfxCallMode::RECORD,
742  { &aXFillColorItem, &aXFillStyleItem });
743  }
744  break;
745  }
746  case GRADIENT:
747  {
748  mpLbFillAttr->show();
749  mpToolBoxColor->hide();
750 
751  if(pSh && pSh->GetItem(SID_GRADIENT_LIST))
752  {
753  if(!mpLbFillAttr->get_count())
754  {
755  mpLbFillAttr->set_sensitive(true);
756  mpLbFillAttr->clear();
757  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
758  }
759 
760  if (mnLastPosGradient != -1)
761  {
762  const SvxGradientListItem * pItem = pSh->GetItem(SID_GRADIENT_LIST);
763 
764  if(mnLastPosGradient < pItem->GetGradientList()->Count())
765  {
766  const XGradient aGradient = pItem->GetGradientList()->GetGradient(mnLastPosGradient)->GetGradient();
767  const XFillGradientItem aXFillGradientItem(mpLbFillAttr->get_text(mnLastPosGradient), aGradient);
768 
769  // #i122676# change FillStyle and Gradient in one call
770  pSh->GetDispatcher()->ExecuteList(
771  SID_ATTR_FILL_GRADIENT, SfxCallMode::RECORD,
772  { &aXFillGradientItem, &aXFillStyleItem });
773  mpLbFillAttr->set_active(mnLastPosGradient);
774  }
775  }
776  }
777  else
778  {
779  mpLbFillAttr->set_sensitive(false);
780  }
781  break;
782  }
783  case HATCH:
784  {
785  mpLbFillAttr->show();
786  mpToolBoxColor->hide();
787 
788  if(pSh && pSh->GetItem(SID_HATCH_LIST))
789  {
790  if(!mpLbFillAttr->get_count())
791  {
792  mpLbFillAttr->set_sensitive(true);
793  mpLbFillAttr->clear();
794  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
795  }
796 
797  if (mnLastPosHatch != -1)
798  {
799  const SvxHatchListItem * pItem = pSh->GetItem(SID_HATCH_LIST);
800 
801  if(mnLastPosHatch < pItem->GetHatchList()->Count())
802  {
803  const XHatch aHatch = pItem->GetHatchList()->GetHatch(mnLastPosHatch)->GetHatch();
804  const XFillHatchItem aXFillHatchItem(mpLbFillAttr->get_active_text(), aHatch);
805 
806  // #i122676# change FillStyle and Hatch in one call
807  pSh->GetDispatcher()->ExecuteList(
808  SID_ATTR_FILL_HATCH, SfxCallMode::RECORD,
809  { &aXFillHatchItem, &aXFillStyleItem });
810  mpLbFillAttr->set_active(mnLastPosHatch);
811  }
812  }
813  }
814  else
815  {
816  mpLbFillAttr->set_sensitive(false);
817  }
818  break;
819  }
820  case BITMAP:
821  {
822  mpLbFillAttr->show();
823  mpToolBoxColor->hide();
824 
825  if(pSh && pSh->GetItem(SID_BITMAP_LIST))
826  {
827  if(!mpLbFillAttr->get_count())
828  {
829  mpLbFillAttr->set_sensitive(true);
830  mpLbFillAttr->clear();
831  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
832  }
833 
834  if (mnLastPosBitmap != -1)
835  {
836  const SvxBitmapListItem * pItem = pSh->GetItem(SID_BITMAP_LIST);
837 
838  if(mnLastPosBitmap < pItem->GetBitmapList()->Count())
839  {
840  const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(mnLastPosBitmap);
841  const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
842 
843  // #i122676# change FillStyle and Bitmap in one call
844  pSh->GetDispatcher()->ExecuteList(
845  SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
846  { &aXFillBitmapItem, &aXFillStyleItem });
847  mpLbFillAttr->set_active(mnLastPosBitmap);
848  }
849  }
850  }
851  else
852  {
853  mpLbFillAttr->set_sensitive(false);
854  }
855  break;
856  }
857  case PATTERN:
858  {
859  mpLbFillAttr->show();
860  mpToolBoxColor->hide();
861 
862  if(pSh && pSh->GetItem(SID_PATTERN_LIST))
863  {
864  if(!mpLbFillAttr->get_count())
865  {
866  mpLbFillAttr->set_sensitive(true);
867  mpLbFillAttr->clear();
868  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_PATTERN_LIST)->GetPatternList());
869  }
870 
871  if (mnLastPosPattern != -1)
872  {
873  const SvxPatternListItem * pItem = pSh->GetItem(SID_PATTERN_LIST);
874 
875  if(mnLastPosPattern < pItem->GetPatternList()->Count())
876  {
877  const XBitmapEntry* pXBitmapEntry = pItem->GetPatternList()->GetBitmap(mnLastPosPattern);
878  const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
879 
880  // #i122676# change FillStyle and Bitmap in one call
881  pSh->GetDispatcher()->ExecuteList(
882  SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
883  { &aXFillBitmapItem, &aXFillStyleItem });
884  mpLbFillAttr->set_active(mnLastPosPattern);
885  }
886  }
887  }
888  else
889  {
890  mpLbFillAttr->set_sensitive(false);
891  }
892  break;
893  }
894 
895  }
896 
897  mnLastXFS = nXFS;
898 
899  mxFillControl->Resize();
900 }
901 
903 {
904  sal_Int32 nXFS = mpLbFillType->get_active();
905  eFillStyle eXFS = static_cast<eFillStyle>(nXFS);
906 
907  const XFillStyleItem aXFillStyleItem(toCssFillStyle(eXFS));
909 
910  // #i122676# dependent from bFillStyleChange, do execute a single or two
911  // changes in one Execute call
912  const bool bFillStyleChange(mnLastXFS != nXFS);
913 
914  switch (eXFS)
915  {
916  case SOLID:
917  {
918  if (bFillStyleChange && pSh)
919  {
920  // #i122676# Single FillStyle change call needed here
921  pSh->GetDispatcher()->ExecuteList(
922  SID_ATTR_FILL_STYLE, SfxCallMode::RECORD,
923  { &aXFillStyleItem });
924  }
925  break;
926  }
927  case GRADIENT:
928  {
929  sal_Int32 nPos = mpLbFillAttr->get_active();
930 
931  if (nPos == -1)
932  {
933  nPos = mnLastPosGradient;
934  }
935 
936  if (nPos != -1 && pSh && pSh->GetItem(SID_GRADIENT_LIST))
937  {
938  const SvxGradientListItem * pItem = pSh->GetItem(SID_GRADIENT_LIST);
939 
940  if(nPos < pItem->GetGradientList()->Count())
941  {
942  const XGradient aGradient = pItem->GetGradientList()->GetGradient(nPos)->GetGradient();
943  const XFillGradientItem aXFillGradientItem(mpLbFillAttr->get_active_text(), aGradient);
944 
945  // #i122676# Change FillStyle and Gradient in one call
946  pSh->GetDispatcher()->ExecuteList(
947  SID_ATTR_FILL_GRADIENT, SfxCallMode::RECORD,
948  bFillStyleChange
949  ? std::initializer_list<SfxPoolItem const*>{ &aXFillGradientItem, &aXFillStyleItem }
950  : std::initializer_list<SfxPoolItem const*>{ &aXFillGradientItem });
951  }
952  }
953 
954  if (nPos != -1)
955  {
956  mnLastPosGradient = nPos;
957  }
958  break;
959  }
960  case HATCH:
961  {
962  sal_Int32 nPos = mpLbFillAttr->get_active();
963 
964  if (nPos == -1)
965  {
966  nPos = mnLastPosHatch;
967  }
968 
969  if (nPos != -1 && pSh && pSh->GetItem(SID_HATCH_LIST))
970  {
971  const SvxHatchListItem * pItem = pSh->GetItem(SID_HATCH_LIST);
972 
973  if(nPos < pItem->GetHatchList()->Count())
974  {
975  const XHatch aHatch = pItem->GetHatchList()->GetHatch(nPos)->GetHatch();
976  const XFillHatchItem aXFillHatchItem( mpLbFillAttr->get_active_text(), aHatch);
977 
978  // #i122676# Change FillStyle and Hatch in one call
979  pSh->GetDispatcher()->ExecuteList(
980  SID_ATTR_FILL_HATCH, SfxCallMode::RECORD,
981  bFillStyleChange
982  ? std::initializer_list<SfxPoolItem const*>{ &aXFillHatchItem, &aXFillStyleItem }
983  : std::initializer_list<SfxPoolItem const*>{ &aXFillHatchItem });
984  }
985  }
986 
987  if (nPos != -1)
988  {
989  mnLastPosHatch = nPos;
990  }
991  break;
992  }
993  case BITMAP:
994  {
995  sal_Int32 nPos = mpLbFillAttr->get_active();
996 
997  if (nPos == -1)
998  {
999  nPos = mnLastPosBitmap;
1000  }
1001 
1002  if (nPos != -1 && pSh && pSh->GetItem(SID_BITMAP_LIST))
1003  {
1004  const SvxBitmapListItem * pItem = pSh->GetItem(SID_BITMAP_LIST);
1005 
1006  if(nPos < pItem->GetBitmapList()->Count())
1007  {
1008  const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(nPos);
1009  const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
1010 
1011  // #i122676# Change FillStyle and Bitmap in one call
1012  pSh->GetDispatcher()->ExecuteList(
1013  SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
1014  bFillStyleChange
1015  ? std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem, &aXFillStyleItem }
1016  : std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem });
1017  }
1018  }
1019 
1020  if (nPos != -1)
1021  {
1022  mnLastPosBitmap = nPos;
1023  }
1024  break;
1025  }
1026  case PATTERN:
1027  {
1028  sal_Int32 nPos = mpLbFillAttr->get_active();
1029 
1030  if (nPos == -1)
1031  {
1032  nPos = mnLastPosPattern;
1033  }
1034 
1035  if (nPos != -1 && pSh && pSh->GetItem(SID_PATTERN_LIST))
1036  {
1037  const SvxPatternListItem * pItem = pSh->GetItem(SID_PATTERN_LIST);
1038 
1039  if(nPos < pItem->GetPatternList()->Count())
1040  {
1041  const XBitmapEntry* pXBitmapEntry = pItem->GetPatternList()->GetBitmap(nPos);
1042  const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
1043 
1044  // #i122676# Change FillStyle and Bitmap in one call
1045  pSh->GetDispatcher()->ExecuteList(
1046  SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
1047  bFillStyleChange
1048  ? std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem, &aXFillStyleItem }
1049  : std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem });
1050  }
1051  }
1052 
1053  if (nPos != -1)
1054  {
1055  mnLastPosPattern = nPos;
1056  }
1057  break;
1058  }
1059 
1060  default: break;
1061  }
1062 }
1063 
1065 {
1066  Size aSize(mxLbFillType->get_preferred_size());
1067  Size aFirstSize(mxToolBoxColor->get_preferred_size());
1068  auto nWidth = std::max(aFirstSize.Width(), LogicToPixel(Size(55, 0), MapMode(MapUnit::MapAppFont)).Width());
1069  auto nHeight = std::max(aSize.Height(), aFirstSize.Height());
1070  mxToolBoxColor->set_size_request(nWidth, -1);
1071  mxLbFillAttr->set_size_request(42, -1); //something narrow so the toolbar sets the overall size of this column
1072  SetSizePixel(Size(m_xContainer->get_preferred_size().Width(), nHeight));
1073 }
1074 
1076 {
1077  if((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1078  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
1079  {
1080  SetOptimalSize();
1081  }
1083 }
1084 
1085 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual ~FillControl() override
Definition: fillctrl.cxx:683
virtual void dispose() override
Definition: fillctrl.cxx:688
const SfxPoolItem * ExecuteList(sal_uInt16 nSlot, SfxCallMode nCall, std::initializer_list< SfxPoolItem const * > args, std::initializer_list< SfxPoolItem const * > internalargs=std::initializer_list< SfxPoolItem const * >())
const XPatternListRef & GetPatternList() const
Definition: drawitem.hxx:146
std::unique_ptr< XFillBitmapItem > mpBitmapItem
Definition: fillctrl.hxx:50
enum SAL_DLLPUBLIC_RTTI FillStyle
virtual void hide()=0
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const =0
SVX_DLLPUBLIC void Fill(weld::ComboBox &, const XHatchListRef &pList)
Definition: itemwin.cxx:244
virtual OUString get_text(int pos) const =0
static XBitmapListRef AsBitmapList(rtl::Reference< XPropertyList > const &plist)
Definition: xtable.hxx:379
constexpr::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
std::unique_ptr< XFillColorItem > mpColorItem
Definition: fillctrl.hxx:47
css::uno::Reference< css::lang::XComponent > m_xFrame
virtual void SetSizePixel(const Size &rNewSize)
std::unique_ptr< XFillGradientItem > mpFillGradientItem
Definition: fillctrl.hxx:48
const XGradientListRef & GetGradientList() const
Definition: drawitem.hxx:73
sal_uInt16 GetCode() const
DataChangedEventType GetType() const
IMPL_LINK_NOARG(FillControl, TypeFocusHdl, weld::Widget &, void)
Definition: fillctrl.cxx:653
static SfxObjectShell * Current()
void append(const OUString &rId, const OUString &rStr)
virtual int get_count() const =0
constexpr OUStringLiteral TMP_STR_BEGIN
Definition: fillctrl.cxx:32
NONE
virtual void show()=0
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: fillctrl.cxx:1075
FillControl(vcl::Window *pParent, const css::uno::Reference< css::frame::XFrame > &rFrame)
Definition: fillctrl.cxx:591
int nCount
constexpr OUStringLiteral TMP_STR_END
Definition: fillctrl.cxx:33
AllSettingsFlags GetFlags() const
static SfxViewShell * Current()
IMPL_LINK(FillControl, TypeKeyInputHdl, const KeyEvent &, rKEvt, bool)
Definition: fillctrl.cxx:632
virtual void Resize() override
virtual void StateChangedAtToolBoxControl(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem *pState) override
Definition: fillctrl.cxx:107
sal_uInt16 nCode
const GraphicObject & GetGraphicObject() const
Definition: xtable.hxx:125
const XHatchListRef & GetHatchList() const
Definition: drawitem.hxx:97
const SfxPoolItem * GetItem(sal_uInt16 nSlotId) const
bool IsEmpty() const
std::unique_ptr< weld::ComboBox > mxLbFillAttr
Definition: fillctrl.hxx:85
virtual ~SvxFillToolBoxControl() override
Definition: fillctrl.cxx:103
void set_active_text(const OUString &rStr)
SVX_DLLPUBLIC void Fill(weld::ComboBox &rListBox)
Definition: itemwin.cxx:174
Point LogicToPixel(const Point &rLogicPt) const
SfxDispatcher * GetDispatcher() const
static void ReleaseFocus_Impl()
Definition: fillctrl.cxx:621
constexpr OUStringLiteral PATTERN
void SetOptimalSize()
Definition: fillctrl.cxx:1064
void connect_changed(const Link< ComboBox &, void > &rLink)
Count
SvxFillToolBoxControl(sal_uInt16 nSlotId, ToolBoxItemId nId, ToolBox &rTbx)
Definition: fillctrl.cxx:78
float u
static XPropertyListRef CreatePropertyList(XPropertyListType t, const OUString &rPath, const OUString &rReferer)
Definition: xtable.cxx:315
std::unique_ptr< XFillHatchItem > mpHatchItem
Definition: fillctrl.hxx:49
virtual void set_active(int pos)=0
VclPtr< FillControl > mxFillControl
Definition: fillctrl.hxx:52
virtual void clear()=0
weld::ComboBox * mpLbFillType
Definition: fillctrl.hxx:53
void GrabFocus()
const XBitmapListRef & GetBitmapList() const
Definition: drawitem.hxx:122
SFX_IMPL_TOOLBOX_CONTROL(SvxFillToolBoxControl, XFillStyleItem)
void reset(reference_type *pBody)
bool IsShift() const
virtual VclPtr< InterimItemWindow > CreateItemWindow(vcl::Window *pParent) override
Definition: fillctrl.cxx:572
SfxItemState
std::unique_ptr< weld::Container > m_xContainer
weld::ComboBox * mpLbFillAttr
Definition: fillctrl.hxx:55
constexpr sal_uInt16 KEY_ESCAPE
virtual void dispose() override
eFillStyle
Definition: fillctrl.cxx:54
unsigned short GetSlotId() const
vcl::Window * GetWindow() const
std::unique_ptr< XFillStyleItem > mpStyleItem
Definition: fillctrl.hxx:46
std::unique_ptr< ToolbarUnoDispatcher > mxColorDispatch
Definition: fillctrl.hxx:84
weld::Toolbar * mpToolBoxColor
Definition: fillctrl.hxx:54
virtual void remove(int pos)=0
IMPL_STATIC_LINK(FillControl, DumpAsPropertyTreeHdl, tools::JsonWriter &, rJsonWriter, void)
Definition: fillctrl.cxx:616
std::unique_ptr< weld::Toolbar > mxToolBoxColor
Definition: fillctrl.hxx:83
const Size & GetSizePixel() const
std::unique_ptr< weld::ComboBox > mxLbFillType
Definition: fillctrl.hxx:82
void InitControlBase(weld::Widget *pWidget)
virtual XFillStyleItem * Clone(SfxItemPool *pPool=nullptr) const override
Definition: xattr.cxx:1744
sal_uInt16 nPos
virtual void set_sensitive(bool sensitive)=0
constexpr sal_uInt16 KEY_TAB
virtual void DataChanged(const DataChangedEvent &rDCEvt)
virtual OUString get_active_text() const =0