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