1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sfx2/dispatch.hxx>
21 #include <sfx2/objsh.hxx>
22 #include <sfx2/viewsh.hxx>
23 #include <rtl/ustring.hxx>
24 #include <vcl/event.hxx>
25 #include <vcl/settings.hxx>
26 #include <vcl/toolbox.hxx>
27 #include <vcl/virdev.hxx>
28 #include <svx/svxids.hrc>
29 #include <tools/json_writer.hxx>
31 constexpr OUStringLiteral TMP_STR_BEGIN
= u
"[";
32 constexpr OUStringLiteral TMP_STR_END
= u
"]";
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>
45 using namespace ::com::sun::star
;
46 using namespace ::com::sun::star::uno
;
47 using namespace ::com::sun::star::util
;
48 using namespace ::com::sun::star::beans
;
49 using namespace ::com::sun::star::lang
;
63 drawing::FillStyle
toCssFillStyle( eFillStyle eXFS
)
67 return drawing::FillStyle_BITMAP
;
70 return static_cast<drawing::FillStyle
>(eXFS
);
75 SFX_IMPL_TOOLBOX_CONTROL( SvxFillToolBoxControl
, XFillStyleItem
);
77 SvxFillToolBoxControl::SvxFillToolBoxControl(
81 : SfxToolBoxControl( nSlotId
, nId
, rTbx
)
82 , mxFillControl(nullptr)
83 , mpLbFillType(nullptr)
84 , mpToolBoxColor(nullptr)
85 , mpLbFillAttr(nullptr)
87 , mnLastPosGradient(0)
92 addStatusListener( ".uno:FillColor");
93 addStatusListener( ".uno:FillGradient");
94 addStatusListener( ".uno:FillHatch");
95 addStatusListener( ".uno:FillBitmap");
96 addStatusListener( ".uno:ColorTableState");
97 addStatusListener( ".uno:GradientListState");
98 addStatusListener( ".uno:HatchListState");
99 addStatusListener( ".uno:BitmapListState");
102 SvxFillToolBoxControl::~SvxFillToolBoxControl()
106 void SvxFillToolBoxControl::StateChangedAtToolBoxControl(
109 const SfxPoolItem
* pState
)
111 const bool bDisabled(SfxItemState::DISABLED
== eState
);
115 case SID_ATTR_FILL_STYLE
:
119 mpLbFillType
->set_sensitive(false);
120 mpLbFillType
->set_active(-1);
121 mpLbFillAttr
->show();
122 mpLbFillAttr
->set_sensitive(false);
123 mpLbFillAttr
->set_active(-1);
124 mpToolBoxColor
->hide();
129 if(eState
>= SfxItemState::DEFAULT
)
131 const XFillStyleItem
* pItem
= dynamic_cast< const XFillStyleItem
* >(pState
);
135 mpStyleItem
.reset(pItem
->Clone());
136 mpLbFillType
->set_sensitive(true);
137 drawing::FillStyle eXFS
= mpStyleItem
->GetValue();
138 mnLastXFS
= sal::static_int_cast
< sal_Int32
>(eXFS
);
139 mpLbFillType
->set_active(mnLastXFS
);
141 if(drawing::FillStyle_NONE
== eXFS
)
143 mpLbFillAttr
->set_active(-1);
144 mpLbFillAttr
->set_sensitive(false);
152 mpLbFillType
->set_active(-1);
153 mpLbFillAttr
->show();
154 mpLbFillAttr
->set_sensitive(false);
155 mpLbFillAttr
->set_active(-1);
156 mpToolBoxColor
->hide();
159 mxFillControl
->Resize();
162 case SID_ATTR_FILL_COLOR
:
164 if(SfxItemState::DEFAULT
== eState
)
166 mpColorItem
.reset(pState
? static_cast<XFillColorItem
*>(pState
->Clone()) : nullptr);
169 if(mpStyleItem
&& drawing::FillStyle_SOLID
== mpStyleItem
->GetValue())
171 mpLbFillAttr
->hide();
172 mpToolBoxColor
->show();
173 mxFillControl
->Resize();
179 case SID_ATTR_FILL_GRADIENT
:
181 if(SfxItemState::DEFAULT
== eState
)
183 mpFillGradientItem
.reset(pState
? static_cast<XFillGradientItem
*>(pState
->Clone()) : nullptr);
186 if(mpStyleItem
&& drawing::FillStyle_GRADIENT
== mpStyleItem
->GetValue())
188 mpLbFillAttr
->show();
189 mpToolBoxColor
->hide();
190 mxFillControl
->Resize();
192 if(SfxItemState::DEFAULT
== eState
)
194 mpLbFillAttr
->set_sensitive(true);
197 else if(SfxItemState::DISABLED
== eState
)
199 mpLbFillAttr
->set_sensitive(false);
200 mpLbFillAttr
->set_active(-1);
204 mpLbFillAttr
->set_active(-1);
209 case SID_ATTR_FILL_HATCH
:
211 if(SfxItemState::DEFAULT
== eState
)
213 mpHatchItem
.reset(pState
? static_cast<XFillHatchItem
*>(pState
->Clone()) : nullptr);
216 if(mpStyleItem
&& drawing::FillStyle_HATCH
== mpStyleItem
->GetValue())
218 mpLbFillAttr
->show();
219 mpToolBoxColor
->hide();
220 mxFillControl
->Resize();
222 if(SfxItemState::DEFAULT
== eState
)
224 mpLbFillAttr
->set_sensitive(true);
227 else if(SfxItemState::DISABLED
== eState
)
229 mpLbFillAttr
->set_sensitive(false);
230 mpLbFillAttr
->set_active(-1);
234 mpLbFillAttr
->set_active(-1);
239 case SID_ATTR_FILL_BITMAP
:
241 if(SfxItemState::DEFAULT
== eState
)
243 mpBitmapItem
.reset(pState
? static_cast<XFillBitmapItem
*>(pState
->Clone()) : nullptr);
246 if(mpStyleItem
&& drawing::FillStyle_BITMAP
== mpStyleItem
->GetValue())
248 mpLbFillAttr
->show();
249 mpToolBoxColor
->hide();
250 mxFillControl
->Resize();
252 if(SfxItemState::DEFAULT
== eState
)
254 mpLbFillAttr
->set_sensitive(true);
257 else if(SfxItemState::DISABLED
== eState
)
259 mpLbFillAttr
->set_sensitive(false);
260 mpLbFillAttr
->set_active(-1);
264 mpLbFillAttr
->set_active(-1);
269 case SID_GRADIENT_LIST
:
271 if(SfxItemState::DEFAULT
== eState
)
273 if(mpStyleItem
&& drawing::FillStyle_GRADIENT
== mpStyleItem
->GetValue())
275 if(mpFillGradientItem
)
277 const OUString
aString( mpFillGradientItem
->GetName() );
278 mpLbFillAttr
->clear();
279 if (const SfxObjectShell
* pSh
= SfxObjectShell::Current())
281 mpLbFillAttr
->set_sensitive(true);
282 SvxFillAttrBox::Fill(*mpLbFillAttr
, pSh
->GetItem(SID_GRADIENT_LIST
)->GetGradientList());
284 mpLbFillAttr
->set_active_text(aString
);
288 mpLbFillAttr
->set_active(-1);
296 if(SfxItemState::DEFAULT
== eState
)
298 if(mpStyleItem
&& drawing::FillStyle_HATCH
== mpStyleItem
->GetValue())
302 const OUString
aString( mpHatchItem
->GetName() );
303 mpLbFillAttr
->clear();
304 if (const SfxObjectShell
* pSh
= SfxObjectShell::Current())
306 mpLbFillAttr
->set_sensitive(true);
307 SvxFillAttrBox::Fill(*mpLbFillAttr
, pSh
->GetItem(SID_HATCH_LIST
)->GetHatchList());
309 mpLbFillAttr
->set_active_text(aString
);
313 mpLbFillAttr
->set_active(-1);
319 case SID_BITMAP_LIST
:
321 if(SfxItemState::DEFAULT
== eState
)
323 if(mpStyleItem
&& drawing::FillStyle_BITMAP
== mpStyleItem
->GetValue())
327 const OUString
aString( mpBitmapItem
->GetName() );
328 mpLbFillAttr
->clear();
329 if (const SfxObjectShell
* pSh
= SfxObjectShell::Current())
331 mpLbFillAttr
->set_sensitive(true);
332 SvxFillAttrBox::Fill(*mpLbFillAttr
, pSh
->GetItem(SID_BITMAP_LIST
)->GetBitmapList());
334 mpLbFillAttr
->set_active_text(aString
);
338 mpLbFillAttr
->set_active(-1);
347 void SvxFillToolBoxControl::Update()
352 const drawing::FillStyle eXFS
= mpStyleItem
->GetValue();
353 SfxObjectShell
* pSh
= SfxObjectShell::Current();
357 case drawing::FillStyle_NONE
:
359 mpLbFillAttr
->show();
360 mpToolBoxColor
->hide();
361 mxFillControl
->Resize();
364 case drawing::FillStyle_SOLID
:
368 mpLbFillAttr
->hide();
369 mpToolBoxColor
->show();
370 mxFillControl
->Resize();
374 case drawing::FillStyle_GRADIENT
:
376 mpLbFillAttr
->show();
377 mpToolBoxColor
->hide();
378 mxFillControl
->Resize();
380 if(pSh
&& pSh
->GetItem(SID_GRADIENT_LIST
))
382 mpLbFillAttr
->set_sensitive(true);
383 mpLbFillAttr
->clear();
384 SvxFillAttrBox::Fill(*mpLbFillAttr
, pSh
->GetItem(SID_GRADIENT_LIST
)->GetGradientList());
386 if(mpFillGradientItem
)
388 const OUString
aString(mpFillGradientItem
->GetName());
390 mpLbFillAttr
->set_active_text(aString
);
392 // Check if the entry is not in the list
393 if (mpLbFillAttr
->get_active_text() != aString
)
395 sal_Int32 nCount
= mpLbFillAttr
->get_count();
399 // Last entry gets tested against temporary entry
400 aTmpStr
= mpLbFillAttr
->get_text( nCount
- 1 );
401 if( aTmpStr
.startsWith(TMP_STR_BEGIN
) &&
402 aTmpStr
.endsWith(TMP_STR_END
) )
404 mpLbFillAttr
->remove(nCount
- 1);
407 aTmpStr
= TMP_STR_BEGIN
+ aString
+ TMP_STR_END
;
409 rtl::Reference
<XGradientList
> xGradientList
= new XGradientList( "", ""/*TODO?*/ );
410 xGradientList
->Insert(std::make_unique
<XGradientEntry
>(mpFillGradientItem
->GetGradientValue(), aTmpStr
));
411 xGradientList
->SetDirty( false );
412 const BitmapEx aBmp
= xGradientList
->GetUiBitmap( 0 );
416 ScopedVclPtrInstance
< VirtualDevice
> pVD
;
417 const Size
aBmpSize(aBmp
.GetSizePixel());
418 pVD
->SetOutputSizePixel(aBmpSize
, false);
419 pVD
->DrawBitmapEx(Point(), aBmp
);
420 mpLbFillAttr
->append("", xGradientList
->Get(0)->GetName(), *pVD
);
421 mpLbFillAttr
->set_active(mpLbFillAttr
->get_count() - 1);
428 mpLbFillAttr
->set_active(-1);
433 mpLbFillAttr
->set_active(-1);
437 case drawing::FillStyle_HATCH
:
439 mpLbFillAttr
->show();
440 mpToolBoxColor
->hide();
441 mxFillControl
->Resize();
443 if(pSh
&& pSh
->GetItem(SID_HATCH_LIST
))
445 mpLbFillAttr
->set_sensitive(true);
446 mpLbFillAttr
->clear();
447 SvxFillAttrBox::Fill(*mpLbFillAttr
, pSh
->GetItem(SID_HATCH_LIST
)->GetHatchList());
451 const OUString
aString(mpHatchItem
->GetName());
453 mpLbFillAttr
->set_active_text( aString
);
455 // Check if the entry is not in the list
456 if( mpLbFillAttr
->get_active_text() != aString
)
458 const sal_Int32 nCount
= mpLbFillAttr
->get_count();
462 // Last entry gets tested against temporary entry
463 aTmpStr
= mpLbFillAttr
->get_text( nCount
- 1 );
464 if( aTmpStr
.startsWith(TMP_STR_BEGIN
) &&
465 aTmpStr
.endsWith(TMP_STR_END
) )
467 mpLbFillAttr
->remove( nCount
- 1 );
470 aTmpStr
= TMP_STR_BEGIN
+ aString
+ TMP_STR_END
;
472 rtl::Reference
<XHatchList
> xHatchList
= new XHatchList( "", ""/*TODO?*/ );
473 xHatchList
->Insert(std::make_unique
<XHatchEntry
>(mpHatchItem
->GetHatchValue(), aTmpStr
));
474 xHatchList
->SetDirty( false );
475 const BitmapEx
& aBmp
= xHatchList
->GetUiBitmap( 0 );
477 if( !aBmp
.IsEmpty() )
479 ScopedVclPtrInstance
< VirtualDevice
> pVD
;
480 const Size
aBmpSize(aBmp
.GetSizePixel());
481 pVD
->SetOutputSizePixel(aBmpSize
, false);
482 pVD
->DrawBitmapEx(Point(), aBmp
);
483 mpLbFillAttr
->append("", xHatchList
->GetHatch(0)->GetName(), *pVD
);
484 mpLbFillAttr
->set_active(mpLbFillAttr
->get_count() - 1);
490 mpLbFillAttr
->set_active(-1);
495 mpLbFillAttr
->set_active(-1);
499 case drawing::FillStyle_BITMAP
:
501 mpLbFillAttr
->show();
502 mpToolBoxColor
->hide();
503 mxFillControl
->Resize();
507 mpLbFillAttr
->set_sensitive(true);
508 mpLbFillAttr
->clear();
510 if(mpBitmapItem
&& !mpBitmapItem
->isPattern() && pSh
->GetItem(SID_BITMAP_LIST
))
512 SvxFillAttrBox::Fill(*mpLbFillAttr
, pSh
->GetItem(SID_BITMAP_LIST
)->GetBitmapList());
514 const OUString
aString(mpBitmapItem
->GetName());
516 mpLbFillAttr
->set_active_text(aString
);
518 // Check if the entry is not in the list
519 if (mpLbFillAttr
->get_active_text() != aString
)
521 sal_Int32 nCount
= mpLbFillAttr
->get_count();
525 // Last entry gets tested against temporary entry
526 aTmpStr
= mpLbFillAttr
->get_text(nCount
- 1);
527 if( aTmpStr
.startsWith(TMP_STR_BEGIN
) &&
528 aTmpStr
.endsWith(TMP_STR_END
) )
530 mpLbFillAttr
->remove(nCount
- 1);
533 aTmpStr
= TMP_STR_BEGIN
+ aString
+ TMP_STR_END
;
535 XBitmapListRef xBitmapList
=
536 XPropertyList::AsBitmapList(
537 XPropertyList::CreatePropertyList(
538 XPropertyListType::Bitmap
, "TmpList", ""/*TODO?*/));
539 xBitmapList
->Insert(std::make_unique
<XBitmapEntry
>(mpBitmapItem
->GetGraphicObject(), aTmpStr
));
540 xBitmapList
->SetDirty( false );
541 SvxFillAttrBox::Fill(*mpLbFillAttr
, xBitmapList
);
542 mpLbFillAttr
->set_active(mpLbFillAttr
->get_count() - 1);
546 else if (mpBitmapItem
&& mpBitmapItem
->isPattern() && pSh
->GetItem(SID_PATTERN_LIST
))
548 mnLastXFS
= sal::static_int_cast
<sal_Int32
>(PATTERN
);
549 mpLbFillType
->set_active(mnLastXFS
);
551 SvxFillAttrBox::Fill(*mpLbFillAttr
, pSh
->GetItem(SID_PATTERN_LIST
)->GetPatternList());
552 const OUString
aString(mpBitmapItem
->GetName());
554 mpLbFillAttr
->set_active_text(aString
);
558 mpLbFillAttr
->set_active(-1);
563 mpLbFillAttr
->set_active(-1);
568 OSL_ENSURE(false, "Non supported FillType (!)");
574 VclPtr
<InterimItemWindow
> SvxFillToolBoxControl::CreateItemWindow(vcl::Window
*pParent
)
576 if(GetSlotId() == SID_ATTR_FILL_STYLE
)
578 mxFillControl
.reset(VclPtr
<FillControl
>::Create(pParent
, m_xFrame
));
580 mpLbFillType
= mxFillControl
->mxLbFillType
.get();
581 mpLbFillAttr
= mxFillControl
->mxLbFillAttr
.get();
582 mpToolBoxColor
= mxFillControl
->mxToolBoxColor
.get();
584 mpLbFillType
->connect_changed(LINK(this,SvxFillToolBoxControl
,SelectFillTypeHdl
));
585 mpLbFillAttr
->connect_changed(LINK(this,SvxFillToolBoxControl
,SelectFillAttrHdl
));
588 return mxFillControl
;
590 return VclPtr
<InterimItemWindow
>();
593 FillControl::FillControl(vcl::Window
* pParent
, const css::uno::Reference
<css::frame::XFrame
>& rFrame
)
594 : InterimItemWindow(pParent
, "svx/ui/fillctrlbox.ui", "FillCtrlBox")
595 , mxLbFillType(m_xBuilder
->weld_combo_box("type"))
596 , mxToolBoxColor(m_xBuilder
->weld_toolbar("color"))
597 , mxColorDispatch(new ToolbarUnoDispatcher(*mxToolBoxColor
, *m_xBuilder
, rFrame
))
598 , mxLbFillAttr(m_xBuilder
->weld_combo_box("attr"))
602 InitControlBase(mxLbFillType
.get());
604 mxLbFillAttr
->connect_key_press(LINK(this, FillControl
, AttrKeyInputHdl
));
605 mxLbFillType
->connect_key_press(LINK(this, FillControl
, TypeKeyInputHdl
));
606 mxToolBoxColor
->connect_key_press(LINK(this, FillControl
, ColorKeyInputHdl
));
608 mxLbFillType
->connect_get_property_tree(LINK(this, FillControl
, DumpAsPropertyTreeHdl
));
610 mxLbFillType
->connect_focus_in(LINK(this, FillControl
, TypeFocusHdl
));
611 mxLbFillAttr
->connect_focus_in(LINK(this, FillControl
, AttrFocusHdl
));
613 SvxFillTypeBox::Fill(*mxLbFillType
);
618 IMPL_STATIC_LINK(FillControl
, DumpAsPropertyTreeHdl
, tools::JsonWriter
&, rJsonWriter
, void)
620 rJsonWriter
.put("command", ".uno:FillStyle");
623 void FillControl::ReleaseFocus_Impl()
625 SfxViewShell
* pCurSh
= SfxViewShell::Current();
628 vcl::Window
* pShellWnd
= pCurSh
->GetWindow();
630 pShellWnd
->GrabFocus();
634 IMPL_LINK(FillControl
, TypeKeyInputHdl
, const KeyEvent
&, rKEvt
, bool)
636 const vcl::KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
637 sal_uInt16 nCode
= rKeyCode
.GetCode();
639 if (nCode
== KEY_ESCAPE
)
641 mxLbFillType
->set_active(mnTypeCurPos
);
646 if (nCode
!= KEY_TAB
)
648 if (rKeyCode
.IsShift())
649 return ChildKeyInput(rKEvt
);
650 if (mxLbFillAttr
->get_visible() && !mxLbFillAttr
->get_sensitive())
651 return ChildKeyInput(rKEvt
);
655 IMPL_LINK_NOARG(FillControl
, TypeFocusHdl
, weld::Widget
&, void)
657 mnTypeCurPos
= mxLbFillType
->get_active();
660 IMPL_LINK_NOARG(FillControl
, AttrFocusHdl
, weld::Widget
&, void)
662 mnAttrCurPos
= mxLbFillAttr
->get_active();
665 IMPL_LINK(FillControl
, AttrKeyInputHdl
, const KeyEvent
&, rKEvt
, bool)
667 const vcl::KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
668 sal_uInt16 nCode
= rKeyCode
.GetCode();
670 if (nCode
== KEY_ESCAPE
)
672 mxLbFillAttr
->set_active(mnAttrCurPos
);
677 return ChildKeyInput(rKEvt
);
680 IMPL_LINK(FillControl
, ColorKeyInputHdl
, const KeyEvent
&, rKEvt
, bool)
682 return ChildKeyInput(rKEvt
);
685 FillControl::~FillControl()
690 void FillControl::dispose()
692 mxLbFillAttr
.reset();
693 mxColorDispatch
.reset();
694 mxToolBoxColor
.reset();
695 mxLbFillType
.reset();
696 InterimItemWindow::dispose();
699 IMPL_LINK_NOARG(SvxFillToolBoxControl
, SelectFillTypeHdl
, weld::ComboBox
&, void)
701 sal_Int32 nXFS
= mpLbFillType
->get_active();
703 if(mnLastXFS
== nXFS
)
706 eFillStyle eXFS
= static_cast<eFillStyle
>(nXFS
);
707 mpLbFillAttr
->clear();
708 SfxObjectShell
* pSh
= SfxObjectShell::Current();
709 const XFillStyleItem
aXFillStyleItem(toCssFillStyle(eXFS
));
711 // #i122676# Do no longer trigger two Execute calls, one for SID_ATTR_FILL_STYLE
712 // and one for setting the fill attribute itself, but add two SfxPoolItems to the
713 // call to get just one action at the SdrObject and to create only one Undo action, too.
714 // Checked that this works in all apps.
720 mpLbFillAttr
->show();
721 mpToolBoxColor
->hide();
722 mpLbFillAttr
->set_sensitive(false);
725 // #i122676# need to call a single SID_ATTR_FILL_STYLE change
726 pSh
->GetDispatcher()->ExecuteList(
727 SID_ATTR_FILL_STYLE
, SfxCallMode::RECORD
,
728 { &aXFillStyleItem
});
734 mpLbFillAttr
->hide();
735 mpToolBoxColor
->show();
738 const ::Color aColor
= mpColorItem
? mpColorItem
->GetColorValue() : COL_AUTO
;
739 const XFillColorItem
aXFillColorItem( "", aColor
);
741 // #i122676# change FillStyle and Color in one call
742 pSh
->GetDispatcher()->ExecuteList(
743 SID_ATTR_FILL_COLOR
, SfxCallMode::RECORD
,
744 { &aXFillColorItem
, &aXFillStyleItem
});
750 mpLbFillAttr
->show();
751 mpToolBoxColor
->hide();
753 if(pSh
&& pSh
->GetItem(SID_GRADIENT_LIST
))
755 if(!mpLbFillAttr
->get_count())
757 mpLbFillAttr
->set_sensitive(true);
758 mpLbFillAttr
->clear();
759 SvxFillAttrBox::Fill(*mpLbFillAttr
, pSh
->GetItem(SID_GRADIENT_LIST
)->GetGradientList());
762 if (mnLastPosGradient
!= -1)
764 const SvxGradientListItem
* pItem
= pSh
->GetItem(SID_GRADIENT_LIST
);
766 if(mnLastPosGradient
< pItem
->GetGradientList()->Count())
768 const basegfx::BGradient aGradient
= pItem
->GetGradientList()->GetGradient(mnLastPosGradient
)->GetGradient();
769 const XFillGradientItem
aXFillGradientItem(mpLbFillAttr
->get_text(mnLastPosGradient
), aGradient
);
771 // #i122676# change FillStyle and Gradient in one call
772 pSh
->GetDispatcher()->ExecuteList(
773 SID_ATTR_FILL_GRADIENT
, SfxCallMode::RECORD
,
774 { &aXFillGradientItem
, &aXFillStyleItem
});
775 mpLbFillAttr
->set_active(mnLastPosGradient
);
781 mpLbFillAttr
->set_sensitive(false);
787 mpLbFillAttr
->show();
788 mpToolBoxColor
->hide();
790 if(pSh
&& pSh
->GetItem(SID_HATCH_LIST
))
792 if(!mpLbFillAttr
->get_count())
794 mpLbFillAttr
->set_sensitive(true);
795 mpLbFillAttr
->clear();
796 SvxFillAttrBox::Fill(*mpLbFillAttr
, pSh
->GetItem(SID_HATCH_LIST
)->GetHatchList());
799 if (mnLastPosHatch
!= -1)
801 const SvxHatchListItem
* pItem
= pSh
->GetItem(SID_HATCH_LIST
);
803 if(mnLastPosHatch
< pItem
->GetHatchList()->Count())
805 const XHatch aHatch
= pItem
->GetHatchList()->GetHatch(mnLastPosHatch
)->GetHatch();
806 const XFillHatchItem
aXFillHatchItem(mpLbFillAttr
->get_active_text(), aHatch
);
808 // #i122676# change FillStyle and Hatch in one call
809 pSh
->GetDispatcher()->ExecuteList(
810 SID_ATTR_FILL_HATCH
, SfxCallMode::RECORD
,
811 { &aXFillHatchItem
, &aXFillStyleItem
});
812 mpLbFillAttr
->set_active(mnLastPosHatch
);
818 mpLbFillAttr
->set_sensitive(false);
824 mpLbFillAttr
->show();
825 mpToolBoxColor
->hide();
827 if(pSh
&& pSh
->GetItem(SID_BITMAP_LIST
))
829 if(!mpLbFillAttr
->get_count())
831 mpLbFillAttr
->set_sensitive(true);
832 mpLbFillAttr
->clear();
833 SvxFillAttrBox::Fill(*mpLbFillAttr
, pSh
->GetItem(SID_BITMAP_LIST
)->GetBitmapList());
836 if (mnLastPosBitmap
!= -1)
838 const SvxBitmapListItem
* pItem
= pSh
->GetItem(SID_BITMAP_LIST
);
840 if(mnLastPosBitmap
< pItem
->GetBitmapList()->Count())
842 const XBitmapEntry
* pXBitmapEntry
= pItem
->GetBitmapList()->GetBitmap(mnLastPosBitmap
);
843 const XFillBitmapItem
aXFillBitmapItem(mpLbFillAttr
->get_active_text(), pXBitmapEntry
->GetGraphicObject());
845 // #i122676# change FillStyle and Bitmap in one call
846 pSh
->GetDispatcher()->ExecuteList(
847 SID_ATTR_FILL_BITMAP
, SfxCallMode::RECORD
,
848 { &aXFillBitmapItem
, &aXFillStyleItem
});
849 mpLbFillAttr
->set_active(mnLastPosBitmap
);
855 mpLbFillAttr
->set_sensitive(false);
861 mpLbFillAttr
->show();
862 mpToolBoxColor
->hide();
864 if(pSh
&& pSh
->GetItem(SID_PATTERN_LIST
))
866 if(!mpLbFillAttr
->get_count())
868 mpLbFillAttr
->set_sensitive(true);
869 mpLbFillAttr
->clear();
870 SvxFillAttrBox::Fill(*mpLbFillAttr
, pSh
->GetItem(SID_PATTERN_LIST
)->GetPatternList());
873 if (mnLastPosPattern
!= -1)
875 const SvxPatternListItem
* pItem
= pSh
->GetItem(SID_PATTERN_LIST
);
877 if(mnLastPosPattern
< pItem
->GetPatternList()->Count())
879 const XBitmapEntry
* pXBitmapEntry
= pItem
->GetPatternList()->GetBitmap(mnLastPosPattern
);
880 const XFillBitmapItem
aXFillBitmapItem(mpLbFillAttr
->get_active_text(), pXBitmapEntry
->GetGraphicObject());
882 // #i122676# change FillStyle and Bitmap in one call
883 pSh
->GetDispatcher()->ExecuteList(
884 SID_ATTR_FILL_BITMAP
, SfxCallMode::RECORD
,
885 { &aXFillBitmapItem
, &aXFillStyleItem
});
886 mpLbFillAttr
->set_active(mnLastPosPattern
);
892 mpLbFillAttr
->set_sensitive(false);
901 mxFillControl
->Resize();
904 IMPL_LINK_NOARG(SvxFillToolBoxControl
, SelectFillAttrHdl
, weld::ComboBox
&, void)
906 sal_Int32 nXFS
= mpLbFillType
->get_active();
907 eFillStyle eXFS
= static_cast<eFillStyle
>(nXFS
);
909 const XFillStyleItem
aXFillStyleItem(toCssFillStyle(eXFS
));
910 SfxObjectShell
* pSh
= SfxObjectShell::Current();
912 // #i122676# dependent from bFillStyleChange, do execute a single or two
913 // changes in one Execute call
914 const bool bFillStyleChange(mnLastXFS
!= nXFS
);
920 if (bFillStyleChange
&& pSh
)
922 // #i122676# Single FillStyle change call needed here
923 pSh
->GetDispatcher()->ExecuteList(
924 SID_ATTR_FILL_STYLE
, SfxCallMode::RECORD
,
925 { &aXFillStyleItem
});
931 sal_Int32 nPos
= mpLbFillAttr
->get_active();
935 nPos
= mnLastPosGradient
;
938 if (nPos
!= -1 && pSh
&& pSh
->GetItem(SID_GRADIENT_LIST
))
940 const SvxGradientListItem
* pItem
= pSh
->GetItem(SID_GRADIENT_LIST
);
942 if(nPos
< pItem
->GetGradientList()->Count())
944 const basegfx::BGradient aGradient
= pItem
->GetGradientList()->GetGradient(nPos
)->GetGradient();
945 const XFillGradientItem
aXFillGradientItem(mpLbFillAttr
->get_active_text(), aGradient
);
947 // #i122676# Change FillStyle and Gradient in one call
948 pSh
->GetDispatcher()->ExecuteList(
949 SID_ATTR_FILL_GRADIENT
, SfxCallMode::RECORD
,
951 ? std::initializer_list
<SfxPoolItem
const*>{ &aXFillGradientItem
, &aXFillStyleItem
}
952 : std::initializer_list
<SfxPoolItem
const*>{ &aXFillGradientItem
});
958 mnLastPosGradient
= nPos
;
964 sal_Int32 nPos
= mpLbFillAttr
->get_active();
968 nPos
= mnLastPosHatch
;
971 if (nPos
!= -1 && pSh
&& pSh
->GetItem(SID_HATCH_LIST
))
973 const SvxHatchListItem
* pItem
= pSh
->GetItem(SID_HATCH_LIST
);
975 if(nPos
< pItem
->GetHatchList()->Count())
977 const XHatch aHatch
= pItem
->GetHatchList()->GetHatch(nPos
)->GetHatch();
978 const XFillHatchItem
aXFillHatchItem( mpLbFillAttr
->get_active_text(), aHatch
);
980 // #i122676# Change FillStyle and Hatch in one call
981 pSh
->GetDispatcher()->ExecuteList(
982 SID_ATTR_FILL_HATCH
, SfxCallMode::RECORD
,
984 ? std::initializer_list
<SfxPoolItem
const*>{ &aXFillHatchItem
, &aXFillStyleItem
}
985 : std::initializer_list
<SfxPoolItem
const*>{ &aXFillHatchItem
});
991 mnLastPosHatch
= nPos
;
997 sal_Int32 nPos
= mpLbFillAttr
->get_active();
1001 nPos
= mnLastPosBitmap
;
1004 if (nPos
!= -1 && pSh
&& pSh
->GetItem(SID_BITMAP_LIST
))
1006 const SvxBitmapListItem
* pItem
= pSh
->GetItem(SID_BITMAP_LIST
);
1008 if(nPos
< pItem
->GetBitmapList()->Count())
1010 const XBitmapEntry
* pXBitmapEntry
= pItem
->GetBitmapList()->GetBitmap(nPos
);
1011 const XFillBitmapItem
aXFillBitmapItem(mpLbFillAttr
->get_active_text(), pXBitmapEntry
->GetGraphicObject());
1013 // #i122676# Change FillStyle and Bitmap in one call
1014 pSh
->GetDispatcher()->ExecuteList(
1015 SID_ATTR_FILL_BITMAP
, SfxCallMode::RECORD
,
1017 ? std::initializer_list
<SfxPoolItem
const*>{ &aXFillBitmapItem
, &aXFillStyleItem
}
1018 : std::initializer_list
<SfxPoolItem
const*>{ &aXFillBitmapItem
});
1024 mnLastPosBitmap
= nPos
;
1030 sal_Int32 nPos
= mpLbFillAttr
->get_active();
1034 nPos
= mnLastPosPattern
;
1037 if (nPos
!= -1 && pSh
&& pSh
->GetItem(SID_PATTERN_LIST
))
1039 const SvxPatternListItem
* pItem
= pSh
->GetItem(SID_PATTERN_LIST
);
1041 if(nPos
< pItem
->GetPatternList()->Count())
1043 const XBitmapEntry
* pXBitmapEntry
= pItem
->GetPatternList()->GetBitmap(nPos
);
1044 const XFillBitmapItem
aXFillBitmapItem(mpLbFillAttr
->get_active_text(), pXBitmapEntry
->GetGraphicObject());
1046 // #i122676# Change FillStyle and Bitmap in one call
1047 pSh
->GetDispatcher()->ExecuteList(
1048 SID_ATTR_FILL_BITMAP
, SfxCallMode::RECORD
,
1050 ? std::initializer_list
<SfxPoolItem
const*>{ &aXFillBitmapItem
, &aXFillStyleItem
}
1051 : std::initializer_list
<SfxPoolItem
const*>{ &aXFillBitmapItem
});
1057 mnLastPosPattern
= nPos
;
1066 void FillControl::SetOptimalSize()
1068 Size
aSize(mxLbFillType
->get_preferred_size());
1069 Size
aFirstSize(mxToolBoxColor
->get_preferred_size());
1070 auto nWidth
= std::max(aFirstSize
.Width(), LogicToPixel(Size(55, 0), MapMode(MapUnit::MapAppFont
)).Width());
1071 auto nHeight
= std::max(aSize
.Height(), aFirstSize
.Height());
1072 mxToolBoxColor
->set_size_request(nWidth
, -1);
1073 mxLbFillAttr
->set_size_request(42, -1); //something narrow so the toolbar sets the overall size of this column
1074 SetSizePixel(Size(m_xContainer
->get_preferred_size().Width(), nHeight
));
1077 void FillControl::DataChanged(const DataChangedEvent
& rDCEvt
)
1079 if((rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
1080 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
))
1084 InterimItemWindow::DataChanged(rDCEvt
);
1087 void FillControl::GetFocus()
1089 // tdf#148047 if the dropdown is active then leave the focus
1090 // there and don't grab back to a different widget
1091 if (mxToolBoxColor
->get_menu_item_active(".uno:FillColor"))
1093 InterimItemWindow::GetFocus();
1096 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */