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
282 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
284 }
285 else
286 {
288 }
289 }
290 }
291 break;
292 }
293 case SID_HATCH_LIST:
294 {
295 if(SfxItemState::DEFAULT == eState)
296 {
297 if(mpStyleItem && drawing::FillStyle_HATCH == mpStyleItem->GetValue())
298 {
299 if(mpHatchItem)
300 {
301 const OUString aString( mpHatchItem->GetName() );
303
306 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
308 }
309 else
310 {
312 }
313 }
314 }
315 break;
316 }
317 case SID_BITMAP_LIST:
318 {
319 if(SfxItemState::DEFAULT == eState)
320 {
321 if(mpStyleItem && drawing::FillStyle_BITMAP == mpStyleItem->GetValue())
322 {
323 if(mpBitmapItem)
324 {
325 const OUString aString( mpBitmapItem->GetName() );
327
330 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
332 }
333 else
334 {
336 }
337 }
338 }
339 break;
340 }
341 }
342}
343
345{
346 if(!mpStyleItem)
347 return;
348
349 const drawing::FillStyle eXFS = mpStyleItem->GetValue();
351
352 switch( eXFS )
353 {
354 case drawing::FillStyle_NONE:
355 {
358 mxFillControl->Resize();
359 break;
360 }
361 case drawing::FillStyle_SOLID:
362 {
363 if(mpColorItem)
364 {
367 mxFillControl->Resize();
368 }
369 break;
370 }
371 case drawing::FillStyle_GRADIENT:
372 {
375 mxFillControl->Resize();
376
377 if(pSh && pSh->GetItem(SID_GRADIENT_LIST))
378 {
381 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
382
384 {
385 const OUString aString(mpFillGradientItem->GetName());
386
388
389 // Check if the entry is not in the list
390 if (mpLbFillAttr->get_active_text() != aString)
391 {
392 sal_Int32 nCount = mpLbFillAttr->get_count();
393 OUString aTmpStr;
394 if( nCount > 0 )
395 {
396 // Last entry gets tested against temporary entry
397 aTmpStr = mpLbFillAttr->get_text( nCount - 1 );
398 if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
399 aTmpStr.endsWith(TMP_STR_END) )
400 {
402 }
403 }
404 aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
405
406 rtl::Reference<XGradientList> xGradientList = new XGradientList( "", ""/*TODO?*/ );
407 xGradientList->Insert(std::make_unique<XGradientEntry>(mpFillGradientItem->GetGradientValue(), aTmpStr));
408 xGradientList->SetDirty( false );
409 const BitmapEx aBmp = xGradientList->GetUiBitmap( 0 );
410
411 if (!aBmp.IsEmpty())
412 {
414 const Size aBmpSize(aBmp.GetSizePixel());
415 pVD->SetOutputSizePixel(aBmpSize, false);
416 pVD->DrawBitmapEx(Point(), aBmp);
417 mpLbFillAttr->append("", xGradientList->Get(0)->GetName(), *pVD);
419 }
420 }
421
422 }
423 else
424 {
426 }
427 }
428 else
429 {
431 }
432 break;
433 }
434 case drawing::FillStyle_HATCH:
435 {
438 mxFillControl->Resize();
439
440 if(pSh && pSh->GetItem(SID_HATCH_LIST))
441 {
444 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
445
446 if(mpHatchItem)
447 {
448 const OUString aString(mpHatchItem->GetName());
449
450 mpLbFillAttr->set_active_text( aString );
451
452 // Check if the entry is not in the list
453 if( mpLbFillAttr->get_active_text() != aString )
454 {
455 const sal_Int32 nCount = mpLbFillAttr->get_count();
456 OUString aTmpStr;
457 if( nCount > 0 )
458 {
459 // Last entry gets tested against temporary entry
460 aTmpStr = mpLbFillAttr->get_text( nCount - 1 );
461 if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
462 aTmpStr.endsWith(TMP_STR_END) )
463 {
464 mpLbFillAttr->remove( nCount - 1 );
465 }
466 }
467 aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
468
469 rtl::Reference<XHatchList> xHatchList = new XHatchList( "", ""/*TODO?*/ );
470 xHatchList->Insert(std::make_unique<XHatchEntry>(mpHatchItem->GetHatchValue(), aTmpStr));
471 xHatchList->SetDirty( false );
472 const BitmapEx & aBmp = xHatchList->GetUiBitmap( 0 );
473
474 if( !aBmp.IsEmpty() )
475 {
477 const Size aBmpSize(aBmp.GetSizePixel());
478 pVD->SetOutputSizePixel(aBmpSize, false);
479 pVD->DrawBitmapEx(Point(), aBmp);
480 mpLbFillAttr->append("", xHatchList->GetHatch(0)->GetName(), *pVD);
482 }
483 }
484 }
485 else
486 {
488 }
489 }
490 else
491 {
493 }
494 break;
495 }
496 case drawing::FillStyle_BITMAP:
497 {
500 mxFillControl->Resize();
501
502 if(pSh)
503 {
506
507 if(mpBitmapItem && !mpBitmapItem->isPattern() && pSh->GetItem(SID_BITMAP_LIST))
508 {
509 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
510
511 const OUString aString(mpBitmapItem->GetName());
512
514
515 // Check if the entry is not in the list
516 if (mpLbFillAttr->get_active_text() != aString)
517 {
518 sal_Int32 nCount = mpLbFillAttr->get_count();
519 OUString aTmpStr;
520 if( nCount > 0 )
521 {
522 // Last entry gets tested against temporary entry
523 aTmpStr = mpLbFillAttr->get_text(nCount - 1);
524 if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
525 aTmpStr.endsWith(TMP_STR_END) )
526 {
528 }
529 }
530 aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
531
532 XBitmapListRef xBitmapList =
535 XPropertyListType::Bitmap, "TmpList", ""/*TODO?*/));
536 xBitmapList->Insert(std::make_unique<XBitmapEntry>(mpBitmapItem->GetGraphicObject(), aTmpStr));
537 xBitmapList->SetDirty( false );
538 SvxFillAttrBox::Fill(*mpLbFillAttr, xBitmapList);
540 }
541
542 }
543 else if (mpBitmapItem && mpBitmapItem->isPattern() && pSh->GetItem(SID_PATTERN_LIST))
544 {
545 mnLastXFS = sal::static_int_cast<sal_Int32>(PATTERN);
547
548 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_PATTERN_LIST)->GetPatternList());
549 const OUString aString(mpBitmapItem->GetName());
550
552 }
553 else
554 {
556 }
557 }
558 else
559 {
561 }
562 break;
563 }
564 default:
565 OSL_ENSURE(false, "Non supported FillType (!)");
566 break;
567 }
568
569}
570
572{
573 if(GetSlotId() == SID_ATTR_FILL_STYLE)
574 {
576
577 mpLbFillType = mxFillControl->mxLbFillType.get();
578 mpLbFillAttr = mxFillControl->mxLbFillAttr.get();
579 mpToolBoxColor = mxFillControl->mxToolBoxColor.get();
580
581 mpLbFillType->connect_changed(LINK(this,SvxFillToolBoxControl,SelectFillTypeHdl));
582 mpLbFillAttr->connect_changed(LINK(this,SvxFillToolBoxControl,SelectFillAttrHdl));
583
584
585 return mxFillControl;
586 }
588}
589
590FillControl::FillControl(vcl::Window* pParent, const css::uno::Reference<css::frame::XFrame>& rFrame)
591 : InterimItemWindow(pParent, "svx/ui/fillctrlbox.ui", "FillCtrlBox")
592 , mxLbFillType(m_xBuilder->weld_combo_box("type"))
593 , mxToolBoxColor(m_xBuilder->weld_toolbar("color"))
594 , mxColorDispatch(new ToolbarUnoDispatcher(*mxToolBoxColor, *m_xBuilder, rFrame))
595 , mxLbFillAttr(m_xBuilder->weld_combo_box("attr"))
596 , mnTypeCurPos(0)
597 , mnAttrCurPos(0)
598{
600
601 mxLbFillAttr->connect_key_press(LINK(this, FillControl, AttrKeyInputHdl));
602 mxLbFillType->connect_key_press(LINK(this, FillControl, TypeKeyInputHdl));
603 mxToolBoxColor->connect_key_press(LINK(this, FillControl, ColorKeyInputHdl));
604
605 mxLbFillType->connect_get_property_tree(LINK(this, FillControl, DumpAsPropertyTreeHdl));
606
607 mxLbFillType->connect_focus_in(LINK(this, FillControl, TypeFocusHdl));
608 mxLbFillAttr->connect_focus_in(LINK(this, FillControl, AttrFocusHdl));
609
611
613}
614
615IMPL_STATIC_LINK(FillControl, DumpAsPropertyTreeHdl, tools::JsonWriter&, rJsonWriter, void)
616{
617 rJsonWriter.put("command", ".uno:FillStyle");
618}
619
621{
623 if (pCurSh)
624 {
625 vcl::Window* pShellWnd = pCurSh->GetWindow();
626 if (pShellWnd)
627 pShellWnd->GrabFocus();
628 }
629}
630
631IMPL_LINK(FillControl, TypeKeyInputHdl, const KeyEvent&, rKEvt, bool)
632{
633 const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
634 sal_uInt16 nCode = rKeyCode.GetCode();
635
636 if (nCode == KEY_ESCAPE)
637 {
638 mxLbFillType->set_active(mnTypeCurPos);
639 ReleaseFocus_Impl();
640 return true;
641 }
642
643 if (nCode != KEY_TAB)
644 return false;
645 if (rKeyCode.IsShift())
646 return ChildKeyInput(rKEvt);
647 if (mxLbFillAttr->get_visible() && !mxLbFillAttr->get_sensitive())
648 return ChildKeyInput(rKEvt);
649 return false;
650}
651
653{
654 mnTypeCurPos = mxLbFillType->get_active();
655}
656
658{
659 mnAttrCurPos = mxLbFillAttr->get_active();
660}
661
662IMPL_LINK(FillControl, AttrKeyInputHdl, const KeyEvent&, rKEvt, bool)
663{
664 const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
665 sal_uInt16 nCode = rKeyCode.GetCode();
666
667 if (nCode == KEY_ESCAPE)
668 {
669 mxLbFillAttr->set_active(mnAttrCurPos);
670 ReleaseFocus_Impl();
671 return true;
672 }
673
674 return ChildKeyInput(rKEvt);
675}
676
677IMPL_LINK(FillControl, ColorKeyInputHdl, const KeyEvent&, rKEvt, bool)
678{
679 return ChildKeyInput(rKEvt);
680}
681
683{
684 disposeOnce();
685}
686
688{
689 mxLbFillAttr.reset();
690 mxColorDispatch.reset();
691 mxToolBoxColor.reset();
692 mxLbFillType.reset();
694}
695
697{
698 sal_Int32 nXFS = mpLbFillType->get_active();
699
700 if(mnLastXFS == nXFS)
701 return;
702
703 eFillStyle eXFS = static_cast<eFillStyle>(nXFS);
704 mpLbFillAttr->clear();
706 const XFillStyleItem aXFillStyleItem(toCssFillStyle(eXFS));
707
708 // #i122676# Do no longer trigger two Execute calls, one for SID_ATTR_FILL_STYLE
709 // and one for setting the fill attribute itself, but add two SfxPoolItems to the
710 // call to get just one action at the SdrObject and to create only one Undo action, too.
711 // Checked that this works in all apps.
712 switch( eXFS )
713 {
714 default:
715 case NONE:
716 {
717 mpLbFillAttr->show();
718 mpToolBoxColor->hide();
719 mpLbFillAttr->set_sensitive(false);
720 if (pSh)
721 {
722 // #i122676# need to call a single SID_ATTR_FILL_STYLE change
724 SID_ATTR_FILL_STYLE, SfxCallMode::RECORD,
725 { &aXFillStyleItem });
726 }
727 break;
728 }
729 case SOLID:
730 {
731 mpLbFillAttr->hide();
732 mpToolBoxColor->show();
733 if (pSh)
734 {
735 const ::Color aColor = mpColorItem ? mpColorItem->GetColorValue() : COL_AUTO;
736 const XFillColorItem aXFillColorItem( "", aColor );
737
738 // #i122676# change FillStyle and Color in one call
740 SID_ATTR_FILL_COLOR, SfxCallMode::RECORD,
741 { &aXFillColorItem, &aXFillStyleItem });
742 }
743 break;
744 }
745 case GRADIENT:
746 {
747 mpLbFillAttr->show();
748 mpToolBoxColor->hide();
749
750 if(pSh && pSh->GetItem(SID_GRADIENT_LIST))
751 {
752 if(!mpLbFillAttr->get_count())
753 {
754 mpLbFillAttr->set_sensitive(true);
755 mpLbFillAttr->clear();
756 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
757 }
758
759 if (mnLastPosGradient != -1)
760 {
761 const SvxGradientListItem * pItem = pSh->GetItem(SID_GRADIENT_LIST);
762
763 if(mnLastPosGradient < pItem->GetGradientList()->Count())
764 {
765 const XGradient aGradient = pItem->GetGradientList()->GetGradient(mnLastPosGradient)->GetGradient();
766 const XFillGradientItem aXFillGradientItem(mpLbFillAttr->get_text(mnLastPosGradient), aGradient);
767
768 // #i122676# change FillStyle and Gradient in one call
770 SID_ATTR_FILL_GRADIENT, SfxCallMode::RECORD,
771 { &aXFillGradientItem, &aXFillStyleItem });
772 mpLbFillAttr->set_active(mnLastPosGradient);
773 }
774 }
775 }
776 else
777 {
778 mpLbFillAttr->set_sensitive(false);
779 }
780 break;
781 }
782 case HATCH:
783 {
784 mpLbFillAttr->show();
785 mpToolBoxColor->hide();
786
787 if(pSh && pSh->GetItem(SID_HATCH_LIST))
788 {
789 if(!mpLbFillAttr->get_count())
790 {
791 mpLbFillAttr->set_sensitive(true);
792 mpLbFillAttr->clear();
793 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
794 }
795
796 if (mnLastPosHatch != -1)
797 {
798 const SvxHatchListItem * pItem = pSh->GetItem(SID_HATCH_LIST);
799
800 if(mnLastPosHatch < pItem->GetHatchList()->Count())
801 {
802 const XHatch aHatch = pItem->GetHatchList()->GetHatch(mnLastPosHatch)->GetHatch();
803 const XFillHatchItem aXFillHatchItem(mpLbFillAttr->get_active_text(), aHatch);
804
805 // #i122676# change FillStyle and Hatch in one call
807 SID_ATTR_FILL_HATCH, SfxCallMode::RECORD,
808 { &aXFillHatchItem, &aXFillStyleItem });
809 mpLbFillAttr->set_active(mnLastPosHatch);
810 }
811 }
812 }
813 else
814 {
815 mpLbFillAttr->set_sensitive(false);
816 }
817 break;
818 }
819 case BITMAP:
820 {
821 mpLbFillAttr->show();
822 mpToolBoxColor->hide();
823
824 if(pSh && pSh->GetItem(SID_BITMAP_LIST))
825 {
826 if(!mpLbFillAttr->get_count())
827 {
828 mpLbFillAttr->set_sensitive(true);
829 mpLbFillAttr->clear();
830 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
831 }
832
833 if (mnLastPosBitmap != -1)
834 {
835 const SvxBitmapListItem * pItem = pSh->GetItem(SID_BITMAP_LIST);
836
837 if(mnLastPosBitmap < pItem->GetBitmapList()->Count())
838 {
839 const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(mnLastPosBitmap);
840 const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
841
842 // #i122676# change FillStyle and Bitmap in one call
844 SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
845 { &aXFillBitmapItem, &aXFillStyleItem });
846 mpLbFillAttr->set_active(mnLastPosBitmap);
847 }
848 }
849 }
850 else
851 {
852 mpLbFillAttr->set_sensitive(false);
853 }
854 break;
855 }
856 case PATTERN:
857 {
858 mpLbFillAttr->show();
859 mpToolBoxColor->hide();
860
861 if(pSh && pSh->GetItem(SID_PATTERN_LIST))
862 {
863 if(!mpLbFillAttr->get_count())
864 {
865 mpLbFillAttr->set_sensitive(true);
866 mpLbFillAttr->clear();
867 SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_PATTERN_LIST)->GetPatternList());
868 }
869
870 if (mnLastPosPattern != -1)
871 {
872 const SvxPatternListItem * pItem = pSh->GetItem(SID_PATTERN_LIST);
873
874 if(mnLastPosPattern < pItem->GetPatternList()->Count())
875 {
876 const XBitmapEntry* pXBitmapEntry = pItem->GetPatternList()->GetBitmap(mnLastPosPattern);
877 const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
878
879 // #i122676# change FillStyle and Bitmap in one call
881 SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
882 { &aXFillBitmapItem, &aXFillStyleItem });
883 mpLbFillAttr->set_active(mnLastPosPattern);
884 }
885 }
886 }
887 else
888 {
889 mpLbFillAttr->set_sensitive(false);
890 }
891 break;
892 }
893
894 }
895
896 mnLastXFS = nXFS;
897
898 mxFillControl->Resize();
899}
900
902{
903 sal_Int32 nXFS = mpLbFillType->get_active();
904 eFillStyle eXFS = static_cast<eFillStyle>(nXFS);
905
906 const XFillStyleItem aXFillStyleItem(toCssFillStyle(eXFS));
908
909 // #i122676# dependent from bFillStyleChange, do execute a single or two
910 // changes in one Execute call
911 const bool bFillStyleChange(mnLastXFS != nXFS);
912
913 switch (eXFS)
914 {
915 case SOLID:
916 {
917 if (bFillStyleChange && pSh)
918 {
919 // #i122676# Single FillStyle change call needed here
921 SID_ATTR_FILL_STYLE, SfxCallMode::RECORD,
922 { &aXFillStyleItem });
923 }
924 break;
925 }
926 case GRADIENT:
927 {
928 sal_Int32 nPos = mpLbFillAttr->get_active();
929
930 if (nPos == -1)
931 {
932 nPos = mnLastPosGradient;
933 }
934
935 if (nPos != -1 && pSh && pSh->GetItem(SID_GRADIENT_LIST))
936 {
937 const SvxGradientListItem * pItem = pSh->GetItem(SID_GRADIENT_LIST);
938
939 if(nPos < pItem->GetGradientList()->Count())
940 {
941 const XGradient aGradient = pItem->GetGradientList()->GetGradient(nPos)->GetGradient();
942 const XFillGradientItem aXFillGradientItem(mpLbFillAttr->get_active_text(), aGradient);
943
944 // #i122676# Change FillStyle and Gradient in one call
946 SID_ATTR_FILL_GRADIENT, SfxCallMode::RECORD,
947 bFillStyleChange
948 ? std::initializer_list<SfxPoolItem const*>{ &aXFillGradientItem, &aXFillStyleItem }
949 : std::initializer_list<SfxPoolItem const*>{ &aXFillGradientItem });
950 }
951 }
952
953 if (nPos != -1)
954 {
955 mnLastPosGradient = nPos;
956 }
957 break;
958 }
959 case HATCH:
960 {
961 sal_Int32 nPos = mpLbFillAttr->get_active();
962
963 if (nPos == -1)
964 {
965 nPos = mnLastPosHatch;
966 }
967
968 if (nPos != -1 && pSh && pSh->GetItem(SID_HATCH_LIST))
969 {
970 const SvxHatchListItem * pItem = pSh->GetItem(SID_HATCH_LIST);
971
972 if(nPos < pItem->GetHatchList()->Count())
973 {
974 const XHatch aHatch = pItem->GetHatchList()->GetHatch(nPos)->GetHatch();
975 const XFillHatchItem aXFillHatchItem( mpLbFillAttr->get_active_text(), aHatch);
976
977 // #i122676# Change FillStyle and Hatch in one call
979 SID_ATTR_FILL_HATCH, SfxCallMode::RECORD,
980 bFillStyleChange
981 ? std::initializer_list<SfxPoolItem const*>{ &aXFillHatchItem, &aXFillStyleItem }
982 : std::initializer_list<SfxPoolItem const*>{ &aXFillHatchItem });
983 }
984 }
985
986 if (nPos != -1)
987 {
988 mnLastPosHatch = nPos;
989 }
990 break;
991 }
992 case BITMAP:
993 {
994 sal_Int32 nPos = mpLbFillAttr->get_active();
995
996 if (nPos == -1)
997 {
998 nPos = mnLastPosBitmap;
999 }
1000
1001 if (nPos != -1 && pSh && pSh->GetItem(SID_BITMAP_LIST))
1002 {
1003 const SvxBitmapListItem * pItem = pSh->GetItem(SID_BITMAP_LIST);
1004
1005 if(nPos < pItem->GetBitmapList()->Count())
1006 {
1007 const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(nPos);
1008 const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
1009
1010 // #i122676# Change FillStyle and Bitmap in one call
1011 pSh->GetDispatcher()->ExecuteList(
1012 SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
1013 bFillStyleChange
1014 ? std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem, &aXFillStyleItem }
1015 : std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem });
1016 }
1017 }
1018
1019 if (nPos != -1)
1020 {
1021 mnLastPosBitmap = nPos;
1022 }
1023 break;
1024 }
1025 case PATTERN:
1026 {
1027 sal_Int32 nPos = mpLbFillAttr->get_active();
1028
1029 if (nPos == -1)
1030 {
1031 nPos = mnLastPosPattern;
1032 }
1033
1034 if (nPos != -1 && pSh && pSh->GetItem(SID_PATTERN_LIST))
1035 {
1036 const SvxPatternListItem * pItem = pSh->GetItem(SID_PATTERN_LIST);
1037
1038 if(nPos < pItem->GetPatternList()->Count())
1039 {
1040 const XBitmapEntry* pXBitmapEntry = pItem->GetPatternList()->GetBitmap(nPos);
1041 const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
1042
1043 // #i122676# Change FillStyle and Bitmap in one call
1044 pSh->GetDispatcher()->ExecuteList(
1045 SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
1046 bFillStyleChange
1047 ? std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem, &aXFillStyleItem }
1048 : std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem });
1049 }
1050 }
1051
1052 if (nPos != -1)
1053 {
1054 mnLastPosPattern = nPos;
1055 }
1056 break;
1057 }
1058
1059 default: break;
1060 }
1061}
1062
1064{
1065 Size aSize(mxLbFillType->get_preferred_size());
1066 Size aFirstSize(mxToolBoxColor->get_preferred_size());
1067 auto nWidth = std::max(aFirstSize.Width(), LogicToPixel(Size(55, 0), MapMode(MapUnit::MapAppFont)).Width());
1068 auto nHeight = std::max(aSize.Height(), aFirstSize.Height());
1069 mxToolBoxColor->set_size_request(nWidth, -1);
1070 mxLbFillAttr->set_size_request(42, -1); //something narrow so the toolbar sets the overall size of this column
1071 SetSizePixel(Size(m_xContainer->get_preferred_size().Width(), nHeight));
1072}
1073
1075{
1076 if((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1077 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
1078 {
1080 }
1082}
1083
1084/* 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:687
std::unique_ptr< weld::ComboBox > mxLbFillType
Definition: fillctrl.hxx:81
void SetOptimalSize()
Definition: fillctrl.cxx:1063
std::unique_ptr< weld::Toolbar > mxToolBoxColor
Definition: fillctrl.hxx:82
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: fillctrl.cxx:1074
static void ReleaseFocus_Impl()
Definition: fillctrl.cxx:620
FillControl(vcl::Window *pParent, const css::uno::Reference< css::frame::XFrame > &rFrame)
Definition: fillctrl.cxx:590
std::unique_ptr< weld::ComboBox > mxLbFillAttr
Definition: fillctrl.hxx:84
virtual ~FillControl() override
Definition: fillctrl.cxx:682
virtual void dispose() 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 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 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:571
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:1753
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:379
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)
void append(const OUString &rId, const OUString &rStr)
virtual OUString get_active_text() const=0
virtual void clear()=0
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:615
IMPL_LINK_NOARG(FillControl, TypeFocusHdl, weld::Widget &, void)
Definition: fillctrl.cxx:652
constexpr OUStringLiteral TMP_STR_BEGIN
Definition: fillctrl.cxx:31
IMPL_LINK(FillControl, TypeKeyInputHdl, const KeyEvent &, rKEvt, bool)
Definition: fillctrl.cxx:631
constexpr sal_uInt16 KEY_ESCAPE
constexpr sal_uInt16 KEY_TAB
sal_uInt16 nPos
sal_uInt16 nCode
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
Count
sal_Int16 nId
SfxItemState
constexpr OUStringLiteral PATTERN