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 <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  return;
329 
330  const drawing::FillStyle eXFS = mpStyleItem->GetValue();
332 
333  switch( eXFS )
334  {
335  case drawing::FillStyle_NONE:
336  {
337  mpLbFillAttr->show();
338  mpToolBoxColor->hide();
340  break;
341  }
342  case drawing::FillStyle_SOLID:
343  {
344  if(mpColorItem)
345  {
346  mpLbFillAttr->hide();
347  mpToolBoxColor->show();
349  }
350  break;
351  }
352  case drawing::FillStyle_GRADIENT:
353  {
354  mpLbFillAttr->show();
355  mpToolBoxColor->hide();
357 
358  if(pSh && pSh->GetItem(SID_GRADIENT_LIST))
359  {
361  mpLbFillAttr->clear();
362  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
363 
365  {
366  const OUString aString(mpFillGradientItem->GetName());
367 
368  mpLbFillAttr->set_active_text(aString);
369 
370  // Check if the entry is not in the list
371  if (mpLbFillAttr->get_active_text() != aString)
372  {
373  sal_Int32 nCount = mpLbFillAttr->get_count();
374  OUString aTmpStr;
375  if( nCount > 0 )
376  {
377  // Last entry gets tested against temporary entry
378  aTmpStr = mpLbFillAttr->get_text( nCount - 1 );
379  if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
380  aTmpStr.endsWith(TMP_STR_END) )
381  {
382  mpLbFillAttr->remove(nCount - 1);
383  }
384  }
385  aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
386 
387  XGradientList aGradientList( "", ""/*TODO?*/ );
388  aGradientList.Insert(std::make_unique<XGradientEntry>(mpFillGradientItem->GetGradientValue(), aTmpStr));
389  aGradientList.SetDirty( false );
390  const BitmapEx aBmp = aGradientList.GetUiBitmap( 0 );
391 
392  if (!aBmp.IsEmpty())
393  {
395  const Size aBmpSize(aBmp.GetSizePixel());
396  pVD->SetOutputSizePixel(aBmpSize, false);
397  pVD->DrawBitmapEx(Point(), aBmp);
398  mpLbFillAttr->append("", aGradientList.Get(0)->GetName(), *pVD);
400  }
401  }
402 
403  }
404  else
405  {
407  }
408  }
409  else
410  {
412  }
413  break;
414  }
415  case drawing::FillStyle_HATCH:
416  {
417  mpLbFillAttr->show();
418  mpToolBoxColor->hide();
420 
421  if(pSh && pSh->GetItem(SID_HATCH_LIST))
422  {
424  mpLbFillAttr->clear();
425  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
426 
427  if(mpHatchItem)
428  {
429  const OUString aString(mpHatchItem->GetName());
430 
431  mpLbFillAttr->set_active_text( aString );
432 
433  // Check if the entry is not in the list
434  if( mpLbFillAttr->get_active_text() != aString )
435  {
436  const sal_Int32 nCount = mpLbFillAttr->get_count();
437  OUString aTmpStr;
438  if( nCount > 0 )
439  {
440  // Last entry gets tested against temporary entry
441  aTmpStr = mpLbFillAttr->get_text( nCount - 1 );
442  if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
443  aTmpStr.endsWith(TMP_STR_END) )
444  {
445  mpLbFillAttr->remove( nCount - 1 );
446  }
447  }
448  aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
449 
450  XHatchList aHatchList( "", ""/*TODO?*/ );
451  aHatchList.Insert(std::make_unique<XHatchEntry>(mpHatchItem->GetHatchValue(), aTmpStr));
452  aHatchList.SetDirty( false );
453  const BitmapEx & aBmp = aHatchList.GetUiBitmap( 0 );
454 
455  if( !aBmp.IsEmpty() )
456  {
458  const Size aBmpSize(aBmp.GetSizePixel());
459  pVD->SetOutputSizePixel(aBmpSize, false);
460  pVD->DrawBitmapEx(Point(), aBmp);
461  mpLbFillAttr->append("", aHatchList.GetHatch(0)->GetName(), *pVD);
463  }
464  }
465  }
466  else
467  {
469  }
470  }
471  else
472  {
474  }
475  break;
476  }
477  case drawing::FillStyle_BITMAP:
478  {
479  mpLbFillAttr->show();
480  mpToolBoxColor->hide();
482 
483  if(pSh && pSh->GetItem(SID_BITMAP_LIST))
484  {
486  mpLbFillAttr->clear();
487  SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
488 
489  if(mpBitmapItem)
490  {
491  const OUString aString(mpBitmapItem->GetName());
492 
493  mpLbFillAttr->set_active_text(aString);
494 
495  // Check if the entry is not in the list
496  if (mpLbFillAttr->get_active_text() != aString)
497  {
498  sal_Int32 nCount = mpLbFillAttr->get_count();
499  OUString aTmpStr;
500  if( nCount > 0 )
501  {
502  // Last entry gets tested against temporary entry
503  aTmpStr = mpLbFillAttr->get_text(nCount - 1);
504  if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
505  aTmpStr.endsWith(TMP_STR_END) )
506  {
507  mpLbFillAttr->remove(nCount - 1);
508  }
509  }
510  aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
511 
512  XBitmapListRef xBitmapList =
515  XPropertyListType::Bitmap, "TmpList", ""/*TODO?*/));
516  xBitmapList->Insert(std::make_unique<XBitmapEntry>(mpBitmapItem->GetGraphicObject(), aTmpStr));
517  xBitmapList->SetDirty( false );
518  SvxFillAttrBox::Fill(*mpLbFillAttr, xBitmapList);
520  }
521 
522  }
523  else
524  {
526  }
527  }
528  else
529  {
531  }
532  break;
533  }
534  default:
535  OSL_ENSURE(false, "Non supported FillType (!)");
536  break;
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 {
570 
571  mxLbFillAttr->connect_key_press(LINK(this, FillControl, AttrKeyInputHdl));
572  mxLbFillType->connect_key_press(LINK(this, FillControl, TypeKeyInputHdl));
573  mxToolBoxColor->connect_key_press(LINK(this, FillControl, ColorKeyInputHdl));
574 
575  mxLbFillType->connect_get_property_tree(LINK(this, FillControl, DumpAsPropertyTreeHdl));
576 
577  mxLbFillType->connect_focus_in(LINK(this, FillControl, TypeFocusHdl));
578  mxLbFillAttr->connect_focus_in(LINK(this, FillControl, AttrFocusHdl));
579 
581 
582  SetOptimalSize();
583 }
584 
585 IMPL_STATIC_LINK(FillControl, DumpAsPropertyTreeHdl, tools::JsonWriter&, rJsonWriter, void)
586 {
587  rJsonWriter.put("command", ".uno:FillStyle");
588 }
589 
591 {
593  if (pCurSh)
594  {
595  vcl::Window* pShellWnd = pCurSh->GetWindow();
596  if (pShellWnd)
597  pShellWnd->GrabFocus();
598  }
599 }
600 
601 IMPL_LINK(FillControl, TypeKeyInputHdl, const KeyEvent&, rKEvt, bool)
602 {
603  const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
604  sal_uInt16 nCode = rKeyCode.GetCode();
605 
606  if (nCode == KEY_ESCAPE)
607  {
608  mxLbFillType->set_active(mnTypeCurPos);
609  ReleaseFocus_Impl();
610  return true;
611  }
612 
613  if (nCode != KEY_TAB)
614  return false;
615  if (rKeyCode.IsShift())
616  return ChildKeyInput(rKEvt);
617  if (mxLbFillAttr->get_visible() && !mxLbFillAttr->get_sensitive())
618  return ChildKeyInput(rKEvt);
619  return false;
620 }
621 
623 {
624  mnTypeCurPos = mxLbFillType->get_active();
625 }
626 
628 {
629  mnAttrCurPos = mxLbFillAttr->get_active();
630 }
631 
632 IMPL_LINK(FillControl, AttrKeyInputHdl, 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  mxLbFillAttr->set_active(mnAttrCurPos);
640  ReleaseFocus_Impl();
641  return true;
642  }
643 
644  return ChildKeyInput(rKEvt);
645 }
646 
647 IMPL_LINK(FillControl, ColorKeyInputHdl, const KeyEvent&, rKEvt, bool)
648 {
649  return ChildKeyInput(rKEvt);
650 }
651 
653 {
654  disposeOnce();
655 }
656 
658 {
659  mxLbFillAttr.reset();
660  mxColorDispatch.reset();
661  mxToolBoxColor.reset();
662  mxLbFillType.reset();
664 }
665 
667 {
668  const drawing::FillStyle eXFS = static_cast<drawing::FillStyle>(mpLbFillType->get_active());
669 
670  if(meLastXFS == eXFS)
671  return;
672 
673  mpLbFillAttr->clear();
675  const XFillStyleItem aXFillStyleItem(eXFS);
676 
677  // #i122676# Do no longer trigger two Execute calls, one for SID_ATTR_FILL_STYLE
678  // and one for setting the fill attribute itself, but add two SfxPoolItems to the
679  // call to get just one action at the SdrObject and to create only one Undo action, too.
680  // Checked that this works in all apps.
681  switch( eXFS )
682  {
683  default:
684  case drawing::FillStyle_NONE:
685  {
686  mpLbFillAttr->show();
687  mpToolBoxColor->hide();
688  mpLbFillAttr->set_sensitive(false);
689  if (pSh)
690  {
691  // #i122676# need to call a single SID_ATTR_FILL_STYLE change
692  pSh->GetDispatcher()->ExecuteList(
693  SID_ATTR_FILL_STYLE, SfxCallMode::RECORD,
694  { &aXFillStyleItem });
695  }
696  break;
697  }
698  case drawing::FillStyle_SOLID:
699  {
700  mpLbFillAttr->hide();
701  mpToolBoxColor->show();
702  const ::Color aColor = mpColorItem->GetColorValue();
703  const XFillColorItem aXFillColorItem( "", aColor );
704  if (pSh)
705  {
706  // #i122676# change FillStyle and Color in one call
707  pSh->GetDispatcher()->ExecuteList(
708  SID_ATTR_FILL_COLOR, SfxCallMode::RECORD,
709  { &aXFillColorItem, &aXFillStyleItem });
710  }
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
737  pSh->GetDispatcher()->ExecuteList(
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
774  pSh->GetDispatcher()->ExecuteList(
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
811  pSh->GetDispatcher()->ExecuteList(
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 
832 {
833  const drawing::FillStyle eXFS = static_cast<drawing::FillStyle>(mpLbFillType->get_active());
834  const XFillStyleItem aXFillStyleItem(eXFS);
836 
837  // #i122676# dependent from bFillStyleChange, do execute a single or two
838  // changes in one Execute call
839  const bool bFillStyleChange(meLastXFS != eXFS);
840 
841  switch(eXFS)
842  {
843  case drawing::FillStyle_SOLID:
844  {
845  if (bFillStyleChange && pSh)
846  {
847  // #i122676# Single FillStyle change call needed here
848  pSh->GetDispatcher()->ExecuteList(
849  SID_ATTR_FILL_STYLE, SfxCallMode::RECORD,
850  { &aXFillStyleItem });
851  }
852  break;
853  }
854  case drawing::FillStyle_GRADIENT:
855  {
856  sal_Int32 nPos = mpLbFillAttr->get_active();
857 
858  if (nPos == -1)
859  {
860  nPos = mnLastPosGradient;
861  }
862 
863  if (nPos != -1 && pSh && pSh->GetItem(SID_GRADIENT_LIST))
864  {
865  const SvxGradientListItem * pItem = pSh->GetItem(SID_GRADIENT_LIST);
866 
867  if(nPos < pItem->GetGradientList()->Count())
868  {
869  const XGradient aGradient = pItem->GetGradientList()->GetGradient(nPos)->GetGradient();
870  const XFillGradientItem aXFillGradientItem(mpLbFillAttr->get_active_text(), aGradient);
871 
872  // #i122676# Change FillStyle and Gradient in one call
873  pSh->GetDispatcher()->ExecuteList(
874  SID_ATTR_FILL_GRADIENT, SfxCallMode::RECORD,
875  bFillStyleChange
876  ? std::initializer_list<SfxPoolItem const*>{ &aXFillGradientItem, &aXFillStyleItem }
877  : std::initializer_list<SfxPoolItem const*>{ &aXFillGradientItem });
878  }
879  }
880 
881  if (nPos != -1)
882  {
883  mnLastPosGradient = nPos;
884  }
885  break;
886  }
887  case drawing::FillStyle_HATCH:
888  {
889  sal_Int32 nPos = mpLbFillAttr->get_active();
890 
891  if (nPos == -1)
892  {
893  nPos = mnLastPosHatch;
894  }
895 
896  if (nPos != -1 && pSh && pSh->GetItem(SID_HATCH_LIST))
897  {
898  const SvxHatchListItem * pItem = pSh->GetItem(SID_HATCH_LIST);
899 
900  if(nPos < pItem->GetHatchList()->Count())
901  {
902  const XHatch aHatch = pItem->GetHatchList()->GetHatch(nPos)->GetHatch();
903  const XFillHatchItem aXFillHatchItem( mpLbFillAttr->get_active_text(), aHatch);
904 
905  // #i122676# Change FillStyle and Hatch in one call
906  pSh->GetDispatcher()->ExecuteList(
907  SID_ATTR_FILL_HATCH, SfxCallMode::RECORD,
908  bFillStyleChange
909  ? std::initializer_list<SfxPoolItem const*>{ &aXFillHatchItem, &aXFillStyleItem }
910  : std::initializer_list<SfxPoolItem const*>{ &aXFillHatchItem });
911  }
912  }
913 
914  if (nPos != -1)
915  {
916  mnLastPosHatch = nPos;
917  }
918  break;
919  }
920  case drawing::FillStyle_BITMAP:
921  {
922  sal_Int32 nPos = mpLbFillAttr->get_active();
923 
924  if (nPos == -1)
925  {
926  nPos = mnLastPosBitmap;
927  }
928 
929  if (nPos != -1 && pSh && pSh->GetItem(SID_BITMAP_LIST))
930  {
931  const SvxBitmapListItem * pItem = pSh->GetItem(SID_BITMAP_LIST);
932 
933  if(nPos < pItem->GetBitmapList()->Count())
934  {
935  const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(nPos);
936  const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
937 
938  // #i122676# Change FillStyle and Bitmap in one call
939  pSh->GetDispatcher()->ExecuteList(
940  SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
941  bFillStyleChange
942  ? std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem, &aXFillStyleItem }
943  : std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem });
944  }
945  }
946 
947  if (nPos != -1)
948  {
949  mnLastPosBitmap = nPos;
950  }
951  break;
952  }
953  default: break;
954  }
955 }
956 
958 {
959  Size aSize(mxLbFillType->get_preferred_size());
960  Size aFirstSize(mxToolBoxColor->get_preferred_size());
961  auto nWidth = std::max(aFirstSize.Width(), LogicToPixel(Size(55, 0), MapMode(MapUnit::MapAppFont)).Width());
962  auto nHeight = std::max(aSize.Height(), aFirstSize.Height());
963  mxToolBoxColor->set_size_request(nWidth, -1);
964  mxLbFillAttr->set_size_request(42, -1); //something narrow so the toolbar sets the overall size of this column
965  SetSizePixel(Size(m_xContainer->get_preferred_size().Width(), nHeight));
966 }
967 
969 {
970  if((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
971  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
972  {
973  SetOptimalSize();
974  }
976 }
977 
978 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual ~FillControl() override
Definition: fillctrl.cxx:652
virtual void dispose() override
Definition: fillctrl.cxx:657
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
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:622
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
virtual void show()=0
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: fillctrl.cxx:968
FillControl(vcl::Window *pParent, const css::uno::Reference< css::frame::XFrame > &rFrame)
Definition: fillctrl.cxx:560
int nCount
AllSettingsFlags GetFlags() const
static SfxViewShell * Current()
IMPL_LINK(FillControl, TypeKeyInputHdl, const KeyEvent &, rKEvt, bool)
Definition: fillctrl.cxx:601
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:174
void Insert(std::unique_ptr< XPropertyEntry > pEntry, tools::Long nIndex=std::numeric_limits< tools::Long >::max())
Definition: xtable.cxx:177
SfxDispatcher * GetDispatcher() const
static void ReleaseFocus_Impl()
Definition: fillctrl.cxx:590
void SetOptimalSize()
Definition: fillctrl.cxx:957
void connect_changed(const Link< ComboBox &, void > &rLink)
#define TMP_STR_END
Definition: fillctrl.cxx:33
Count
XPropertyEntry * Get(tools::Long nIndex) const
Definition: xtable.cxx:131
SvxFillToolBoxControl(sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox &rTbx)
Definition: fillctrl.cxx:54
BitmapEx GetUiBitmap(tools::Long nIndex) const
Definition: xtable.cxx:160
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
XHatchEntry * GetHatch(tools::Long nIndex) const
Definition: xtabhtch.cxx:53
bool IsShift() const
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: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:585
std::unique_ptr< weld::Toolbar > mxToolBoxColor
Definition: fillctrl.hxx:82
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