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/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>
30
31constexpr OUStringLiteral TMP_STR_BEGIN = u"[";
32constexpr OUStringLiteral TMP_STR_END = u"]";
33
34#include <svx/drawitem.hxx>
35#include <svx/xfillit0.hxx>
36#include <svx/xtable.hxx>
37#include <svx/fillctrl.hxx>
38#include <svx/itemwin.hxx>
39#include <svx/xflclit.hxx>
40#include <svx/xflgrit.hxx>
41#include <svx/xflhtit.hxx>
42#include <svx/xbtmpit.hxx>
43#include <memory>
44
45using namespace ::com::sun::star;
46using namespace ::com::sun::star::uno;
47using namespace ::com::sun::star::util;
48using namespace ::com::sun::star::beans;
49using namespace ::com::sun::star::lang;
50
51namespace {
52
53enum eFillStyle
54{
55 NONE,
56 SOLID,
58 HATCH,
59 BITMAP,
61};
62
63drawing::FillStyle toCssFillStyle( eFillStyle eXFS )
64{
65 if (eXFS == PATTERN)
66 {
67 return drawing::FillStyle_BITMAP;
68 }
69
70 return static_cast<drawing::FillStyle>(eXFS);
71}
72
73}
74
76
78 sal_uInt16 nSlotId,
79 ToolBoxItemId nId,
80 ToolBox& rTbx )
81 : SfxToolBoxControl( nSlotId, nId, rTbx )
82 , mxFillControl(nullptr)
83 , mpLbFillType(nullptr)
84 , mpToolBoxColor(nullptr)
85 , mpLbFillAttr(nullptr)
86 , mnLastXFS(-1)
87 , mnLastPosGradient(0)
88 , mnLastPosHatch(0)
89 , mnLastPosBitmap(0)
90 , mnLastPosPattern(0)
91{
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");
100}
101
103{
104}
105
107 sal_uInt16 nSID,
108 SfxItemState eState,
109 const SfxPoolItem* pState)
110{
111 const bool bDisabled(SfxItemState::DISABLED == eState);
112
113 switch(nSID)
114 {
115 case SID_ATTR_FILL_STYLE:
116 {
117 if(bDisabled)
118 {
125 mnLastXFS = -1;
126 mpStyleItem.reset();
127 }
128
129 if(eState >= SfxItemState::DEFAULT)
130 {
131 const XFillStyleItem* pItem = dynamic_cast< const XFillStyleItem* >(pState);
132
133 if(pItem)
134 {
135 mpStyleItem.reset(pItem->Clone());
137 drawing::FillStyle eXFS = mpStyleItem->GetValue();
138 mnLastXFS = sal::static_int_cast< sal_Int32 >(eXFS);
140
141 if(drawing::FillStyle_NONE == eXFS)
142 {
145 }
146
147 Update();
148 break;
149 }
150 }
151
157 mnLastXFS = -1;
158 mpStyleItem.reset();
159 mxFillControl->Resize();
160 break;
161 }
162 case SID_ATTR_FILL_COLOR:
163 {
164 if(SfxItemState::DEFAULT == eState)
165 {
166 mpColorItem.reset(pState ? static_cast<XFillColorItem*>(pState->Clone()) : nullptr);
167 }
168
169 if(mpStyleItem && drawing::FillStyle_SOLID == mpStyleItem->GetValue())
170 {
173 mxFillControl->Resize();
174
175 Update();
176 }
177 break;
178 }
179 case SID_ATTR_FILL_GRADIENT:
180 {
181 if(SfxItemState::DEFAULT == eState)
182 {
183 mpFillGradientItem.reset(pState ? static_cast<XFillGradientItem*>(pState->Clone()) : nullptr);
184 }
185
186 if(mpStyleItem && drawing::FillStyle_GRADIENT == mpStyleItem->GetValue())
187 {
190 mxFillControl->Resize();
191
192 if(SfxItemState::DEFAULT == eState)
193 {
195 Update();
196 }
197 else if(SfxItemState::DISABLED == eState )
198 {
201 }
202 else
203 {
205 }
206 }
207 break;
208 }
209 case SID_ATTR_FILL_HATCH:
210 {
211 if(SfxItemState::DEFAULT == eState)
212 {
213 mpHatchItem.reset(pState ? static_cast<XFillHatchItem*>(pState->Clone()) : nullptr);
214 }
215
216 if(mpStyleItem && drawing::FillStyle_HATCH == mpStyleItem->GetValue())
217 {
220 mxFillControl->Resize();
221
222 if(SfxItemState::DEFAULT == eState)
223 {
225 Update();
226 }
227 else if(SfxItemState::DISABLED == eState )
228 {
231 }
232 else
233 {
235 }
236 }
237 break;
238 }
239 case SID_ATTR_FILL_BITMAP:
240 {
241 if(SfxItemState::DEFAULT == eState)
242 {
243 mpBitmapItem.reset(pState ? static_cast<XFillBitmapItem*>(pState->Clone()) : nullptr);
244 }
245
246 if(mpStyleItem && drawing::FillStyle_BITMAP == mpStyleItem->GetValue())
247 {
250 mxFillControl->Resize();
251
252 if(SfxItemState::DEFAULT == eState)
253 {
255 Update();
256 }
257 else if(SfxItemState::DISABLED == eState )
258 {
261 }
262 else
263 {
265 }
266 }
267 break;
268 }
269 case SID_GRADIENT_LIST:
270 {
271 if(SfxItemState::DEFAULT == eState)
272 {
273 if(mpStyleItem && drawing::FillStyle_GRADIENT == mpStyleItem->GetValue())
274 {
276 {
277 const OUString aString( mpFillGradientItem->GetName() );
279 if (const SfxObjectShell* pSh = SfxObjectShell::Current())
280 {
282 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
283 }
285 }
286 else
287 {
289 }
290 }
291 }
292 break;
293 }
294 case SID_HATCH_LIST:
295 {
296 if(SfxItemState::DEFAULT == eState)
297 {
298 if(mpStyleItem && drawing::FillStyle_HATCH == mpStyleItem->GetValue())
299 {
300 if(mpHatchItem)
301 {
302 const OUString aString( mpHatchItem->GetName() );
304 if (const SfxObjectShell* pSh = SfxObjectShell::Current())
305 {
307 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
308 }
310 }
311 else
312 {
314 }
315 }
316 }
317 break;
318 }
319 case SID_BITMAP_LIST:
320 {
321 if(SfxItemState::DEFAULT == eState)
322 {
323 if(mpStyleItem && drawing::FillStyle_BITMAP == mpStyleItem->GetValue())
324 {
325 if(mpBitmapItem)
326 {
327 const OUString aString( mpBitmapItem->GetName() );
329 if (const SfxObjectShell* pSh = SfxObjectShell::Current())
330 {
332 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
333 }
335 }
336 else
337 {
339 }
340 }
341 }
342 break;
343 }
344 }
345}
346
348{
349 if(!mpStyleItem)
350 return;
351
352 const drawing::FillStyle eXFS = mpStyleItem->GetValue();
354
355 switch( eXFS )
356 {
357 case drawing::FillStyle_NONE:
358 {
361 mxFillControl->Resize();
362 break;
363 }
364 case drawing::FillStyle_SOLID:
365 {
366 if(mpColorItem)
367 {
370 mxFillControl->Resize();
371 }
372 break;
373 }
374 case drawing::FillStyle_GRADIENT:
375 {
378 mxFillControl->Resize();
379
380 if(pSh && pSh->GetItem(SID_GRADIENT_LIST))
381 {
384 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
385
387 {
388 const OUString aString(mpFillGradientItem->GetName());
389
391
392 // Check if the entry is not in the list
393 if (mpLbFillAttr->get_active_text() != aString)
394 {
395 sal_Int32 nCount = mpLbFillAttr->get_count();
396 OUString aTmpStr;
397 if( nCount > 0 )
398 {
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) )
403 {
405 }
406 }
407 aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
408
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 );
413
414 if (!aBmp.IsEmpty())
415 {
417 const Size aBmpSize(aBmp.GetSizePixel());
418 pVD->SetOutputSizePixel(aBmpSize, false);
419 pVD->DrawBitmapEx(Point(), aBmp);
420 mpLbFillAttr->append("", xGradientList->Get(0)->GetName(), *pVD);
422 }
423 }
424
425 }
426 else
427 {
429 }
430 }
431 else
432 {
434 }
435 break;
436 }
437 case drawing::FillStyle_HATCH:
438 {
441 mxFillControl->Resize();
442
443 if(pSh && pSh->GetItem(SID_HATCH_LIST))
444 {
447 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
448
449 if(mpHatchItem)
450 {
451 const OUString aString(mpHatchItem->GetName());
452
453 mpLbFillAttr->set_active_text( aString );
454
455 // Check if the entry is not in the list
456 if( mpLbFillAttr->get_active_text() != aString )
457 {
458 const sal_Int32 nCount = mpLbFillAttr->get_count();
459 OUString aTmpStr;
460 if( nCount > 0 )
461 {
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) )
466 {
467 mpLbFillAttr->remove( nCount - 1 );
468 }
469 }
470 aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
471
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 );
476
477 if( !aBmp.IsEmpty() )
478 {
480 const Size aBmpSize(aBmp.GetSizePixel());
481 pVD->SetOutputSizePixel(aBmpSize, false);
482 pVD->DrawBitmapEx(Point(), aBmp);
483 mpLbFillAttr->append("", xHatchList->GetHatch(0)->GetName(), *pVD);
485 }
486 }
487 }
488 else
489 {
491 }
492 }
493 else
494 {
496 }
497 break;
498 }
499 case drawing::FillStyle_BITMAP:
500 {
503 mxFillControl->Resize();
504
505 if(pSh)
506 {
509
510 if(mpBitmapItem && !mpBitmapItem->isPattern() && pSh->GetItem(SID_BITMAP_LIST))
511 {
512 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
513
514 const OUString aString(mpBitmapItem->GetName());
515
517
518 // Check if the entry is not in the list
519 if (mpLbFillAttr->get_active_text() != aString)
520 {
521 sal_Int32 nCount = mpLbFillAttr->get_count();
522 OUString aTmpStr;
523 if( nCount > 0 )
524 {
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) )
529 {
531 }
532 }
533 aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
534
535 XBitmapListRef xBitmapList =
538 XPropertyListType::Bitmap, "TmpList", ""/*TODO?*/));
539 xBitmapList->Insert(std::make_unique<XBitmapEntry>(mpBitmapItem->GetGraphicObject(), aTmpStr));
540 xBitmapList->SetDirty( false );
541 SvxFillAttrBox::Fill(*mpLbFillAttr, xBitmapList);
543 }
544
545 }
546 else if (mpBitmapItem && mpBitmapItem->isPattern() && pSh->GetItem(SID_PATTERN_LIST))
547 {
548 mnLastXFS = sal::static_int_cast<sal_Int32>(PATTERN);
550
551 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_PATTERN_LIST)->GetPatternList());
552 const OUString aString(mpBitmapItem->GetName());
553
555 }
556 else
557 {
559 }
560 }
561 else
562 {
564 }
565 break;
566 }
567 default:
568 OSL_ENSURE(false, "Non supported FillType (!)");
569 break;
570 }
571
572}
573
575{
576 if(GetSlotId() == SID_ATTR_FILL_STYLE)
577 {
579
580 mpLbFillType = mxFillControl->mxLbFillType.get();
581 mpLbFillAttr = mxFillControl->mxLbFillAttr.get();
582 mpToolBoxColor = mxFillControl->mxToolBoxColor.get();
583
584 mpLbFillType->connect_changed(LINK(this,SvxFillToolBoxControl,SelectFillTypeHdl));
585 mpLbFillAttr->connect_changed(LINK(this,SvxFillToolBoxControl,SelectFillAttrHdl));
586
587
588 return mxFillControl;
589 }
591}
592
593FillControl::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"))
599 , mnTypeCurPos(0)
600 , mnAttrCurPos(0)
601{
603
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));
607
608 mxLbFillType->connect_get_property_tree(LINK(this, FillControl, DumpAsPropertyTreeHdl));
609
610 mxLbFillType->connect_focus_in(LINK(this, FillControl, TypeFocusHdl));
611 mxLbFillAttr->connect_focus_in(LINK(this, FillControl, AttrFocusHdl));
612
614
616}
617
618IMPL_STATIC_LINK(FillControl, DumpAsPropertyTreeHdl, tools::JsonWriter&, rJsonWriter, void)
619{
620 rJsonWriter.put("command", ".uno:FillStyle");
621}
622
624{
626 if (pCurSh)
627 {
628 vcl::Window* pShellWnd = pCurSh->GetWindow();
629 if (pShellWnd)
630 pShellWnd->GrabFocus();
631 }
632}
633
634IMPL_LINK(FillControl, TypeKeyInputHdl, const KeyEvent&, rKEvt, bool)
635{
636 const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
637 sal_uInt16 nCode = rKeyCode.GetCode();
638
639 if (nCode == KEY_ESCAPE)
640 {
641 mxLbFillType->set_active(mnTypeCurPos);
642 ReleaseFocus_Impl();
643 return true;
644 }
645
646 if (nCode != KEY_TAB)
647 return false;
648 if (rKeyCode.IsShift())
649 return ChildKeyInput(rKEvt);
650 if (mxLbFillAttr->get_visible() && !mxLbFillAttr->get_sensitive())
651 return ChildKeyInput(rKEvt);
652 return false;
653}
654
656{
657 mnTypeCurPos = mxLbFillType->get_active();
658}
659
661{
662 mnAttrCurPos = mxLbFillAttr->get_active();
663}
664
665IMPL_LINK(FillControl, AttrKeyInputHdl, const KeyEvent&, rKEvt, bool)
666{
667 const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
668 sal_uInt16 nCode = rKeyCode.GetCode();
669
670 if (nCode == KEY_ESCAPE)
671 {
672 mxLbFillAttr->set_active(mnAttrCurPos);
673 ReleaseFocus_Impl();
674 return true;
675 }
676
677 return ChildKeyInput(rKEvt);
678}
679
680IMPL_LINK(FillControl, ColorKeyInputHdl, const KeyEvent&, rKEvt, bool)
681{
682 return ChildKeyInput(rKEvt);
683}
684
686{
687 disposeOnce();
688}
689
691{
692 mxLbFillAttr.reset();
693 mxColorDispatch.reset();
694 mxToolBoxColor.reset();
695 mxLbFillType.reset();
697}
698
700{
701 sal_Int32 nXFS = mpLbFillType->get_active();
702
703 if(mnLastXFS == nXFS)
704 return;
705
706 eFillStyle eXFS = static_cast<eFillStyle>(nXFS);
707 mpLbFillAttr->clear();
709 const XFillStyleItem aXFillStyleItem(toCssFillStyle(eXFS));
710
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.
715 switch( eXFS )
716 {
717 default:
718 case NONE:
719 {
720 mpLbFillAttr->show();
721 mpToolBoxColor->hide();
722 mpLbFillAttr->set_sensitive(false);
723 if (pSh)
724 {
725 // #i122676# need to call a single SID_ATTR_FILL_STYLE change
727 SID_ATTR_FILL_STYLE, SfxCallMode::RECORD,
728 { &aXFillStyleItem });
729 }
730 break;
731 }
732 case SOLID:
733 {
734 mpLbFillAttr->hide();
735 mpToolBoxColor->show();
736 if (pSh)
737 {
738 const ::Color aColor = mpColorItem ? mpColorItem->GetColorValue() : COL_AUTO;
739 const XFillColorItem aXFillColorItem( "", aColor );
740
741 // #i122676# change FillStyle and Color in one call
743 SID_ATTR_FILL_COLOR, SfxCallMode::RECORD,
744 { &aXFillColorItem, &aXFillStyleItem });
745 }
746 break;
747 }
748 case GRADIENT:
749 {
750 mpLbFillAttr->show();
751 mpToolBoxColor->hide();
752
753 if(pSh && pSh->GetItem(SID_GRADIENT_LIST))
754 {
755 if(!mpLbFillAttr->get_count())
756 {
757 mpLbFillAttr->set_sensitive(true);
758 mpLbFillAttr->clear();
759 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
760 }
761
762 if (mnLastPosGradient != -1)
763 {
764 const SvxGradientListItem * pItem = pSh->GetItem(SID_GRADIENT_LIST);
765
766 if(mnLastPosGradient < pItem->GetGradientList()->Count())
767 {
768 const basegfx::BGradient aGradient = pItem->GetGradientList()->GetGradient(mnLastPosGradient)->GetGradient();
769 const XFillGradientItem aXFillGradientItem(mpLbFillAttr->get_text(mnLastPosGradient), aGradient);
770
771 // #i122676# change FillStyle and Gradient in one call
773 SID_ATTR_FILL_GRADIENT, SfxCallMode::RECORD,
774 { &aXFillGradientItem, &aXFillStyleItem });
775 mpLbFillAttr->set_active(mnLastPosGradient);
776 }
777 }
778 }
779 else
780 {
781 mpLbFillAttr->set_sensitive(false);
782 }
783 break;
784 }
785 case HATCH:
786 {
787 mpLbFillAttr->show();
788 mpToolBoxColor->hide();
789
790 if(pSh && pSh->GetItem(SID_HATCH_LIST))
791 {
792 if(!mpLbFillAttr->get_count())
793 {
794 mpLbFillAttr->set_sensitive(true);
795 mpLbFillAttr->clear();
796 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
797 }
798
799 if (mnLastPosHatch != -1)
800 {
801 const SvxHatchListItem * pItem = pSh->GetItem(SID_HATCH_LIST);
802
803 if(mnLastPosHatch < pItem->GetHatchList()->Count())
804 {
805 const XHatch aHatch = pItem->GetHatchList()->GetHatch(mnLastPosHatch)->GetHatch();
806 const XFillHatchItem aXFillHatchItem(mpLbFillAttr->get_active_text(), aHatch);
807
808 // #i122676# change FillStyle and Hatch in one call
810 SID_ATTR_FILL_HATCH, SfxCallMode::RECORD,
811 { &aXFillHatchItem, &aXFillStyleItem });
812 mpLbFillAttr->set_active(mnLastPosHatch);
813 }
814 }
815 }
816 else
817 {
818 mpLbFillAttr->set_sensitive(false);
819 }
820 break;
821 }
822 case BITMAP:
823 {
824 mpLbFillAttr->show();
825 mpToolBoxColor->hide();
826
827 if(pSh && pSh->GetItem(SID_BITMAP_LIST))
828 {
829 if(!mpLbFillAttr->get_count())
830 {
831 mpLbFillAttr->set_sensitive(true);
832 mpLbFillAttr->clear();
833 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
834 }
835
836 if (mnLastPosBitmap != -1)
837 {
838 const SvxBitmapListItem * pItem = pSh->GetItem(SID_BITMAP_LIST);
839
840 if(mnLastPosBitmap < pItem->GetBitmapList()->Count())
841 {
842 const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(mnLastPosBitmap);
843 const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
844
845 // #i122676# change FillStyle and Bitmap in one call
847 SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
848 { &aXFillBitmapItem, &aXFillStyleItem });
849 mpLbFillAttr->set_active(mnLastPosBitmap);
850 }
851 }
852 }
853 else
854 {
855 mpLbFillAttr->set_sensitive(false);
856 }
857 break;
858 }
859 case PATTERN:
860 {
861 mpLbFillAttr->show();
862 mpToolBoxColor->hide();
863
864 if(pSh && pSh->GetItem(SID_PATTERN_LIST))
865 {
866 if(!mpLbFillAttr->get_count())
867 {
868 mpLbFillAttr->set_sensitive(true);
869 mpLbFillAttr->clear();
870 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_PATTERN_LIST)->GetPatternList());
871 }
872
873 if (mnLastPosPattern != -1)
874 {
875 const SvxPatternListItem * pItem = pSh->GetItem(SID_PATTERN_LIST);
876
877 if(mnLastPosPattern < pItem->GetPatternList()->Count())
878 {
879 const XBitmapEntry* pXBitmapEntry = pItem->GetPatternList()->GetBitmap(mnLastPosPattern);
880 const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
881
882 // #i122676# change FillStyle and Bitmap in one call
884 SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
885 { &aXFillBitmapItem, &aXFillStyleItem });
886 mpLbFillAttr->set_active(mnLastPosPattern);
887 }
888 }
889 }
890 else
891 {
892 mpLbFillAttr->set_sensitive(false);
893 }
894 break;
895 }
896
897 }
898
899 mnLastXFS = nXFS;
900
901 mxFillControl->Resize();
902}
903
905{
906 sal_Int32 nXFS = mpLbFillType->get_active();
907 eFillStyle eXFS = static_cast<eFillStyle>(nXFS);
908
909 const XFillStyleItem aXFillStyleItem(toCssFillStyle(eXFS));
911
912 // #i122676# dependent from bFillStyleChange, do execute a single or two
913 // changes in one Execute call
914 const bool bFillStyleChange(mnLastXFS != nXFS);
915
916 switch (eXFS)
917 {
918 case SOLID:
919 {
920 if (bFillStyleChange && pSh)
921 {
922 // #i122676# Single FillStyle change call needed here
924 SID_ATTR_FILL_STYLE, SfxCallMode::RECORD,
925 { &aXFillStyleItem });
926 }
927 break;
928 }
929 case GRADIENT:
930 {
931 sal_Int32 nPos = mpLbFillAttr->get_active();
932
933 if (nPos == -1)
934 {
935 nPos = mnLastPosGradient;
936 }
937
938 if (nPos != -1 && pSh && pSh->GetItem(SID_GRADIENT_LIST))
939 {
940 const SvxGradientListItem * pItem = pSh->GetItem(SID_GRADIENT_LIST);
941
942 if(nPos < pItem->GetGradientList()->Count())
943 {
944 const basegfx::BGradient aGradient = pItem->GetGradientList()->GetGradient(nPos)->GetGradient();
945 const XFillGradientItem aXFillGradientItem(mpLbFillAttr->get_active_text(), aGradient);
946
947 // #i122676# Change FillStyle and Gradient in one call
949 SID_ATTR_FILL_GRADIENT, SfxCallMode::RECORD,
950 bFillStyleChange
951 ? std::initializer_list<SfxPoolItem const*>{ &aXFillGradientItem, &aXFillStyleItem }
952 : std::initializer_list<SfxPoolItem const*>{ &aXFillGradientItem });
953 }
954 }
955
956 if (nPos != -1)
957 {
958 mnLastPosGradient = nPos;
959 }
960 break;
961 }
962 case HATCH:
963 {
964 sal_Int32 nPos = mpLbFillAttr->get_active();
965
966 if (nPos == -1)
967 {
968 nPos = mnLastPosHatch;
969 }
970
971 if (nPos != -1 && pSh && pSh->GetItem(SID_HATCH_LIST))
972 {
973 const SvxHatchListItem * pItem = pSh->GetItem(SID_HATCH_LIST);
974
975 if(nPos < pItem->GetHatchList()->Count())
976 {
977 const XHatch aHatch = pItem->GetHatchList()->GetHatch(nPos)->GetHatch();
978 const XFillHatchItem aXFillHatchItem( mpLbFillAttr->get_active_text(), aHatch);
979
980 // #i122676# Change FillStyle and Hatch in one call
982 SID_ATTR_FILL_HATCH, SfxCallMode::RECORD,
983 bFillStyleChange
984 ? std::initializer_list<SfxPoolItem const*>{ &aXFillHatchItem, &aXFillStyleItem }
985 : std::initializer_list<SfxPoolItem const*>{ &aXFillHatchItem });
986 }
987 }
988
989 if (nPos != -1)
990 {
991 mnLastPosHatch = nPos;
992 }
993 break;
994 }
995 case BITMAP:
996 {
997 sal_Int32 nPos = mpLbFillAttr->get_active();
998
999 if (nPos == -1)
1000 {
1001 nPos = mnLastPosBitmap;
1002 }
1003
1004 if (nPos != -1 && pSh && pSh->GetItem(SID_BITMAP_LIST))
1005 {
1006 const SvxBitmapListItem * pItem = pSh->GetItem(SID_BITMAP_LIST);
1007
1008 if(nPos < pItem->GetBitmapList()->Count())
1009 {
1010 const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(nPos);
1011 const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
1012
1013 // #i122676# Change FillStyle and Bitmap in one call
1014 pSh->GetDispatcher()->ExecuteList(
1015 SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
1016 bFillStyleChange
1017 ? std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem, &aXFillStyleItem }
1018 : std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem });
1019 }
1020 }
1021
1022 if (nPos != -1)
1023 {
1024 mnLastPosBitmap = nPos;
1025 }
1026 break;
1027 }
1028 case PATTERN:
1029 {
1030 sal_Int32 nPos = mpLbFillAttr->get_active();
1031
1032 if (nPos == -1)
1033 {
1034 nPos = mnLastPosPattern;
1035 }
1036
1037 if (nPos != -1 && pSh && pSh->GetItem(SID_PATTERN_LIST))
1038 {
1039 const SvxPatternListItem * pItem = pSh->GetItem(SID_PATTERN_LIST);
1040
1041 if(nPos < pItem->GetPatternList()->Count())
1042 {
1043 const XBitmapEntry* pXBitmapEntry = pItem->GetPatternList()->GetBitmap(nPos);
1044 const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
1045
1046 // #i122676# Change FillStyle and Bitmap in one call
1047 pSh->GetDispatcher()->ExecuteList(
1048 SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
1049 bFillStyleChange
1050 ? std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem, &aXFillStyleItem }
1051 : std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem });
1052 }
1053 }
1054
1055 if (nPos != -1)
1056 {
1057 mnLastPosPattern = nPos;
1058 }
1059 break;
1060 }
1061
1062 default: break;
1063 }
1064}
1065
1067{
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));
1075}
1076
1078{
1079 if((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1080 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
1081 {
1083 }
1085}
1086
1088{
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"))
1092 return;
1094}
1095
1096/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Reference< css::lang::XComponent > m_xFrame
bool IsEmpty() const
const Size & GetSizePixel() const
DataChangedEventType GetType() const
AllSettingsFlags GetFlags() const
std::unique_ptr< ToolbarUnoDispatcher > mxColorDispatch
Definition: fillctrl.hxx:83
virtual void dispose() override
Definition: fillctrl.cxx:690
virtual void GetFocus() override
Definition: fillctrl.cxx:1087
std::unique_ptr< weld::ComboBox > mxLbFillType
Definition: fillctrl.hxx:81
void SetOptimalSize()
Definition: fillctrl.cxx:1066
std::unique_ptr< weld::Toolbar > mxToolBoxColor
Definition: fillctrl.hxx:82
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: fillctrl.cxx:1077
static void ReleaseFocus_Impl()
Definition: fillctrl.cxx:623
FillControl(vcl::Window *pParent, const css::uno::Reference< css::frame::XFrame > &rFrame)
Definition: fillctrl.cxx:593
std::unique_ptr< weld::ComboBox > mxLbFillAttr
Definition: fillctrl.hxx:84
virtual ~FillControl() override
Definition: fillctrl.cxx:685
virtual void dispose() override
virtual void GetFocus() override
std::unique_ptr< weld::Container > m_xContainer
void InitControlBase(weld::Widget *pWidget)
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 * >())
static SAL_WARN_UNUSED_RESULT SfxObjectShell * Current()
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const=0
const SfxPoolItem * GetItem(sal_uInt16 nSlotId) const
SfxDispatcher * GetDispatcher() const
unsigned short GetSlotId() const
static SAL_WARN_UNUSED_RESULT SfxViewShell * Current()
vcl::Window * GetWindow() const
constexpr tools::Long Height() const
constexpr tools::Long Width() const
const XBitmapListRef & GetBitmapList() const
Definition: drawitem.hxx:122
weld::Toolbar * mpToolBoxColor
Definition: fillctrl.hxx:53
std::unique_ptr< XFillGradientItem > mpFillGradientItem
Definition: fillctrl.hxx:47
std::unique_ptr< XFillBitmapItem > mpBitmapItem
Definition: fillctrl.hxx:49
std::unique_ptr< XFillColorItem > mpColorItem
Definition: fillctrl.hxx:46
virtual ~SvxFillToolBoxControl() override
Definition: fillctrl.cxx:102
weld::ComboBox * mpLbFillAttr
Definition: fillctrl.hxx:54
VclPtr< FillControl > mxFillControl
Definition: fillctrl.hxx:51
std::unique_ptr< XFillHatchItem > mpHatchItem
Definition: fillctrl.hxx:48
weld::ComboBox * mpLbFillType
Definition: fillctrl.hxx:52
virtual VclPtr< InterimItemWindow > CreateItemWindow(vcl::Window *pParent) override
Definition: fillctrl.cxx:574
virtual void StateChangedAtToolBoxControl(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem *pState) override
Definition: fillctrl.cxx:106
SvxFillToolBoxControl(sal_uInt16 nSlotId, ToolBoxItemId nId, ToolBox &rTbx)
Definition: fillctrl.cxx:77
std::unique_ptr< XFillStyleItem > mpStyleItem
Definition: fillctrl.hxx:45
const XGradientListRef & GetGradientList() const
Definition: drawitem.hxx:73
const XHatchListRef & GetHatchList() const
Definition: drawitem.hxx:97
const XPatternListRef & GetPatternList() const
Definition: drawitem.hxx:146
void reset(reference_type *pBody)
reference_type * get() const
const GraphicObject & GetGraphicObject() const
Definition: xtable.hxx:125
virtual XFillStyleItem * Clone(SfxItemPool *pPool=nullptr) const override
Definition: xattr.cxx:1871
static XPropertyListRef CreatePropertyList(XPropertyListType t, const OUString &rPath, const OUString &rReferer)
Definition: xtable.cxx:316
static XBitmapListRef AsBitmapList(rtl::Reference< XPropertyList > const &plist)
Definition: xtable.hxx:381
sal_uInt16 GetCode() const
bool IsShift() const
Point LogicToPixel(const Point &rLogicPt) const
virtual void SetSizePixel(const Size &rNewSize)
void GrabFocus()
virtual void DataChanged(const DataChangedEvent &rDCEvt)
virtual OUString get_active_text() const=0
virtual void clear()=0
void append(const weld::ComboBoxEntry &rItem)
virtual void set_active(int pos)=0
virtual OUString get_text(int pos) const=0
virtual void remove(int pos)=0
virtual int get_count() const=0
void set_active_text(const OUString &rStr)
void connect_changed(const Link< ComboBox &, void > &rLink)
virtual void show()=0
virtual void hide()=0
virtual void set_sensitive(bool sensitive)=0
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
int nCount
float u
constexpr OUStringLiteral TMP_STR_END
Definition: fillctrl.cxx:32
SFX_IMPL_TOOLBOX_CONTROL(SvxFillToolBoxControl, XFillStyleItem)
IMPL_STATIC_LINK(FillControl, DumpAsPropertyTreeHdl, tools::JsonWriter &, rJsonWriter, void)
Definition: fillctrl.cxx:618
IMPL_LINK_NOARG(FillControl, TypeFocusHdl, weld::Widget &, void)
Definition: fillctrl.cxx:655
constexpr OUStringLiteral TMP_STR_BEGIN
Definition: fillctrl.cxx:31
IMPL_LINK(FillControl, TypeKeyInputHdl, const KeyEvent &, rKEvt, bool)
Definition: fillctrl.cxx:634
constexpr sal_uInt16 KEY_ESCAPE
constexpr sal_uInt16 KEY_TAB
sal_uInt16 nPos
SVX_DLLPUBLIC void Fill(weld::ComboBox &, const XHatchListRef &pList)
Definition: itemwin.cxx:244
SVX_DLLPUBLIC void Fill(weld::ComboBox &rListBox)
Definition: itemwin.cxx:173
NONE
sal_Int16 nId
SfxItemState
Count
constexpr OUStringLiteral PATTERN