Version 7.1.7.1, tag libreoffice-7.1.7.1
[LibreOffice.git] / svx / source / tbxctrls / fillctrl.cxx
blobe327be070b1673f53a277b82902fa2e353b36a88
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/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>
32 #define TMP_STR_BEGIN "["
33 #define TMP_STR_END "]"
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>
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;
53 SFX_IMPL_TOOLBOX_CONTROL( SvxFillToolBoxControl, XFillStyleItem );
55 SvxFillToolBoxControl::SvxFillToolBoxControl(
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)
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");
84 SvxFillToolBoxControl::~SvxFillToolBoxControl()
88 void SvxFillToolBoxControl::StateChanged(
89 sal_uInt16 nSID,
90 SfxItemState eState,
91 const SfxPoolItem* pState)
93 const bool bDisabled(SfxItemState::DISABLED == eState);
95 switch(nSID)
97 case SID_ATTR_FILL_STYLE:
99 if(bDisabled)
101 mpLbFillType->set_sensitive(false);
102 mpLbFillType->set_active(-1);
103 mpLbFillAttr->show();
104 mpLbFillAttr->set_sensitive(false);
105 mpLbFillAttr->set_active(-1);
106 mpToolBoxColor->hide();
107 meLastXFS = static_cast<drawing::FillStyle>(-1);
108 mpStyleItem.reset();
111 if(eState >= SfxItemState::DEFAULT)
113 const XFillStyleItem* pItem = dynamic_cast< const XFillStyleItem* >(pState);
115 if(pItem)
117 mpStyleItem.reset(pItem->Clone());
118 mpLbFillType->set_sensitive(true);
119 drawing::FillStyle eXFS = mpStyleItem->GetValue();
120 meLastXFS = eXFS;
121 mpLbFillType->set_active(sal::static_int_cast< sal_Int32 >(eXFS));
123 if(drawing::FillStyle_NONE == eXFS)
125 mpLbFillAttr->set_active(-1);
126 mpLbFillAttr->set_sensitive(false);
129 Update();
130 break;
134 mpLbFillType->set_active(-1);
135 mpLbFillAttr->show();
136 mpLbFillAttr->set_sensitive(false);
137 mpLbFillAttr->set_active(-1);
138 mpToolBoxColor->hide();
139 meLastXFS = static_cast<drawing::FillStyle>(-1);
140 mpStyleItem.reset();
141 mxFillControl->Resize();
142 break;
144 case SID_ATTR_FILL_COLOR:
146 if(SfxItemState::DEFAULT == eState)
148 mpColorItem.reset(pState ? static_cast<XFillColorItem*>(pState->Clone()) : nullptr);
151 if(mpStyleItem && drawing::FillStyle_SOLID == mpStyleItem->GetValue())
153 mpLbFillAttr->hide();
154 mpToolBoxColor->show();
155 mxFillControl->Resize();
157 Update();
159 break;
161 case SID_ATTR_FILL_GRADIENT:
163 if(SfxItemState::DEFAULT == eState)
165 mpFillGradientItem.reset(pState ? static_cast<XFillGradientItem*>(pState->Clone()) : nullptr);
168 if(mpStyleItem && drawing::FillStyle_GRADIENT == mpStyleItem->GetValue())
170 mpLbFillAttr->show();
171 mpToolBoxColor->hide();
172 mxFillControl->Resize();
174 if(SfxItemState::DEFAULT == eState)
176 mpLbFillAttr->set_sensitive(true);
177 Update();
179 else if(SfxItemState::DISABLED == eState )
181 mpLbFillAttr->set_sensitive(false);
182 mpLbFillAttr->set_active(-1);
184 else
186 mpLbFillAttr->set_active(-1);
189 break;
191 case SID_ATTR_FILL_HATCH:
193 if(SfxItemState::DEFAULT == eState)
195 mpHatchItem.reset(pState ? static_cast<XFillHatchItem*>(pState->Clone()) : nullptr);
198 if(mpStyleItem && drawing::FillStyle_HATCH == mpStyleItem->GetValue())
200 mpLbFillAttr->show();
201 mpToolBoxColor->hide();
202 mxFillControl->Resize();
204 if(SfxItemState::DEFAULT == eState)
206 mpLbFillAttr->set_sensitive(true);
207 Update();
209 else if(SfxItemState::DISABLED == eState )
211 mpLbFillAttr->set_sensitive(false);
212 mpLbFillAttr->set_active(-1);
214 else
216 mpLbFillAttr->set_active(-1);
219 break;
221 case SID_ATTR_FILL_BITMAP:
223 if(SfxItemState::DEFAULT == eState)
225 mpBitmapItem.reset(pState ? static_cast<XFillBitmapItem*>(pState->Clone()) : nullptr);
228 if(mpStyleItem && drawing::FillStyle_BITMAP == mpStyleItem->GetValue())
230 mpLbFillAttr->show();
231 mpToolBoxColor->hide();
232 mxFillControl->Resize();
234 if(SfxItemState::DEFAULT == eState)
236 mpLbFillAttr->set_sensitive(true);
237 Update();
239 else if(SfxItemState::DISABLED == eState )
241 mpLbFillAttr->set_sensitive(false);
242 mpLbFillAttr->set_active(-1);
244 else
246 mpLbFillAttr->set_active(-1);
249 break;
251 case SID_GRADIENT_LIST:
253 if(SfxItemState::DEFAULT == eState)
255 if(mpStyleItem && drawing::FillStyle_GRADIENT == mpStyleItem->GetValue())
257 if(mpFillGradientItem)
259 const OUString aString( mpFillGradientItem->GetName() );
260 const SfxObjectShell* pSh = SfxObjectShell::Current();
262 mpLbFillAttr->clear();
263 mpLbFillAttr->set_sensitive(true);
264 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
265 mpLbFillAttr->set_active_text(aString);
267 else
269 mpLbFillAttr->set_active(-1);
273 break;
275 case SID_HATCH_LIST:
277 if(SfxItemState::DEFAULT == eState)
279 if(mpStyleItem && drawing::FillStyle_HATCH == mpStyleItem->GetValue())
281 if(mpHatchItem)
283 const OUString aString( mpHatchItem->GetName() );
284 const SfxObjectShell* pSh = SfxObjectShell::Current();
286 mpLbFillAttr->clear();
287 mpLbFillAttr->set_sensitive(true);
288 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
289 mpLbFillAttr->set_active_text(aString);
291 else
293 mpLbFillAttr->set_active(-1);
297 break;
299 case SID_BITMAP_LIST:
301 if(SfxItemState::DEFAULT == eState)
303 if(mpStyleItem && drawing::FillStyle_BITMAP == mpStyleItem->GetValue())
305 if(mpBitmapItem)
307 const OUString aString( mpBitmapItem->GetName() );
308 const SfxObjectShell* pSh = SfxObjectShell::Current();
310 mpLbFillAttr->clear();
311 mpLbFillAttr->set_sensitive(true);
312 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
313 mpLbFillAttr->set_active_text(aString);
315 else
317 mpLbFillAttr->set_active(-1);
321 break;
326 void SvxFillToolBoxControl::Update()
328 if(!mpStyleItem)
329 return;
331 const drawing::FillStyle eXFS = mpStyleItem->GetValue();
332 SfxObjectShell* pSh = SfxObjectShell::Current();
334 switch( eXFS )
336 case drawing::FillStyle_NONE:
338 mpLbFillAttr->show();
339 mpToolBoxColor->hide();
340 mxFillControl->Resize();
341 break;
343 case drawing::FillStyle_SOLID:
345 if(mpColorItem)
347 mpLbFillAttr->hide();
348 mpToolBoxColor->show();
349 mxFillControl->Resize();
351 break;
353 case drawing::FillStyle_GRADIENT:
355 mpLbFillAttr->show();
356 mpToolBoxColor->hide();
357 mxFillControl->Resize();
359 if(pSh && pSh->GetItem(SID_GRADIENT_LIST))
361 mpLbFillAttr->set_sensitive(true);
362 mpLbFillAttr->clear();
363 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
365 if(mpFillGradientItem)
367 const OUString aString(mpFillGradientItem->GetName());
369 mpLbFillAttr->set_active_text(aString);
371 // Check if the entry is not in the list
372 if (mpLbFillAttr->get_active_text() != aString)
374 sal_Int32 nCount = mpLbFillAttr->get_count();
375 OUString aTmpStr;
376 if( nCount > 0 )
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) )
383 mpLbFillAttr->remove(nCount - 1);
386 aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
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 );
393 if (!aBmp.IsEmpty())
395 ScopedVclPtrInstance< VirtualDevice > pVD;
396 const Size aBmpSize(aBmp.GetSizePixel());
397 pVD->SetOutputSizePixel(aBmpSize, false);
398 pVD->DrawBitmapEx(Point(), aBmp);
399 mpLbFillAttr->append("", aGradientList.Get(0)->GetName(), *pVD);
400 mpLbFillAttr->set_active(mpLbFillAttr->get_count() - 1);
405 else
407 mpLbFillAttr->set_active(-1);
410 else
412 mpLbFillAttr->set_active(-1);
414 break;
416 case drawing::FillStyle_HATCH:
418 mpLbFillAttr->show();
419 mpToolBoxColor->hide();
420 mxFillControl->Resize();
422 if(pSh && pSh->GetItem(SID_HATCH_LIST))
424 mpLbFillAttr->set_sensitive(true);
425 mpLbFillAttr->clear();
426 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
428 if(mpHatchItem)
430 const OUString aString(mpHatchItem->GetName());
432 mpLbFillAttr->set_active_text( aString );
434 // Check if the entry is not in the list
435 if( mpLbFillAttr->get_active_text() != aString )
437 const sal_Int32 nCount = mpLbFillAttr->get_count();
438 OUString aTmpStr;
439 if( nCount > 0 )
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) )
446 mpLbFillAttr->remove( nCount - 1 );
449 aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
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 );
456 if( !aBmp.IsEmpty() )
458 ScopedVclPtrInstance< VirtualDevice > pVD;
459 const Size aBmpSize(aBmp.GetSizePixel());
460 pVD->SetOutputSizePixel(aBmpSize, false);
461 pVD->DrawBitmapEx(Point(), aBmp);
462 mpLbFillAttr->append("", aHatchList.GetHatch(0)->GetName(), *pVD);
463 mpLbFillAttr->set_active(mpLbFillAttr->get_count() - 1);
467 else
469 mpLbFillAttr->set_active(-1);
472 else
474 mpLbFillAttr->set_active(-1);
476 break;
478 case drawing::FillStyle_BITMAP:
480 mpLbFillAttr->show();
481 mpToolBoxColor->hide();
482 mxFillControl->Resize();
484 if(pSh && pSh->GetItem(SID_BITMAP_LIST))
486 mpLbFillAttr->set_sensitive(true);
487 mpLbFillAttr->clear();
488 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
490 if(mpBitmapItem)
492 const OUString aString(mpBitmapItem->GetName());
494 mpLbFillAttr->set_active_text(aString);
496 // Check if the entry is not in the list
497 if (mpLbFillAttr->get_active_text() != aString)
499 sal_Int32 nCount = mpLbFillAttr->get_count();
500 OUString aTmpStr;
501 if( nCount > 0 )
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) )
508 mpLbFillAttr->remove(nCount - 1);
511 aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
513 XBitmapListRef xBitmapList =
514 XPropertyList::AsBitmapList(
515 XPropertyList::CreatePropertyList(
516 XPropertyListType::Bitmap, "TmpList", ""/*TODO?*/));
517 xBitmapList->Insert(std::make_unique<XBitmapEntry>(mpBitmapItem->GetGraphicObject(), aTmpStr));
518 xBitmapList->SetDirty( false );
519 SvxFillAttrBox::Fill(*mpLbFillAttr, xBitmapList);
520 mpLbFillAttr->set_active(mpLbFillAttr->get_count() - 1);
524 else
526 mpLbFillAttr->set_active(-1);
529 else
531 mpLbFillAttr->set_active(-1);
533 break;
535 default:
536 OSL_ENSURE(false, "Non supported FillType (!)");
537 break;
542 VclPtr<InterimItemWindow> SvxFillToolBoxControl::CreateItemWindow(vcl::Window *pParent)
544 if(GetSlotId() == SID_ATTR_FILL_STYLE)
546 mxFillControl.reset(VclPtr<FillControl>::Create(pParent, m_xFrame));
548 mpLbFillType = mxFillControl->mxLbFillType.get();
549 mpLbFillAttr = mxFillControl->mxLbFillAttr.get();
550 mpToolBoxColor = mxFillControl->mxToolBoxColor.get();
552 mpLbFillType->connect_changed(LINK(this,SvxFillToolBoxControl,SelectFillTypeHdl));
553 mpLbFillAttr->connect_changed(LINK(this,SvxFillToolBoxControl,SelectFillAttrHdl));
556 return mxFillControl;
558 return VclPtr<InterimItemWindow>();
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)
570 InitControlBase(mxLbFillType.get());
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));
576 mxLbFillType->connect_get_property_tree(LINK(this, FillControl, DumpAsPropertyTreeHdl));
578 mxLbFillType->connect_focus_in(LINK(this, FillControl, TypeFocusHdl));
579 mxLbFillAttr->connect_focus_in(LINK(this, FillControl, AttrFocusHdl));
581 SvxFillTypeBox::Fill(*mxLbFillType);
583 SetOptimalSize();
586 IMPL_STATIC_LINK(FillControl, DumpAsPropertyTreeHdl, tools::JsonWriter&, rJsonWriter, void)
588 rJsonWriter.put("command", ".uno:FillStyle");
591 void FillControl::ReleaseFocus_Impl()
593 SfxViewShell* pCurSh = SfxViewShell::Current();
594 if (pCurSh)
596 vcl::Window* pShellWnd = pCurSh->GetWindow();
597 if (pShellWnd)
598 pShellWnd->GrabFocus();
602 IMPL_LINK(FillControl, TypeKeyInputHdl, const KeyEvent&, rKEvt, bool)
604 const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
605 sal_uInt16 nCode = rKeyCode.GetCode();
607 if (nCode == KEY_ESCAPE)
609 mxLbFillType->set_active(mnTypeCurPos);
610 ReleaseFocus_Impl();
611 return true;
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;
623 IMPL_LINK_NOARG(FillControl, TypeFocusHdl, weld::Widget&, void)
625 mnTypeCurPos = mxLbFillType->get_active();
628 IMPL_LINK_NOARG(FillControl, AttrFocusHdl, weld::Widget&, void)
630 mnAttrCurPos = mxLbFillAttr->get_active();
633 IMPL_LINK(FillControl, AttrKeyInputHdl, const KeyEvent&, rKEvt, bool)
635 const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
636 sal_uInt16 nCode = rKeyCode.GetCode();
638 if (nCode == KEY_ESCAPE)
640 mxLbFillAttr->set_active(mnAttrCurPos);
641 ReleaseFocus_Impl();
642 return true;
645 return ChildKeyInput(rKEvt);
648 IMPL_LINK(FillControl, ColorKeyInputHdl, const KeyEvent&, rKEvt, bool)
650 return ChildKeyInput(rKEvt);
653 FillControl::~FillControl()
655 disposeOnce();
658 void FillControl::dispose()
660 mxLbFillAttr.reset();
661 mxColorDispatch.reset();
662 mxToolBoxColor.reset();
663 mxLbFillType.reset();
664 InterimItemWindow::dispose();
667 IMPL_LINK_NOARG(SvxFillToolBoxControl, SelectFillTypeHdl, weld::ComboBox&, void)
669 const drawing::FillStyle eXFS = static_cast<drawing::FillStyle>(mpLbFillType->get_active());
671 if(meLastXFS == eXFS)
672 return;
674 mpLbFillAttr->clear();
675 SfxObjectShell* pSh = SfxObjectShell::Current();
676 const XFillStyleItem aXFillStyleItem(eXFS);
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 )
684 default:
685 case drawing::FillStyle_NONE:
687 mpLbFillAttr->show();
688 mpToolBoxColor->hide();
689 mpLbFillAttr->set_sensitive(false);
690 if (pSh)
692 // #i122676# need to call a single SID_ATTR_FILL_STYLE change
693 pSh->GetDispatcher()->ExecuteList(
694 SID_ATTR_FILL_STYLE, SfxCallMode::RECORD,
695 { &aXFillStyleItem });
697 break;
699 case drawing::FillStyle_SOLID:
701 mpLbFillAttr->hide();
702 mpToolBoxColor->show();
703 if (pSh)
705 const ::Color aColor = mpColorItem ? mpColorItem->GetColorValue() : COL_AUTO;
706 const XFillColorItem aXFillColorItem( "", aColor );
708 // #i122676# change FillStyle and Color in one call
709 pSh->GetDispatcher()->ExecuteList(
710 SID_ATTR_FILL_COLOR, SfxCallMode::RECORD,
711 { &aXFillColorItem, &aXFillStyleItem });
713 break;
715 case drawing::FillStyle_GRADIENT:
717 mpLbFillAttr->show();
718 mpToolBoxColor->hide();
720 if(pSh && pSh->GetItem(SID_GRADIENT_LIST))
722 if(!mpLbFillAttr->get_count())
724 mpLbFillAttr->set_sensitive(true);
725 mpLbFillAttr->clear();
726 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
729 if (mnLastPosGradient != -1)
731 const SvxGradientListItem * pItem = pSh->GetItem(SID_GRADIENT_LIST);
733 if(mnLastPosGradient < pItem->GetGradientList()->Count())
735 const XGradient aGradient = pItem->GetGradientList()->GetGradient(mnLastPosGradient)->GetGradient();
736 const XFillGradientItem aXFillGradientItem(mpLbFillAttr->get_text(mnLastPosGradient), aGradient);
738 // #i122676# change FillStyle and Gradient in one call
739 pSh->GetDispatcher()->ExecuteList(
740 SID_ATTR_FILL_GRADIENT, SfxCallMode::RECORD,
741 { &aXFillGradientItem, &aXFillStyleItem });
742 mpLbFillAttr->set_active(mnLastPosGradient);
746 else
748 mpLbFillAttr->set_sensitive(false);
750 break;
752 case drawing::FillStyle_HATCH:
754 mpLbFillAttr->show();
755 mpToolBoxColor->hide();
757 if(pSh && pSh->GetItem(SID_HATCH_LIST))
759 if(!mpLbFillAttr->get_count())
761 mpLbFillAttr->set_sensitive(true);
762 mpLbFillAttr->clear();
763 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
766 if (mnLastPosHatch != -1)
768 const SvxHatchListItem * pItem = pSh->GetItem(SID_HATCH_LIST);
770 if(mnLastPosHatch < pItem->GetHatchList()->Count())
772 const XHatch aHatch = pItem->GetHatchList()->GetHatch(mnLastPosHatch)->GetHatch();
773 const XFillHatchItem aXFillHatchItem(mpLbFillAttr->get_active_text(), aHatch);
775 // #i122676# change FillStyle and Hatch in one call
776 pSh->GetDispatcher()->ExecuteList(
777 SID_ATTR_FILL_HATCH, SfxCallMode::RECORD,
778 { &aXFillHatchItem, &aXFillStyleItem });
779 mpLbFillAttr->set_active(mnLastPosHatch);
783 else
785 mpLbFillAttr->set_sensitive(false);
787 break;
789 case drawing::FillStyle_BITMAP:
791 mpLbFillAttr->show();
792 mpToolBoxColor->hide();
794 if(pSh && pSh->GetItem(SID_BITMAP_LIST))
796 if(!mpLbFillAttr->get_count())
798 mpLbFillAttr->set_sensitive(true);
799 mpLbFillAttr->clear();
800 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
803 if (mnLastPosBitmap != -1)
805 const SvxBitmapListItem * pItem = pSh->GetItem(SID_BITMAP_LIST);
807 if(mnLastPosBitmap < pItem->GetBitmapList()->Count())
809 const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(mnLastPosBitmap);
810 const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
812 // #i122676# change FillStyle and Bitmap in one call
813 pSh->GetDispatcher()->ExecuteList(
814 SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
815 { &aXFillBitmapItem, &aXFillStyleItem });
816 mpLbFillAttr->set_active(mnLastPosBitmap);
820 else
822 mpLbFillAttr->set_sensitive(false);
824 break;
828 meLastXFS = eXFS;
830 mxFillControl->Resize();
833 IMPL_LINK_NOARG(SvxFillToolBoxControl, SelectFillAttrHdl, weld::ComboBox&, void)
835 const drawing::FillStyle eXFS = static_cast<drawing::FillStyle>(mpLbFillType->get_active());
836 const XFillStyleItem aXFillStyleItem(eXFS);
837 SfxObjectShell* pSh = SfxObjectShell::Current();
839 // #i122676# dependent from bFillStyleChange, do execute a single or two
840 // changes in one Execute call
841 const bool bFillStyleChange(meLastXFS != eXFS);
843 switch(eXFS)
845 case drawing::FillStyle_SOLID:
847 if (bFillStyleChange && pSh)
849 // #i122676# Single FillStyle change call needed here
850 pSh->GetDispatcher()->ExecuteList(
851 SID_ATTR_FILL_STYLE, SfxCallMode::RECORD,
852 { &aXFillStyleItem });
854 break;
856 case drawing::FillStyle_GRADIENT:
858 sal_Int32 nPos = mpLbFillAttr->get_active();
860 if (nPos == -1)
862 nPos = mnLastPosGradient;
865 if (nPos != -1 && pSh && pSh->GetItem(SID_GRADIENT_LIST))
867 const SvxGradientListItem * pItem = pSh->GetItem(SID_GRADIENT_LIST);
869 if(nPos < pItem->GetGradientList()->Count())
871 const XGradient aGradient = pItem->GetGradientList()->GetGradient(nPos)->GetGradient();
872 const XFillGradientItem aXFillGradientItem(mpLbFillAttr->get_active_text(), aGradient);
874 // #i122676# Change FillStyle and Gradient in one call
875 pSh->GetDispatcher()->ExecuteList(
876 SID_ATTR_FILL_GRADIENT, SfxCallMode::RECORD,
877 bFillStyleChange
878 ? std::initializer_list<SfxPoolItem const*>{ &aXFillGradientItem, &aXFillStyleItem }
879 : std::initializer_list<SfxPoolItem const*>{ &aXFillGradientItem });
883 if (nPos != -1)
885 mnLastPosGradient = nPos;
887 break;
889 case drawing::FillStyle_HATCH:
891 sal_Int32 nPos = mpLbFillAttr->get_active();
893 if (nPos == -1)
895 nPos = mnLastPosHatch;
898 if (nPos != -1 && pSh && pSh->GetItem(SID_HATCH_LIST))
900 const SvxHatchListItem * pItem = pSh->GetItem(SID_HATCH_LIST);
902 if(nPos < pItem->GetHatchList()->Count())
904 const XHatch aHatch = pItem->GetHatchList()->GetHatch(nPos)->GetHatch();
905 const XFillHatchItem aXFillHatchItem( mpLbFillAttr->get_active_text(), aHatch);
907 // #i122676# Change FillStyle and Hatch in one call
908 pSh->GetDispatcher()->ExecuteList(
909 SID_ATTR_FILL_HATCH, SfxCallMode::RECORD,
910 bFillStyleChange
911 ? std::initializer_list<SfxPoolItem const*>{ &aXFillHatchItem, &aXFillStyleItem }
912 : std::initializer_list<SfxPoolItem const*>{ &aXFillHatchItem });
916 if (nPos != -1)
918 mnLastPosHatch = nPos;
920 break;
922 case drawing::FillStyle_BITMAP:
924 sal_Int32 nPos = mpLbFillAttr->get_active();
926 if (nPos == -1)
928 nPos = mnLastPosBitmap;
931 if (nPos != -1 && pSh && pSh->GetItem(SID_BITMAP_LIST))
933 const SvxBitmapListItem * pItem = pSh->GetItem(SID_BITMAP_LIST);
935 if(nPos < pItem->GetBitmapList()->Count())
937 const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(nPos);
938 const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
940 // #i122676# Change FillStyle and Bitmap in one call
941 pSh->GetDispatcher()->ExecuteList(
942 SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
943 bFillStyleChange
944 ? std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem, &aXFillStyleItem }
945 : std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem });
949 if (nPos != -1)
951 mnLastPosBitmap = nPos;
953 break;
955 default: break;
959 void FillControl::SetOptimalSize()
961 Size aSize(mxLbFillType->get_preferred_size());
962 Size aFirstSize(mxToolBoxColor->get_preferred_size());
963 auto nWidth = std::max(aFirstSize.Width(), LogicToPixel(Size(55, 0), MapMode(MapUnit::MapAppFont)).Width());
964 auto nHeight = std::max(aSize.Height(), aFirstSize.Height());
965 mxToolBoxColor->set_size_request(nWidth, -1);
966 mxLbFillAttr->set_size_request(42, -1); //something narrow so the toolbar sets the overall size of this column
967 SetSizePixel(Size(m_xContainer->get_preferred_size().Width(), nHeight));
970 void FillControl::DataChanged(const DataChangedEvent& rDCEvt)
972 if((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
973 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
975 SetOptimalSize();
977 InterimItemWindow::DataChanged(rDCEvt);
980 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */