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 <svx/svxids.hrc>
29 #include <tools/json_writer.hxx>
30 
31 #define TMP_STR_BEGIN "["
32 #define TMP_STR_END "]"
33 
34 #include <svx/drawitem.hxx>
35 #include <svx/xfillit0.hxx>
36 #include <svx/xtable.hxx>
37 #include <svx/fillctrl.hxx>
38 #include <svx/itemwin.hxx>
39 #include <svx/xflclit.hxx>
40 #include <svx/xflgrit.hxx>
41 #include <svx/xflhtit.hxx>
42 #include <svx/xbtmpit.hxx>
43 #include <boost/property_tree/ptree.hpp>
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 
53 
55  sal_uInt16 nSlotId,
56  sal_uInt16 nId,
57  ToolBox& rTbx )
58  : SfxToolBoxControl( nSlotId, nId, rTbx )
59  , mpStyleItem()
60  , mpColorItem()
61  , mpFillGradientItem()
62  , mpHatchItem()
63  , mpBitmapItem()
64  , mxFillControl(nullptr)
65  , mpLbFillType(nullptr)
66  , mpToolBoxColor(nullptr)
67  , mpLbFillAttr(nullptr)
68  , meLastXFS(static_cast<drawing::FillStyle>(-1))
69  , mnLastPosGradient(0)
70  , mnLastPosHatch(0)
71  , mnLastPosBitmap(0)
72 {
73  addStatusListener( ".uno:FillColor");
74  addStatusListener( ".uno:FillGradient");
75  addStatusListener( ".uno:FillHatch");
76  addStatusListener( ".uno:FillBitmap");
77  addStatusListener( ".uno:ColorTableState");
78  addStatusListener( ".uno:GradientListState");
79  addStatusListener( ".uno:HatchListState");
80  addStatusListener( ".uno:BitmapListState");
81 }
82 
84 {
85 }
86 
88  sal_uInt16 nSID,
89  SfxItemState eState,
90  const SfxPoolItem* pState)
91 {
92  const bool bDisabled(SfxItemState::DISABLED == eState);
93 
94  switch(nSID)
95  {
96  case SID_ATTR_FILL_STYLE:
97  {
98  if(bDisabled)
99  {
100  mpLbFillType->set_sensitive(false);
102  mpLbFillAttr->show();
103  mpLbFillAttr->set_sensitive(false);
105  mpToolBoxColor->hide();
106  meLastXFS = static_cast<drawing::FillStyle>(-1);
107  mpStyleItem.reset();
108  }
109 
110  if(eState >= SfxItemState::DEFAULT)
111  {
112  const XFillStyleItem* pItem = dynamic_cast< const XFillStyleItem* >(pState);
113 
114  if(pItem)
115  {
116  mpStyleItem.reset(pItem->Clone());
118  drawing::FillStyle eXFS = mpStyleItem->GetValue();
119  meLastXFS = eXFS;
120  mpLbFillType->set_active(sal::static_int_cast< sal_Int32 >(eXFS));
121 
122  if(drawing::FillStyle_NONE == eXFS)
123  {
125  mpLbFillAttr->set_sensitive(false);
126  }
127 
128  Update();
129  break;
130  }
131  }
132 
134  mpLbFillAttr->show();
135  mpLbFillAttr->set_sensitive(false);
137  mpToolBoxColor->hide();
138  meLastXFS = static_cast<drawing::FillStyle>(-1);
139  mpStyleItem.reset();
141  break;
142  }
143  case SID_ATTR_FILL_COLOR:
144  {
145  if(SfxItemState::DEFAULT == eState)
146  {
147  mpColorItem.reset(pState ? static_cast<XFillColorItem*>(pState->Clone()) : nullptr);
148  }
149 
150  if(mpStyleItem && drawing::FillStyle_SOLID == mpStyleItem->GetValue())
151  {
152  mpLbFillAttr->hide();
153  mpToolBoxColor->show();
155 
156  Update();
157  }
158  break;
159  }
160  case SID_ATTR_FILL_GRADIENT:
161  {
162  if(SfxItemState::DEFAULT == eState)
163  {
164  mpFillGradientItem.reset(pState ? static_cast<XFillGradientItem*>(pState->Clone()) : nullptr);
165  }
166 
167  if(mpStyleItem && drawing::FillStyle_GRADIENT == mpStyleItem->GetValue())
168  {
169  mpLbFillAttr->show();
170  mpToolBoxColor->hide();
172 
173  if(SfxItemState::DEFAULT == eState)
174  {
176  Update();
177  }
178  else if(SfxItemState::DISABLED == eState )
179  {
180  mpLbFillAttr->set_sensitive(false);
182  }
183  else
184  {
186  }
187  }
188  break;
189  }
190  case SID_ATTR_FILL_HATCH:
191  {
192  if(SfxItemState::DEFAULT == eState)
193  {
194  mpHatchItem.reset(pState ? static_cast<XFillHatchItem*>(pState->Clone()) : nullptr);
195  }
196 
197  if(mpStyleItem && drawing::FillStyle_HATCH == mpStyleItem->GetValue())
198  {
199  mpLbFillAttr->show();
200  mpToolBoxColor->hide();
202 
203  if(SfxItemState::DEFAULT == eState)
204  {
206  Update();
207  }
208  else if(SfxItemState::DISABLED == eState )
209  {
210  mpLbFillAttr->set_sensitive(false);
212  }
213  else
214  {
216  }
217  }
218  break;
219  }
220  case SID_ATTR_FILL_BITMAP:
221  {
222  if(SfxItemState::DEFAULT == eState)
223  {
224  mpBitmapItem.reset(pState ? static_cast<XFillBitmapItem*>(pState->Clone()) : nullptr);
225  }
226 
227  if(mpStyleItem && drawing::FillStyle_BITMAP == mpStyleItem->GetValue())
228  {
229  mpLbFillAttr->show();
230  mpToolBoxColor->hide();
232 
233  if(SfxItemState::DEFAULT == eState)
234  {
236  Update();
237  }
238  else if(SfxItemState::DISABLED == eState )
239  {
240  mpLbFillAttr->set_sensitive(false);
242  }
243  else
244  {
246  }
247  }
248  break;
249  }
250  case SID_GRADIENT_LIST:
251  {
252  if(SfxItemState::DEFAULT == eState)
253  {
254  if(mpStyleItem && drawing::FillStyle_GRADIENT == mpStyleItem->GetValue())
255  {
257  {
258  const OUString aString( mpFillGradientItem->GetName() );
260 
261  mpLbFillAttr->clear();
263  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
264  mpLbFillAttr->set_active_text(aString);
265  }
266  else
267  {
269  }
270  }
271  }
272  break;
273  }
274  case SID_HATCH_LIST:
275  {
276  if(SfxItemState::DEFAULT == eState)
277  {
278  if(mpStyleItem && drawing::FillStyle_HATCH == mpStyleItem->GetValue())
279  {
280  if(mpHatchItem)
281  {
282  const OUString aString( mpHatchItem->GetName() );
284 
285  mpLbFillAttr->clear();
287  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
288  mpLbFillAttr->set_active_text(aString);
289  }
290  else
291  {
293  }
294  }
295  }
296  break;
297  }
298  case SID_BITMAP_LIST:
299  {
300  if(SfxItemState::DEFAULT == eState)
301  {
302  if(mpStyleItem && drawing::FillStyle_BITMAP == mpStyleItem->GetValue())
303  {
304  if(mpBitmapItem)
305  {
306  const OUString aString( mpBitmapItem->GetName() );
308 
309  mpLbFillAttr->clear();
311  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
312  mpLbFillAttr->set_active_text(aString);
313  }
314  else
315  {
317  }
318  }
319  }
320  break;
321  }
322  }
323 }
324 
326 {
327  if(mpStyleItem)
328  {
329  const drawing::FillStyle eXFS = mpStyleItem->GetValue();
331 
332  switch( eXFS )
333  {
334  case drawing::FillStyle_NONE:
335  {
336  mpLbFillAttr->show();
337  mpToolBoxColor->hide();
339  break;
340  }
341  case drawing::FillStyle_SOLID:
342  {
343  if(mpColorItem)
344  {
345  mpLbFillAttr->hide();
346  mpToolBoxColor->show();
348  }
349  break;
350  }
351  case drawing::FillStyle_GRADIENT:
352  {
353  mpLbFillAttr->show();
354  mpToolBoxColor->hide();
356 
357  if(pSh && pSh->GetItem(SID_GRADIENT_LIST))
358  {
360  mpLbFillAttr->clear();
361  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
362 
364  {
365  const OUString aString(mpFillGradientItem->GetName());
366 
367  mpLbFillAttr->set_active_text(aString);
368 
369  // Check if the entry is not in the list
370  if (mpLbFillAttr->get_active_text() != aString)
371  {
372  sal_Int32 nCount = mpLbFillAttr->get_count();
373  OUString aTmpStr;
374  if( nCount > 0 )
375  {
376  // Last entry gets tested against temporary entry
377  aTmpStr = mpLbFillAttr->get_text( nCount - 1 );
378  if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
379  aTmpStr.endsWith(TMP_STR_END) )
380  {
381  mpLbFillAttr->remove(nCount - 1);
382  }
383  }
384  aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
385 
386  XGradientList aGradientList( "", ""/*TODO?*/ );
387  aGradientList.Insert(std::make_unique<XGradientEntry>(mpFillGradientItem->GetGradientValue(), aTmpStr));
388  aGradientList.SetDirty( false );
389  const BitmapEx aBmp = aGradientList.GetUiBitmap( 0 );
390 
391  if (!aBmp.IsEmpty())
392  {
394  const Size aBmpSize(aBmp.GetSizePixel());
395  pVD->SetOutputSizePixel(aBmpSize, false);
396  pVD->DrawBitmapEx(Point(), aBmp);
397  mpLbFillAttr->append("", aGradientList.Get(0)->GetName(), *pVD);
399  }
400  }
401 
402  }
403  else
404  {
406  }
407  }
408  else
409  {
411  }
412  break;
413  }
414  case drawing::FillStyle_HATCH:
415  {
416  mpLbFillAttr->show();
417  mpToolBoxColor->hide();
419 
420  if(pSh && pSh->GetItem(SID_HATCH_LIST))
421  {
423  mpLbFillAttr->clear();
424  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
425 
426  if(mpHatchItem)
427  {
428  const OUString aString(mpHatchItem->GetName());
429 
430  mpLbFillAttr->set_active_text( aString );
431 
432  // Check if the entry is not in the list
433  if( mpLbFillAttr->get_active_text() != aString )
434  {
435  const sal_Int32 nCount = mpLbFillAttr->get_count();
436  OUString aTmpStr;
437  if( nCount > 0 )
438  {
439  // Last entry gets tested against temporary entry
440  aTmpStr = mpLbFillAttr->get_text( nCount - 1 );
441  if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
442  aTmpStr.endsWith(TMP_STR_END) )
443  {
444  mpLbFillAttr->remove( nCount - 1 );
445  }
446  }
447  aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
448 
449  XHatchList aHatchList( "", ""/*TODO?*/ );
450  aHatchList.Insert(std::make_unique<XHatchEntry>(mpHatchItem->GetHatchValue(), aTmpStr));
451  aHatchList.SetDirty( false );
452  const BitmapEx & aBmp = aHatchList.GetUiBitmap( 0 );
453 
454  if( !aBmp.IsEmpty() )
455  {
457  const Size aBmpSize(aBmp.GetSizePixel());
458  pVD->SetOutputSizePixel(aBmpSize, false);
459  pVD->DrawBitmapEx(Point(), aBmp);
460  mpLbFillAttr->append("", aHatchList.GetHatch(0)->GetName(), *pVD);
462  }
463  }
464  }
465  else
466  {
468  }
469  }
470  else
471  {
473  }
474  break;
475  }
476  case drawing::FillStyle_BITMAP:
477  {
478  mpLbFillAttr->show();
479  mpToolBoxColor->hide();
481 
482  if(pSh && pSh->GetItem(SID_BITMAP_LIST))
483  {
485  mpLbFillAttr->clear();
486  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
487 
488  if(mpBitmapItem)
489  {
490  const OUString aString(mpBitmapItem->GetName());
491 
492  mpLbFillAttr->set_active_text(aString);
493 
494  // Check if the entry is not in the list
495  if (mpLbFillAttr->get_active_text() != aString)
496  {
497  sal_Int32 nCount = mpLbFillAttr->get_count();
498  OUString aTmpStr;
499  if( nCount > 0 )
500  {
501  // Last entry gets tested against temporary entry
502  aTmpStr = mpLbFillAttr->get_text(nCount - 1);
503  if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
504  aTmpStr.endsWith(TMP_STR_END) )
505  {
506  mpLbFillAttr->remove(nCount - 1);
507  }
508  }
509  aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
510 
511  XBitmapListRef xBitmapList =
514  XPropertyListType::Bitmap, "TmpList", ""/*TODO?*/));
515  xBitmapList->Insert(std::make_unique<XBitmapEntry>(mpBitmapItem->GetGraphicObject(), aTmpStr));
516  xBitmapList->SetDirty( false );
517  SvxFillAttrBox::Fill(*mpLbFillAttr, xBitmapList);
519  }
520 
521  }
522  else
523  {
525  }
526  }
527  else
528  {
530  }
531  break;
532  }
533  default:
534  OSL_ENSURE(false, "Non supported FillType (!)");
535  break;
536  }
537  }
538 
539 }
540 
542 {
543  if(GetSlotId() == SID_ATTR_FILL_STYLE)
544  {
546 
550 
551  mpLbFillType->connect_changed(LINK(this,SvxFillToolBoxControl,SelectFillTypeHdl));
552  mpLbFillAttr->connect_changed(LINK(this,SvxFillToolBoxControl,SelectFillAttrHdl));
553 
554 
555  return mxFillControl;
556  }
557  return VclPtr<InterimItemWindow>();
558 }
559 
560 FillControl::FillControl(vcl::Window* pParent, const css::uno::Reference<css::frame::XFrame>& rFrame)
561  : InterimItemWindow(pParent, "svx/ui/fillctrlbox.ui", "FillCtrlBox")
562  , mxLbFillType(m_xBuilder->weld_combo_box("type"))
563  , mxToolBoxColor(m_xBuilder->weld_toolbar("color"))
564  , mxColorDispatch(new ToolbarUnoDispatcher(*mxToolBoxColor, *m_xBuilder, rFrame))
565  , mxLbFillAttr(m_xBuilder->weld_combo_box("attr"))
566  , mnTypeCurPos(0)
567  , mnAttrCurPos(0)
568 {
569  mxLbFillAttr->connect_key_press(LINK(this, FillControl, AttrKeyInputHdl));
570  mxLbFillType->connect_key_press(LINK(this, FillControl, TypeKeyInputHdl));
571  mxToolBoxColor->connect_key_press(LINK(this, FillControl, ColorKeyInputHdl));
572 
573  mxLbFillType->connect_get_property_tree(LINK(this, FillControl, DumpAsPropertyTreeHdl));
574 
575  mxLbFillType->connect_focus_in(LINK(this, FillControl, TypeFocusHdl));
576  mxLbFillAttr->connect_focus_in(LINK(this, FillControl, AttrFocusHdl));
577 
579 
580  SetOptimalSize();
581 }
582 
583 IMPL_STATIC_LINK(FillControl, DumpAsPropertyTreeHdl, tools::JsonWriter&, rJsonWriter, void)
584 {
585  rJsonWriter.put("command", ".uno:FillStyle");
586 }
587 
589 {
591  if (pCurSh)
592  {
593  vcl::Window* pShellWnd = pCurSh->GetWindow();
594  if (pShellWnd)
595  pShellWnd->GrabFocus();
596  }
597 }
598 
599 IMPL_LINK(FillControl, TypeKeyInputHdl, const KeyEvent&, rKEvt, bool)
600 {
601  const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
602  sal_uInt16 nCode = rKeyCode.GetCode();
603 
604  if (nCode == KEY_ESCAPE)
605  {
606  mxLbFillType->set_active(mnTypeCurPos);
607  ReleaseFocus_Impl();
608  return true;
609  }
610 
611  if (nCode != KEY_TAB)
612  return false;
613  if (rKeyCode.IsShift())
614  return ChildKeyInput(rKEvt);
615  if (mxLbFillAttr->get_visible() && !mxLbFillAttr->get_sensitive())
616  return ChildKeyInput(rKEvt);
617  return false;
618 }
619 
621 {
622  mnTypeCurPos = mxLbFillType->get_active();
623 }
624 
626 {
627  mnAttrCurPos = mxLbFillAttr->get_active();
628 }
629 
630 IMPL_LINK(FillControl, AttrKeyInputHdl, const KeyEvent&, rKEvt, bool)
631 {
632  const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
633  sal_uInt16 nCode = rKeyCode.GetCode();
634 
635  if (nCode == KEY_ESCAPE)
636  {
637  mxLbFillAttr->set_active(mnAttrCurPos);
638  ReleaseFocus_Impl();
639  return true;
640  }
641 
642  return ChildKeyInput(rKEvt);
643 }
644 
645 IMPL_LINK(FillControl, ColorKeyInputHdl, const KeyEvent&, rKEvt, bool)
646 {
647  return ChildKeyInput(rKEvt);
648 }
649 
651 {
652  if (mxLbFillType)
653  mxLbFillType->grab_focus();
655 }
656 
658 {
659  disposeOnce();
660 }
661 
663 {
664  mxLbFillAttr.reset();
665  mxColorDispatch.reset();
666  mxToolBoxColor.reset();
667  mxLbFillType.reset();
669 }
670 
672 {
673  const drawing::FillStyle eXFS = static_cast<drawing::FillStyle>(mpLbFillType->get_active());
674 
675  if(meLastXFS != eXFS)
676  {
677  mpLbFillAttr->clear();
679  const XFillStyleItem aXFillStyleItem(eXFS);
680 
681  // #i122676# Do no longer trigger two Execute calls, one for SID_ATTR_FILL_STYLE
682  // and one for setting the fill attribute itself, but add two SfxPoolItems to the
683  // call to get just one action at the SdrObject and to create only one Undo action, too.
684  // Checked that this works in all apps.
685  switch( eXFS )
686  {
687  default:
688  case drawing::FillStyle_NONE:
689  {
690  mpLbFillAttr->show();
691  mpToolBoxColor->hide();
692  mpLbFillAttr->set_sensitive(false);
693 
694  // #i122676# need to call a single SID_ATTR_FILL_STYLE change
696  SID_ATTR_FILL_STYLE, SfxCallMode::RECORD,
697  { &aXFillStyleItem });
698  break;
699  }
700  case drawing::FillStyle_SOLID:
701  {
702  mpLbFillAttr->hide();
703  mpToolBoxColor->show();
704  const ::Color aColor = mpColorItem->GetColorValue();
705  const XFillColorItem aXFillColorItem( "", aColor );
706 
707  // #i122676# change FillStyle and Color in one call
709  SID_ATTR_FILL_COLOR, SfxCallMode::RECORD,
710  { &aXFillColorItem, &aXFillStyleItem });
711  break;
712  }
713  case drawing::FillStyle_GRADIENT:
714  {
715  mpLbFillAttr->show();
716  mpToolBoxColor->hide();
717 
718  if(pSh && pSh->GetItem(SID_GRADIENT_LIST))
719  {
720  if(!mpLbFillAttr->get_count())
721  {
722  mpLbFillAttr->set_sensitive(true);
723  mpLbFillAttr->clear();
724  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
725  }
726 
727  if (mnLastPosGradient != -1)
728  {
729  const SvxGradientListItem * pItem = pSh->GetItem(SID_GRADIENT_LIST);
730 
731  if(mnLastPosGradient < pItem->GetGradientList()->Count())
732  {
733  const XGradient aGradient = pItem->GetGradientList()->GetGradient(mnLastPosGradient)->GetGradient();
734  const XFillGradientItem aXFillGradientItem(mpLbFillAttr->get_text(mnLastPosGradient), aGradient);
735 
736  // #i122676# change FillStyle and Gradient in one call
738  SID_ATTR_FILL_GRADIENT, SfxCallMode::RECORD,
739  { &aXFillGradientItem, &aXFillStyleItem });
740  mpLbFillAttr->set_active(mnLastPosGradient);
741  }
742  }
743  }
744  else
745  {
746  mpLbFillAttr->set_sensitive(false);
747  }
748  break;
749  }
750  case drawing::FillStyle_HATCH:
751  {
752  mpLbFillAttr->show();
753  mpToolBoxColor->hide();
754 
755  if(pSh && pSh->GetItem(SID_HATCH_LIST))
756  {
757  if(!mpLbFillAttr->get_count())
758  {
759  mpLbFillAttr->set_sensitive(true);
760  mpLbFillAttr->clear();
761  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
762  }
763 
764  if (mnLastPosHatch != -1)
765  {
766  const SvxHatchListItem * pItem = pSh->GetItem(SID_HATCH_LIST);
767 
768  if(mnLastPosHatch < pItem->GetHatchList()->Count())
769  {
770  const XHatch aHatch = pItem->GetHatchList()->GetHatch(mnLastPosHatch)->GetHatch();
771  const XFillHatchItem aXFillHatchItem(mpLbFillAttr->get_active_text(), aHatch);
772 
773  // #i122676# change FillStyle and Hatch in one call
775  SID_ATTR_FILL_HATCH, SfxCallMode::RECORD,
776  { &aXFillHatchItem, &aXFillStyleItem });
777  mpLbFillAttr->set_active(mnLastPosHatch);
778  }
779  }
780  }
781  else
782  {
783  mpLbFillAttr->set_sensitive(false);
784  }
785  break;
786  }
787  case drawing::FillStyle_BITMAP:
788  {
789  mpLbFillAttr->show();
790  mpToolBoxColor->hide();
791 
792  if(pSh && pSh->GetItem(SID_BITMAP_LIST))
793  {
794  if(!mpLbFillAttr->get_count())
795  {
796  mpLbFillAttr->set_sensitive(true);
797  mpLbFillAttr->clear();
798  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
799  }
800 
801  if (mnLastPosBitmap != -1)
802  {
803  const SvxBitmapListItem * pItem = pSh->GetItem(SID_BITMAP_LIST);
804 
805  if(mnLastPosBitmap < pItem->GetBitmapList()->Count())
806  {
807  const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(mnLastPosBitmap);
808  const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
809 
810  // #i122676# change FillStyle and Bitmap in one call
812  SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
813  { &aXFillBitmapItem, &aXFillStyleItem });
814  mpLbFillAttr->set_active(mnLastPosBitmap);
815  }
816  }
817  }
818  else
819  {
820  mpLbFillAttr->set_sensitive(false);
821  }
822  break;
823  }
824  }
825 
826  meLastXFS = eXFS;
827 
828  mxFillControl->Resize();
829  }
830 }
831 
833 {
834  const drawing::FillStyle eXFS = static_cast<drawing::FillStyle>(mpLbFillType->get_active());
835  const XFillStyleItem aXFillStyleItem(eXFS);
837 
838  // #i122676# dependent from bFillStyleChange, do execute a single or two
839  // changes in one Execute call
840  const bool bFillStyleChange(meLastXFS != eXFS);
841 
842  switch(eXFS)
843  {
844  case drawing::FillStyle_SOLID:
845  {
846  if(bFillStyleChange)
847  {
848  // #i122676# Single FillStyle change call needed here
850  SID_ATTR_FILL_STYLE, SfxCallMode::RECORD,
851  { &aXFillStyleItem });
852  }
853  break;
854  }
855  case drawing::FillStyle_GRADIENT:
856  {
857  sal_Int32 nPos = mpLbFillAttr->get_active();
858 
859  if (nPos == -1)
860  {
861  nPos = mnLastPosGradient;
862  }
863 
864  if (nPos != -1 && pSh && pSh->GetItem(SID_GRADIENT_LIST))
865  {
866  const SvxGradientListItem * pItem = pSh->GetItem(SID_GRADIENT_LIST);
867 
868  if(nPos < pItem->GetGradientList()->Count())
869  {
870  const XGradient aGradient = pItem->GetGradientList()->GetGradient(nPos)->GetGradient();
871  const XFillGradientItem aXFillGradientItem(mpLbFillAttr->get_active_text(), aGradient);
872 
873  // #i122676# Change FillStyle and Gradient in one call
875  SID_ATTR_FILL_GRADIENT, SfxCallMode::RECORD,
876  bFillStyleChange
877  ? std::initializer_list<SfxPoolItem const*>{ &aXFillGradientItem, &aXFillStyleItem }
878  : std::initializer_list<SfxPoolItem const*>{ &aXFillGradientItem });
879  }
880  }
881 
882  if (nPos != -1)
883  {
884  mnLastPosGradient = nPos;
885  }
886  break;
887  }
888  case drawing::FillStyle_HATCH:
889  {
890  sal_Int32 nPos = mpLbFillAttr->get_active();
891 
892  if (nPos == -1)
893  {
894  nPos = mnLastPosHatch;
895  }
896 
897  if (nPos != -1 && pSh && pSh->GetItem(SID_HATCH_LIST))
898  {
899  const SvxHatchListItem * pItem = pSh->GetItem(SID_HATCH_LIST);
900 
901  if(nPos < pItem->GetHatchList()->Count())
902  {
903  const XHatch aHatch = pItem->GetHatchList()->GetHatch(nPos)->GetHatch();
904  const XFillHatchItem aXFillHatchItem( mpLbFillAttr->get_active_text(), aHatch);
905 
906  // #i122676# Change FillStyle and Hatch in one call
908  SID_ATTR_FILL_HATCH, SfxCallMode::RECORD,
909  bFillStyleChange
910  ? std::initializer_list<SfxPoolItem const*>{ &aXFillHatchItem, &aXFillStyleItem }
911  : std::initializer_list<SfxPoolItem const*>{ &aXFillHatchItem });
912  }
913  }
914 
915  if (nPos != -1)
916  {
917  mnLastPosHatch = nPos;
918  }
919  break;
920  }
921  case drawing::FillStyle_BITMAP:
922  {
923  sal_Int32 nPos = mpLbFillAttr->get_active();
924 
925  if (nPos == -1)
926  {
927  nPos = mnLastPosBitmap;
928  }
929 
930  if (nPos != -1 && pSh && pSh->GetItem(SID_BITMAP_LIST))
931  {
932  const SvxBitmapListItem * pItem = pSh->GetItem(SID_BITMAP_LIST);
933 
934  if(nPos < pItem->GetBitmapList()->Count())
935  {
936  const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(nPos);
937  const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
938 
939  // #i122676# Change FillStyle and Bitmap in one call
941  SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
942  bFillStyleChange
943  ? std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem, &aXFillStyleItem }
944  : std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem });
945  }
946  }
947 
948  if (nPos != -1)
949  {
950  mnLastPosBitmap = nPos;
951  }
952  break;
953  }
954  default: break;
955  }
956 }
957 
959 {
960  Size aSize(mxLbFillType->get_preferred_size());
961  Size aFirstSize(mxToolBoxColor->get_preferred_size());
962  auto nWidth = std::max(aFirstSize.Width(), LogicToPixel(Size(55, 0), MapMode(MapUnit::MapAppFont)).Width());
963  auto nHeight = std::max(aSize.Height(), aFirstSize.Height());
964  mxToolBoxColor->set_size_request(nWidth, -1);
965  mxLbFillAttr->set_size_request(42, -1); //something narrow so the toolbar sets the overall size of this column
966  SetSizePixel(Size(m_xContainer->get_preferred_size().Width(), nHeight));
967 }
968 
970 {
971  if((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
972  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
973  {
974  SetOptimalSize();
975  }
977 }
978 
979 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual ~FillControl() override
Definition: fillctrl.cxx:657
virtual void dispose() override
Definition: fillctrl.cxx:662
XPropertyEntry * Get(long nIndex) const
Definition: xtable.cxx:131
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 * >())
std::unique_ptr< XFillBitmapItem > mpBitmapItem
Definition: fillctrl.hxx:50
virtual void hide()=0
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const =0
SVX_DLLPUBLIC void Fill(weld::ComboBox &, const XHatchListRef &pList)
Definition: itemwin.cxx:248
SfxDispatcher * GetDispatcher()
virtual OUString get_text(int pos) const =0
static XBitmapListRef AsBitmapList(rtl::Reference< XPropertyList > const &plist)
Definition: xtable.hxx:389
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:620
static SfxObjectShell * Current()
void append(const OUString &rId, const OUString &rStr)
virtual void StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem *pState) override
Definition: fillctrl.cxx:87
css::drawing::FillStyle meLastXFS
Definition: fillctrl.hxx:57
virtual int get_count() const =0
void Insert(std::unique_ptr< XPropertyEntry > pEntry, long nIndex=std::numeric_limits< long >::max())
Definition: xtable.cxx:177
virtual void show()=0
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: fillctrl.cxx:969
FillControl(vcl::Window *pParent, const css::uno::Reference< css::frame::XFrame > &rFrame)
Definition: fillctrl.cxx:560
int nCount
virtual void GetFocus() override
AllSettingsFlags GetFlags() const
static SfxViewShell * Current()
IMPL_LINK(FillControl, TypeKeyInputHdl, const KeyEvent &, rKEvt, bool)
Definition: fillctrl.cxx:599
virtual void Resize() override
sal_uInt16 nCode
const GraphicObject & GetGraphicObject() const
Definition: xtable.hxx:125
const OUString & GetName() const
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:84
virtual ~SvxFillToolBoxControl() override
Definition: fillctrl.cxx:83
void set_active_text(const OUString &rStr)
SVX_DLLPUBLIC void Fill(weld::ComboBox &rListBox)
Definition: itemwin.cxx:178
static void ReleaseFocus_Impl()
Definition: fillctrl.cxx:588
void SetOptimalSize()
Definition: fillctrl.cxx:958
void connect_changed(const Link< ComboBox &, void > &rLink)
#define TMP_STR_END
Definition: fillctrl.cxx:32
Count
SvxFillToolBoxControl(sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox &rTbx)
Definition: fillctrl.cxx:54
XHatchEntry * GetHatch(long nIndex) const
Definition: xtabhtch.cxx:53
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
virtual void GetFocus() override
Definition: fillctrl.cxx:650
weld::ComboBox * mpLbFillType
Definition: fillctrl.hxx:53
void GrabFocus()
void SetDirty(bool bDirty)
Definition: xtable.hxx:192
const XBitmapListRef & GetBitmapList() const
Definition: drawitem.hxx:122
SFX_IMPL_TOOLBOX_CONTROL(SvxFillToolBoxControl, XFillStyleItem)
void reset(reference_type *pBody)
Point LogicToPixel(const Point &rLogicPt) const
bool IsShift() const
static SfxViewFrame * Current()
virtual VclPtr< InterimItemWindow > CreateItemWindow(vcl::Window *pParent) override
Definition: fillctrl.cxx:541
SfxItemState
std::unique_ptr< weld::Container > m_xContainer
#define TMP_STR_BEGIN
Definition: fillctrl.cxx:31
weld::ComboBox * mpLbFillAttr
Definition: fillctrl.hxx:55
constexpr sal_uInt16 KEY_ESCAPE
virtual void dispose() override
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:83
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:583
std::unique_ptr< weld::Toolbar > mxToolBoxColor
Definition: fillctrl.hxx:82
BitmapEx GetUiBitmap(long nIndex) const
Definition: xtable.cxx:160
const Size & GetSizePixel() const
std::unique_ptr< weld::ComboBox > mxLbFillType
Definition: fillctrl.hxx:81
virtual XFillStyleItem * Clone(SfxItemPool *pPool=nullptr) const override
Definition: xattr.cxx:1743
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