91 null derefs seen in crashreporting report
[LibreOffice.git] / sw / source / uibase / sidebar / PageStylesPanel.cxx
blob2a1de2ebe3001f5e0bd1cc102b276f30be0dec5f
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 .
19 #include <sal/config.h>
20 #include <svl/intitem.hxx>
21 #include <svx/colorbox.hxx>
22 #include <svx/drawitem.hxx>
23 #include <svx/xfillit0.hxx>
24 #include <svx/xflclit.hxx>
25 #include <svx/xflgrit.hxx>
26 #include <svx/xflhtit.hxx>
27 #include <svx/xbtmpit.hxx>
28 #include <svx/itemwin.hxx>
29 #include <svx/SvxNumOptionsTabPageHelper.hxx>
30 #include "PageStylesPanel.hxx"
31 #include <sfx2/sidebar/Panel.hxx>
32 #include <sfx2/dispatch.hxx>
33 #include <sfx2/bindings.hxx>
34 #include <sfx2/objsh.hxx>
35 #include <cmdid.h>
37 using namespace ::com::sun::star;
39 namespace sw::sidebar{
41 namespace {
43 enum eFillStyle
45 NONE,
46 SOLID,
47 GRADIENT,
48 HATCH,
49 BITMAP,
50 PATTERN
55 const SvxPageUsage aArr[] =
57 SvxPageUsage::All,
58 SvxPageUsage::Mirror,
59 SvxPageUsage::Right,
60 SvxPageUsage::Left
64 static sal_uInt16 PageUsageToPos_Impl( SvxPageUsage nUsage )
66 for ( size_t i = 0; i < SAL_N_ELEMENTS(aArr); ++i )
67 if ( aArr[i] == nUsage )
68 return i;
69 return 3;
72 static SvxPageUsage PosToPageUsage_Impl( sal_uInt16 nPos )
74 if ( nPos >= SAL_N_ELEMENTS(aArr) )
75 return SvxPageUsage::NONE;
76 return aArr[nPos];
79 std::unique_ptr<PanelLayout> PageStylesPanel::Create(weld::Widget* pParent, SfxBindings* pBindings)
81 if( pParent == nullptr )
82 throw ::com::sun::star::lang::IllegalArgumentException("no parent window given to PageStylesPanel::Create", nullptr, 0);
83 if( pBindings == nullptr )
84 throw ::com::sun::star::lang::IllegalArgumentException("no SfxBindings given to PageStylesPanel::Create", nullptr, 0);
86 return std::make_unique<PageStylesPanel>(pParent, pBindings);
89 PageStylesPanel::PageStylesPanel(
90 weld::Widget* pParent,
91 SfxBindings* pBindings
92 ) :
93 PanelLayout(pParent, "PageStylesPanel", "modules/swriter/ui/pagestylespanel.ui"),
94 mpBindings( pBindings ),
95 mpPageColumnItem( new SfxInt16Item(SID_ATTR_PAGE_COLUMN) ),
96 mpPageItem( new SvxPageItem(SID_ATTR_PAGE) ),
97 maPageColumnControl(SID_ATTR_PAGE_COLUMN, *pBindings, *this),
98 maPageNumFormatControl( SID_ATTR_PAGE, *pBindings, *this ),
99 maBgColorControl( SID_ATTR_PAGE_COLOR, *pBindings, *this ),
100 maBgHatchingControl( SID_ATTR_PAGE_HATCH, *pBindings, *this ),
101 maBgGradientControl( SID_ATTR_PAGE_GRADIENT, *pBindings, *this ),
102 maBgBitmapControl( SID_ATTR_PAGE_BITMAP, *pBindings, *this ),
103 maBgFillStyleControl(SID_ATTR_PAGE_FILLSTYLE, *pBindings, *this),
104 mxBgColorLB(new ColorListBox(m_xBuilder->weld_menu_button("lbcolor"), [this]{ return GetFrameWeld(); })),
105 mxBgHatchingLB(m_xBuilder->weld_combo_box("lbhatching")),
106 mxBgGradientLB(new ColorListBox(m_xBuilder->weld_menu_button("lbgradient"), [this]{ return GetFrameWeld(); })),
107 mxBgBitmapLB(m_xBuilder->weld_combo_box("lbbitmap")),
108 mxLayoutSelectLB(m_xBuilder->weld_combo_box("layoutbox")),
109 mxColumnCount(m_xBuilder->weld_combo_box("columnbox")),
110 mxNumberSelectLB(new SvxPageNumberListBox(m_xBuilder->weld_combo_box("numberbox"))),
111 mxBgFillType(m_xBuilder->weld_combo_box("bgselect")),
112 mxCustomEntry(m_xBuilder->weld_label("customlabel"))
114 Initialize();
117 PageStylesPanel::~PageStylesPanel()
119 mxColumnCount.reset();
120 mxNumberSelectLB.reset();
121 mxBgFillType.reset();
122 mxBgColorLB.reset();
123 mxBgHatchingLB.reset();
124 mxBgGradientLB.reset();
125 mxBgBitmapLB.reset();
126 mxLayoutSelectLB.reset();
127 mxCustomEntry.reset();
129 maBgBitmapControl.dispose();
130 maBgColorControl.dispose();
131 maBgFillStyleControl.dispose();
132 maBgGradientControl.dispose();
133 maBgHatchingControl.dispose();
134 maPageColumnControl.dispose();
135 maPageNumFormatControl.dispose();
138 void PageStylesPanel::Initialize()
140 SvxFillTypeBox::Fill(*mxBgFillType);
142 aCustomEntry = mxCustomEntry->get_label();
143 mpBindings->Invalidate(SID_ATTR_PAGE_COLUMN);
144 mpBindings->Invalidate(SID_ATTR_PAGE);
145 mpBindings->Invalidate(SID_ATTR_PAGE_FILLSTYLE);
146 Update();
148 mxColumnCount->connect_changed( LINK(this, PageStylesPanel, ModifyColumnCountHdl) );
149 SvxNumOptionsTabPageHelper::GetI18nNumbering(mxNumberSelectLB->get_widget(), ::std::numeric_limits<sal_uInt16>::max());
150 mxNumberSelectLB->connect_changed( LINK(this, PageStylesPanel, ModifyNumberingHdl) );
151 mxLayoutSelectLB->connect_changed( LINK(this, PageStylesPanel, ModifyLayoutHdl) );
152 mxBgFillType->connect_changed( LINK(this, PageStylesPanel, ModifyFillStyleHdl));
153 mxBgColorLB->SetSelectHdl( LINK(this, PageStylesPanel, ModifyFillColorListHdl));
154 mxBgGradientLB->SetSelectHdl( LINK(this, PageStylesPanel, ModifyFillColorListHdl));
155 mxBgHatchingLB->connect_changed( LINK(this, PageStylesPanel, ModifyFillColorHdl));
156 mxBgBitmapLB->connect_changed( LINK(this, PageStylesPanel, ModifyFillColorHdl));
159 void PageStylesPanel::Update()
161 const eFillStyle eXFS = static_cast<eFillStyle>(mxBgFillType->get_active());
162 SfxObjectShell* pSh = SfxObjectShell::Current();
163 if (!pSh)
165 SAL_WARN("sw.ui", "PageStylesPanel::Update(): no SfxObjectShell found");
166 return;
168 switch(eXFS)
170 case NONE:
172 mxBgColorLB->hide();
173 mxBgHatchingLB->hide();
174 mxBgGradientLB->hide();
175 mxBgBitmapLB->hide();
177 break;
178 case SOLID:
180 mxBgBitmapLB->hide();
181 mxBgGradientLB->hide();
182 mxBgHatchingLB->hide();
183 mxBgColorLB->show();
184 const Color aColor = GetColorSetOrDefault();
185 mxBgColorLB->SelectEntry(aColor);
187 break;
188 case GRADIENT:
190 mxBgBitmapLB->hide();
191 mxBgHatchingLB->hide();
192 mxBgColorLB->show();
193 mxBgGradientLB->show();
195 const XGradient xGradient = GetGradientSetOrDefault();
196 const Color aStartColor = xGradient.GetStartColor();
197 mxBgColorLB->SelectEntry(aStartColor);
198 const Color aEndColor = xGradient.GetEndColor();
199 mxBgGradientLB->SelectEntry(aEndColor);
201 break;
203 case HATCH:
205 mxBgColorLB->hide();
206 mxBgGradientLB->hide();
207 mxBgBitmapLB->hide();
208 mxBgHatchingLB->show();
209 mxBgHatchingLB->clear();
210 SvxFillAttrBox::Fill(*mxBgHatchingLB, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
212 const OUString aHatchName = GetHatchingSetOrDefault();
213 mxBgHatchingLB->set_active_text( aHatchName );
215 break;
217 case BITMAP:
218 case PATTERN:
220 mxBgColorLB->hide();
221 mxBgGradientLB->hide();
222 mxBgHatchingLB->hide();
223 mxBgBitmapLB->show();
224 mxBgBitmapLB->clear();
225 OUString aBitmapName;
227 if( eXFS == BITMAP )
229 SvxFillAttrBox::Fill(*mxBgBitmapLB, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
230 aBitmapName = GetBitmapSetOrDefault();
232 else
234 SvxFillAttrBox::Fill(*mxBgBitmapLB, pSh->GetItem(SID_PATTERN_LIST)->GetPatternList());
235 aBitmapName = GetPatternSetOrDefault();
238 mxBgBitmapLB->set_active_text( aBitmapName );
240 break;
242 default:
243 break;
246 // Need to do a relayouting, otherwise the panel size is not updated after show / hide controls
247 if (m_pPanel)
248 m_pPanel->TriggerDeckLayouting();
251 Color const & PageStylesPanel::GetColorSetOrDefault()
253 if ( !mpBgColorItem )
254 mpBgColorItem.reset( new XFillColorItem( OUString(), Color(0x72, 0x9f, 0xcf) ) );
256 return mpBgColorItem->GetColorValue();
259 XGradient const & PageStylesPanel::GetGradientSetOrDefault()
261 if( !mpBgGradientItem )
263 SfxObjectShell* pSh = SfxObjectShell::Current();
264 const SvxGradientListItem * pGradListItem = pSh->GetItem(SID_GRADIENT_LIST);
265 const XGradient aGradient = pGradListItem->GetGradientList()->GetGradient(0)->GetGradient();
266 const OUString aGradientName = pGradListItem->GetGradientList()->GetGradient(0)->GetName();
268 mpBgGradientItem.reset( new XFillGradientItem( aGradientName, aGradient ) );
271 return mpBgGradientItem->GetGradientValue();
274 OUString const & PageStylesPanel::GetHatchingSetOrDefault()
276 if( !mpBgHatchItem )
278 SfxObjectShell* pSh = SfxObjectShell::Current();
279 const SvxHatchListItem * pHatchListItem = pSh->GetItem(SID_HATCH_LIST);
280 const XHatch aHatch = pHatchListItem->GetHatchList()->GetHatch(0)->GetHatch();
281 const OUString aHatchName = pHatchListItem->GetHatchList()->GetHatch(0)->GetName();
283 mpBgHatchItem.reset( new XFillHatchItem( aHatchName, aHatch ) );
286 return mpBgHatchItem->GetName();
289 OUString const & PageStylesPanel::GetBitmapSetOrDefault()
291 if( !mpBgBitmapItem || mpBgBitmapItem->isPattern() )
293 SfxObjectShell* pSh = SfxObjectShell::Current();
294 const SvxBitmapListItem * pBmpListItem = pSh->GetItem(SID_BITMAP_LIST);
295 const GraphicObject aGraphObj = pBmpListItem->GetBitmapList()->GetBitmap(0)->GetGraphicObject();
296 const OUString aBmpName = pBmpListItem->GetBitmapList()->GetBitmap(0)->GetName();
298 mpBgBitmapItem.reset( new XFillBitmapItem( aBmpName, aGraphObj ) );
301 return mpBgBitmapItem->GetName();
304 OUString const & PageStylesPanel::GetPatternSetOrDefault()
306 if( !mpBgBitmapItem || !mpBgBitmapItem->isPattern() )
308 SfxObjectShell* pSh = SfxObjectShell::Current();
309 const SvxPatternListItem * pPatternListItem = pSh->GetItem(SID_PATTERN_LIST);
310 const GraphicObject aGraphObj = pPatternListItem->GetPatternList()->GetBitmap(0)->GetGraphicObject();
311 const OUString aPatternName = pPatternListItem->GetPatternList()->GetBitmap(0)->GetName();
313 mpBgBitmapItem.reset( new XFillBitmapItem( aPatternName, aGraphObj ) );
316 return mpBgBitmapItem->GetName();
319 void PageStylesPanel::NotifyItemUpdate(
320 const sal_uInt16 nSid,
321 const SfxItemState eState,
322 const SfxPoolItem* pState)
324 if (!mxColumnCount) //disposed
325 return;
327 switch(nSid)
329 case SID_ATTR_PAGE_COLUMN:
331 if ( eState >= SfxItemState::DEFAULT &&
332 dynamic_cast< const SfxInt16Item *>( pState ) )
334 mpPageColumnItem.reset( static_cast<SfxInt16Item*>(pState->Clone()) );
335 if(mpPageColumnItem->GetValue() <= 5)
337 mxColumnCount->set_active(mpPageColumnItem->GetValue() - 1);
338 int nIndex = mxColumnCount->find_text(aCustomEntry);
339 if (nIndex != -1)
340 mxColumnCount->remove(nIndex);
342 else
344 if (mxColumnCount->find_text(aCustomEntry) == -1)
345 mxColumnCount->append_text(aCustomEntry);
346 mxColumnCount->set_active_text(aCustomEntry);
350 break;
352 case SID_ATTR_PAGE:
354 if( eState >= SfxItemState::DEFAULT &&
355 dynamic_cast< const SvxPageItem*>( pState ) )
357 mpPageItem.reset( static_cast<SvxPageItem*>(pState->Clone()) );
358 SvxNumType eNumType = mpPageItem->GetNumType();
359 mxNumberSelectLB->set_active_id(eNumType);
361 SvxPageUsage nUse = mpPageItem->GetPageUsage();
362 mxLayoutSelectLB->set_active( PageUsageToPos_Impl( nUse ) );
365 break;
367 case SID_ATTR_PAGE_COLOR:
369 if(eState >= SfxItemState::DEFAULT)
371 mxBgFillType->set_active( static_cast<sal_Int32>(SOLID) );
372 mpBgColorItem.reset(pState ? static_cast< XFillColorItem* >(pState->Clone()) : nullptr);
373 Update();
376 break;
378 case SID_ATTR_PAGE_HATCH:
380 if(eState >= SfxItemState::DEFAULT)
382 mxBgFillType->set_active( static_cast<sal_Int32>(HATCH) );
383 mpBgHatchItem.reset(pState ? static_cast < XFillHatchItem* >(pState->Clone()) : nullptr);
384 Update();
387 break;
389 case SID_ATTR_PAGE_GRADIENT:
391 if(eState >= SfxItemState::DEFAULT)
393 mxBgFillType->set_active( static_cast<sal_Int32>(GRADIENT) );
394 mpBgGradientItem.reset(pState ? static_cast< XFillGradientItem* >(pState->Clone()) : nullptr);
395 Update();
398 break;
399 case SID_ATTR_PAGE_BITMAP:
401 if(eState >= SfxItemState::DEFAULT)
403 mpBgBitmapItem.reset(pState ? static_cast< XFillBitmapItem* >(pState->Clone()) : nullptr);
404 if (mpBgBitmapItem)
406 if (mpBgBitmapItem->isPattern())
407 mxBgFillType->set_active( static_cast<sal_Int32>(PATTERN) );
408 else
409 mxBgFillType->set_active( static_cast<sal_Int32>(BITMAP) );
411 Update();
414 break;
416 case SID_ATTR_PAGE_FILLSTYLE:
418 const XFillStyleItem* pFillStyleItem = nullptr;
419 if (eState >= SfxItemState::DEFAULT)
420 pFillStyleItem = dynamic_cast< const XFillStyleItem* >(pState);
421 if (pFillStyleItem)
423 css::drawing::FillStyle eXFS = pFillStyleItem->GetValue();
424 switch(eXFS)
426 case drawing::FillStyle_NONE:
427 mxBgFillType->set_active( static_cast<sal_Int32>(NONE) );
428 break;
429 case drawing::FillStyle_SOLID:
430 mxBgFillType->set_active( static_cast<sal_Int32>(SOLID) );
431 break;
432 case drawing::FillStyle_GRADIENT:
433 mxBgFillType->set_active( static_cast<sal_Int32>(GRADIENT) );
434 break;
435 case drawing::FillStyle_HATCH:
436 mxBgFillType->set_active( static_cast<sal_Int32>(HATCH) );
437 break;
438 case drawing::FillStyle_BITMAP:
439 if (mpBgBitmapItem->isPattern())
440 mxBgFillType->set_active( static_cast<sal_Int32>(PATTERN) );
441 else
442 mxBgFillType->set_active( static_cast<sal_Int32>(BITMAP) );
443 break;
444 default:
445 break;
447 Update();
450 break;
452 default:
453 break;
457 IMPL_LINK_NOARG( PageStylesPanel, ModifyColumnCountHdl, weld::ComboBox&, void )
459 sal_uInt16 nColumnType = mxColumnCount->get_active() + 1;
460 mpPageColumnItem->SetValue( nColumnType );
461 mpBindings->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_COLUMN,
462 SfxCallMode::RECORD, { mpPageColumnItem.get() });
465 IMPL_LINK_NOARG( PageStylesPanel, ModifyNumberingHdl, weld::ComboBox&, void )
467 SvxNumType nEntryData = mxNumberSelectLB->get_active_id();
468 mpPageItem->SetNumType(nEntryData);
469 mpBindings->GetDispatcher()->ExecuteList(SID_ATTR_PAGE, SfxCallMode::RECORD, { mpPageItem.get() });
472 IMPL_LINK_NOARG( PageStylesPanel, ModifyLayoutHdl, weld::ComboBox&, void )
474 sal_uInt16 nUse = mxLayoutSelectLB->get_active();
475 mpPageItem->SetPageUsage(PosToPageUsage_Impl(nUse));
476 mpBindings->GetDispatcher()->ExecuteList(SID_ATTR_PAGE, SfxCallMode::RECORD, { mpPageItem.get() });
479 IMPL_LINK_NOARG(PageStylesPanel, ModifyFillStyleHdl, weld::ComboBox&, void)
481 const eFillStyle eXFS = static_cast<eFillStyle>(mxBgFillType->get_active());
482 Update();
484 switch (eXFS)
486 case NONE:
488 const XFillStyleItem aXFillStyleItem(drawing::FillStyle_NONE);
489 GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_FILLSTYLE, SfxCallMode::RECORD, { &aXFillStyleItem });
491 break;
493 case SOLID:
495 XFillColorItem aItem( OUString(), mpBgColorItem->GetColorValue() );
496 GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_COLOR, SfxCallMode::RECORD, { &aItem });
498 break;
500 case GRADIENT:
502 XFillGradientItem aItem( mpBgGradientItem->GetName(), mpBgGradientItem->GetGradientValue() );
503 GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_GRADIENT, SfxCallMode::RECORD, { &aItem });
505 break;
507 case HATCH:
509 XFillHatchItem aItem( mpBgHatchItem->GetName(), mpBgHatchItem->GetHatchValue() );
510 GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_HATCH, SfxCallMode::RECORD, { &aItem });
512 break;
514 case BITMAP:
515 case PATTERN:
517 XFillBitmapItem aItem( mpBgBitmapItem->GetName(), mpBgBitmapItem->GetGraphicObject() );
518 GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_BITMAP, SfxCallMode::RECORD, { &aItem });
520 break;
522 default:
523 break;
527 void PageStylesPanel::ModifyFillColor()
529 const eFillStyle eXFS = static_cast<eFillStyle>(mxBgFillType->get_active());
530 SfxObjectShell* pSh = SfxObjectShell::Current();
531 switch(eXFS)
533 case SOLID:
535 XFillColorItem aItem(OUString(), mxBgColorLB->GetSelectEntryColor());
536 GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_COLOR, SfxCallMode::RECORD, { &aItem });
538 break;
539 case GRADIENT:
541 XGradient aGradient;
542 aGradient.SetStartColor(mxBgColorLB->GetSelectEntryColor());
543 aGradient.SetEndColor(mxBgGradientLB->GetSelectEntryColor());
545 XFillGradientItem aItem(aGradient);
546 GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_GRADIENT, SfxCallMode::RECORD, { &aItem });
548 break;
549 case HATCH:
551 const SvxHatchListItem * pHatchListItem = pSh->GetItem(SID_HATCH_LIST);
552 sal_uInt16 nPos = mxBgHatchingLB->get_active();
553 XHatch aHatch = pHatchListItem->GetHatchList()->GetHatch(nPos)->GetHatch();
554 const OUString aHatchName = pHatchListItem->GetHatchList()->GetHatch(nPos)->GetName();
556 XFillHatchItem aItem(aHatchName, aHatch);
557 GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_HATCH, SfxCallMode::RECORD, { &aItem });
559 break;
560 case BITMAP:
561 case PATTERN:
563 sal_Int16 nPos = mxBgBitmapLB->get_active();
564 GraphicObject aBitmap;
565 OUString aBitmapName;
567 if ( eXFS == BITMAP )
569 SvxBitmapListItem const * pBitmapListItem = pSh->GetItem(SID_BITMAP_LIST);
570 aBitmap = pBitmapListItem->GetBitmapList()->GetBitmap(nPos)->GetGraphicObject();
571 aBitmapName = pBitmapListItem->GetBitmapList()->GetBitmap(nPos)->GetName();
573 else
575 SvxPatternListItem const * pPatternListItem = pSh->GetItem(SID_PATTERN_LIST);
576 aBitmap = pPatternListItem->GetPatternList()->GetBitmap(nPos)->GetGraphicObject();
577 aBitmapName = pPatternListItem->GetPatternList()->GetBitmap(nPos)->GetName();
580 XFillBitmapItem aItem(aBitmapName, aBitmap);
581 GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_BITMAP, SfxCallMode::RECORD, { &aItem });
583 break;
584 default:
585 break;
589 IMPL_LINK_NOARG(PageStylesPanel, ModifyFillColorHdl, weld::ComboBox&, void)
591 ModifyFillColor();
594 IMPL_LINK_NOARG(PageStylesPanel, ModifyFillColorListHdl, ColorListBox&, void)
596 ModifyFillColor();
601 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */