1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svx/colorbox.hxx>
21 #include <svx/svxids.hrc>
22 #include <svtools/unitconv.hxx>
24 #include <svx/xfillit0.hxx>
25 #include <svx/xflclit.hxx>
26 #include <svx/xflgrit.hxx>
27 #include <svx/xflhtit.hxx>
28 #include <svx/xbtmpit.hxx>
29 #include <svx/sdmetitm.hxx>
30 #include <svx/sdooitm.hxx>
31 #include <svx/sdprcitm.hxx>
32 #include <svx/sdshcitm.hxx>
33 #include <svx/sdshitm.hxx>
34 #include <svx/sdshtitm.hxx>
35 #include <svx/sdsxyitm.hxx>
36 #include <svx/drawitem.hxx>
37 #include <svx/xfltrit.hxx>
38 #include <cuitabarea.hxx>
39 #include <svx/dlgutil.hxx>
40 #include <cuitabline.hxx>
42 using namespace com::sun::star
;
44 const WhichRangesContainer
SvxShadowTabPage::pShadowRanges(svl::Items
<
45 SDRATTR_SHADOWCOLOR
, SDRATTR_SHADOWTRANSPARENCE
,
46 SDRATTR_SHADOWBLUR
, SDRATTR_SHADOWBLUR
,
47 SID_ATTR_FILL_SHADOW
, SID_ATTR_FILL_SHADOW
,
48 SID_ATTR_SHADOW_BLUR
, SID_ATTR_SHADOW_BLUR
,
49 SID_ATTR_SHADOW_TRANSPARENCE
, SID_ATTR_SHADOW_YDISTANCE
52 SvxShadowTabPage::SvxShadowTabPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rInAttrs
)
53 : SvxTabPage(pPage
, pController
, "cui/ui/shadowtabpage.ui", "ShadowTabPage", rInAttrs
)
54 , m_rOutAttrs(rInAttrs
)
55 , m_pnColorListState(nullptr)
56 , m_nPageType(PageType::Area
)
58 , m_aXFillAttr(rInAttrs
.GetPool())
59 , m_rXFSet(m_aXFillAttr
.GetItemSet())
60 , m_aCtlPosition(this)
61 , m_xTsbShowShadow(m_xBuilder
->weld_check_button("TSB_SHOW_SHADOW"))
62 , m_xGridShadow(m_xBuilder
->weld_widget("gridSHADOW"))
63 , m_xMtrDistance(m_xBuilder
->weld_metric_spin_button("MTR_FLD_DISTANCE", FieldUnit::CM
))
64 , m_xLbShadowColor(new ColorListBox(m_xBuilder
->weld_menu_button("LB_SHADOW_COLOR"),
65 [this]{ return GetDialogController()->getDialog(); }))
66 , m_xMtrTransparent(m_xBuilder
->weld_metric_spin_button("MTR_SHADOW_TRANSPARENT", FieldUnit::PERCENT
))
67 , m_xLbShadowBlurMetric(m_xBuilder
->weld_metric_spin_button("LB_SHADOW_BLUR", FieldUnit::POINT
))
68 , m_xCtlPosition(new weld::CustomWeld(*m_xBuilder
, "CTL_POSITION", m_aCtlPosition
))
69 , m_xCtlXRectPreview(new weld::CustomWeld(*m_xBuilder
, "CTL_COLOR_PREVIEW", m_aCtlXRectPreview
))
71 // this page needs ExchangeSupport
75 FieldUnit eFUnit
= GetModuleFieldUnit( rInAttrs
);
81 eFUnit
= FieldUnit::MM
;
83 default: ;//prevent warning
85 SetFieldUnit( *m_xMtrDistance
, eFUnit
);
88 SfxItemPool
* pPool
= m_rOutAttrs
.GetPool();
89 DBG_ASSERT( pPool
, "Where is the pool?" );
90 m_ePoolUnit
= pPool
->GetMetric( SDRATTR_SHADOWXDIST
);
92 // setting the output device
93 drawing::FillStyle eXFS
= drawing::FillStyle_SOLID
;
94 if( m_rOutAttrs
.GetItemState( XATTR_FILLSTYLE
) != SfxItemState::DONTCARE
)
96 eXFS
= static_cast<const XFillStyleItem
&>( m_rOutAttrs
.
97 Get( GetWhich( XATTR_FILLSTYLE
) ) ).GetValue();
100 case drawing::FillStyle_SOLID
:
101 if( SfxItemState::DONTCARE
!= m_rOutAttrs
.GetItemState( XATTR_FILLCOLOR
) )
103 m_rXFSet
.Put( m_rOutAttrs
.Get( XATTR_FILLCOLOR
) );
107 case drawing::FillStyle_GRADIENT
:
108 if( SfxItemState::DONTCARE
!= m_rOutAttrs
.GetItemState( XATTR_FILLGRADIENT
) )
110 m_rXFSet
.Put( m_rOutAttrs
.Get( XATTR_FILLGRADIENT
) );
114 case drawing::FillStyle_HATCH
:
115 if( SfxItemState::DONTCARE
!= m_rOutAttrs
.GetItemState( XATTR_FILLHATCH
) )
117 m_rXFSet
.Put( m_rOutAttrs
.Get( XATTR_FILLHATCH
) );
121 case drawing::FillStyle_BITMAP
:
123 if( SfxItemState::DONTCARE
!= m_rOutAttrs
.GetItemState( XATTR_FILLBITMAP
) )
125 m_rXFSet
.Put( m_rOutAttrs
.Get( XATTR_FILLBITMAP
) );
129 case drawing::FillStyle_NONE
: break;
135 m_rXFSet
.Put( XFillColorItem( OUString(), COL_LIGHTRED
) );
138 if(drawing::FillStyle_NONE
== eXFS
)
141 // fallback to solid fillmode when no fill mode is provided to have
142 // a reasonable shadow preview. The used color will be a set one or
143 // the default (currently blue8)
144 eXFS
= drawing::FillStyle_SOLID
;
147 m_rXFSet
.Put( XFillStyleItem( eXFS
) );
148 m_aCtlXRectPreview
.SetRectangleAttributes(m_aXFillAttr
.GetItemSet());
150 m_xTsbShowShadow
->connect_toggled(LINK( this, SvxShadowTabPage
, ClickShadowHdl_Impl
));
151 m_xLbShadowColor
->SetSelectHdl( LINK( this, SvxShadowTabPage
, SelectShadowHdl_Impl
) );
152 Link
<weld::MetricSpinButton
&,void> aLink
= LINK( this, SvxShadowTabPage
, ModifyShadowHdl_Impl
);
153 m_xLbShadowBlurMetric
->connect_value_changed(aLink
);
154 m_xMtrTransparent
->connect_value_changed(aLink
);
155 m_xMtrDistance
->connect_value_changed(aLink
);
158 SvxShadowTabPage::~SvxShadowTabPage()
160 m_xCtlXRectPreview
.reset();
161 m_xLbShadowColor
.reset();
162 m_xCtlPosition
.reset();
163 m_xLbShadowBlurMetric
.reset();
166 void SvxShadowTabPage::ActivatePage( const SfxItemSet
& rSet
)
168 const SfxUInt16Item
* pPageTypeItem
= rSet
.GetItem
<SfxUInt16Item
>(SID_PAGE_TYPE
, false);
170 SetPageType(static_cast<PageType
>(pPageTypeItem
->GetValue()));
172 if( m_nDlgType
!= 0 )
175 if( !m_pColorList
.is() )
179 if( *m_pnColorListState
& ChangeType::CHANGED
||
180 *m_pnColorListState
& ChangeType::MODIFIED
)
182 if( *m_pnColorListState
& ChangeType::CHANGED
)
184 SvxAreaTabDialog
* pArea
= dynamic_cast<SvxAreaTabDialog
*>(GetDialogController());
187 m_pColorList
= pArea
->GetNewColorList();
191 SvxLineTabDialog
* pLine
= dynamic_cast<SvxLineTabDialog
*>(GetDialogController());
193 m_pColorList
= pLine
->GetNewColorList();
197 SfxItemSet
rAttribs( rSet
);
198 // rSet contains shadow attributes too, but we want
199 // to use it for updating rectangle attributes only,
200 // so set the shadow to none here
201 SdrOnOffItem
aItem( makeSdrShadowItem( false ));
202 rAttribs
.Put( aItem
);
204 m_aCtlXRectPreview
.SetRectangleAttributes( rAttribs
);
205 ModifyShadowHdl_Impl( *m_xMtrTransparent
);
207 m_nPageType
= PageType::Shadow
;
211 DeactivateRC
SvxShadowTabPage::DeactivatePage( SfxItemSet
* _pSet
)
214 FillItemSet( _pSet
);
216 return DeactivateRC::LeavePage
;
220 bool SvxShadowTabPage::FillItemSet( SfxItemSet
* rAttrs
)
222 bool bModified
= false;
224 const SfxPoolItem
* pOld
= nullptr;
226 if (m_xTsbShowShadow
->get_state_changed_from_saved())
228 TriState eState
= m_xTsbShowShadow
->get_state();
229 assert(eState
!= TRISTATE_INDET
);
230 // given how m_xTsbShowShadow is set up and saved in Reset(),
231 // eState == TRISTATE_INDET would imply
232 // !IsValueChangedFromSaved()
233 SdrOnOffItem
aItem( makeSdrShadowItem(eState
== TRISTATE_TRUE
) );
234 pOld
= GetOldItem( *rAttrs
, SDRATTR_SHADOW
);
235 if ( !pOld
|| !( *static_cast<const SdrOnOffItem
*>(pOld
) == aItem
) )
237 rAttrs
->Put( aItem
);
243 // a bit intricate inquiry whether there was something changed,
244 // as the items can't be displayed directly on controls
245 sal_Int32 nX
= 0, nY
= 0;
246 sal_Int32 nXY
= GetCoreValue( *m_xMtrDistance
, m_ePoolUnit
);
248 switch (m_aCtlPosition
.GetActualRP())
250 case RectPoint::LT
: nX
= nY
= -nXY
; break;
251 case RectPoint::MT
: nY
= -nXY
; break;
252 case RectPoint::RT
: nX
= nXY
; nY
= -nXY
; break;
253 case RectPoint::LM
: nX
= -nXY
; break;
254 case RectPoint::RM
: nX
= nXY
; break;
255 case RectPoint::LB
: nX
= -nXY
; nY
= nXY
; break;
256 case RectPoint::MB
: nY
= nXY
; break;
257 case RectPoint::RB
: nX
= nY
= nXY
; break;
258 case RectPoint::MM
: break;
261 // If the values of the shadow distances==SfxItemState::DONTCARE and the displayed
262 // string in the respective MetricField=="", then the comparison of the old
263 // and the new distance values would return a wrong result because in such a
264 // case the new distance values would match the default values of the MetricField !!!!
265 if ( !m_xMtrDistance
->get_text().isEmpty() ||
266 m_rOutAttrs
.GetItemState( SDRATTR_SHADOWXDIST
) != SfxItemState::DONTCARE
||
267 m_rOutAttrs
.GetItemState( SDRATTR_SHADOWYDIST
) != SfxItemState::DONTCARE
)
269 sal_Int32 nOldX
= 9876543; // impossible value, so DontCare
270 sal_Int32 nOldY
= 9876543;
271 if( m_rOutAttrs
.GetItemState( SDRATTR_SHADOWXDIST
) != SfxItemState::DONTCARE
&&
272 m_rOutAttrs
.GetItemState( SDRATTR_SHADOWYDIST
) != SfxItemState::DONTCARE
)
274 nOldX
= m_rOutAttrs
.Get( SDRATTR_SHADOWXDIST
).GetValue();
275 nOldY
= m_rOutAttrs
.Get( SDRATTR_SHADOWYDIST
).GetValue();
277 SdrMetricItem
aXItem( makeSdrShadowXDistItem(nX
) );
278 pOld
= GetOldItem( *rAttrs
, SDRATTR_SHADOWXDIST
);
280 ( !pOld
|| !( *static_cast<const SdrMetricItem
*>(pOld
) == aXItem
) ) )
282 rAttrs
->Put( aXItem
);
285 SdrMetricItem
aYItem( makeSdrShadowYDistItem(nY
) );
286 pOld
= GetOldItem( *rAttrs
, SDRATTR_SHADOWYDIST
);
288 ( !pOld
|| !( *static_cast<const SdrMetricItem
*>(pOld
) == aYItem
) ) )
290 rAttrs
->Put( aYItem
);
297 XColorItem
aItem(makeSdrShadowColorItem(m_xLbShadowColor
->GetSelectEntryColor()));
298 pOld
= GetOldItem( *rAttrs
, SDRATTR_SHADOWCOLOR
);
299 if ( !pOld
|| !( *static_cast<const XColorItem
*>(pOld
) == aItem
) )
301 rAttrs
->Put( aItem
);
307 sal_uInt16 nVal
= static_cast<sal_uInt16
>(m_xMtrTransparent
->get_value(FieldUnit::PERCENT
));
308 if (m_xMtrTransparent
->get_value_changed_from_saved())
310 SdrPercentItem
aItem( makeSdrShadowTransparenceItem(nVal
) );
311 pOld
= GetOldItem( *rAttrs
, SDRATTR_SHADOWTRANSPARENCE
);
312 if ( !pOld
|| !( *static_cast<const SdrPercentItem
*>(pOld
) == aItem
) )
314 rAttrs
->Put( aItem
);
319 if (m_xLbShadowBlurMetric
->get_value_changed_from_saved())
321 SdrMetricItem
aItem(SDRATTR_SHADOWBLUR
, m_xLbShadowBlurMetric
->get_value(FieldUnit::MM_100TH
));
322 pOld
= GetOldItem( *rAttrs
, SDRATTR_SHADOWBLUR
);
323 if ( !pOld
|| !( *static_cast<const SdrMetricItem
*>(pOld
) == aItem
) )
325 rAttrs
->Put( aItem
);
330 rAttrs
->Put (CntUInt16Item(SID_PAGE_TYPE
, static_cast<sal_uInt16
>(m_nPageType
)));
336 void SvxShadowTabPage::Reset( const SfxItemSet
* rAttrs
)
338 // all objects can have a shadow
339 // at the moment there are only 8 possible positions where a shadow can be set
341 // has a shadow been set?
342 if( rAttrs
->GetItemState( SDRATTR_SHADOW
) != SfxItemState::DONTCARE
)
344 if( rAttrs
->Get( SDRATTR_SHADOW
).GetValue() )
345 m_xTsbShowShadow
->set_state(TRISTATE_TRUE
);
348 m_xTsbShowShadow
->set_state(TRISTATE_FALSE
);
352 m_xTsbShowShadow
->set_state(TRISTATE_INDET
);
354 // distance (only 8 possible positions),
355 // so there is only one item evaluated
357 if( rAttrs
->GetItemState( SDRATTR_SHADOWXDIST
) != SfxItemState::DONTCARE
&&
358 rAttrs
->GetItemState( SDRATTR_SHADOWYDIST
) != SfxItemState::DONTCARE
)
360 sal_Int32 nX
= rAttrs
->Get( SDRATTR_SHADOWXDIST
).GetValue();
361 sal_Int32 nY
= rAttrs
->Get( SDRATTR_SHADOWYDIST
).GetValue();
364 SetMetricValue( *m_xMtrDistance
, nX
< 0 ? -nX
: nX
, m_ePoolUnit
);
366 SetMetricValue( *m_xMtrDistance
, nY
< 0 ? -nY
: nY
, m_ePoolUnit
);
368 // setting the shadow control
369 if ( nX
< 0 && nY
< 0 ) m_aCtlPosition
.SetActualRP( RectPoint::LT
);
370 else if( nX
== 0 && nY
< 0 ) m_aCtlPosition
.SetActualRP( RectPoint::MT
);
371 else if( nX
> 0 && nY
< 0 ) m_aCtlPosition
.SetActualRP( RectPoint::RT
);
372 else if( nX
< 0 && nY
== 0 ) m_aCtlPosition
.SetActualRP( RectPoint::LM
);
373 // there's no center point anymore
374 else if( nX
== 0 && nY
== 0 ) m_aCtlPosition
.SetActualRP( RectPoint::RB
);
375 else if( nX
> 0 && nY
== 0 ) m_aCtlPosition
.SetActualRP( RectPoint::RM
);
376 else if( nX
< 0 && nY
> 0 ) m_aCtlPosition
.SetActualRP( RectPoint::LB
);
377 else if( nX
== 0 && nY
> 0 ) m_aCtlPosition
.SetActualRP( RectPoint::MB
);
378 else if( nX
> 0 && nY
> 0 ) m_aCtlPosition
.SetActualRP( RectPoint::RB
);
382 // determine default-distance
383 SfxItemPool
* pPool
= m_rOutAttrs
.GetPool();
385 sal_Int32 n
= pPool
->GetDefaultItem(SDRATTR_SHADOWXDIST
).GetValue();
387 n
= pPool
->GetDefaultItem(SDRATTR_SHADOWYDIST
).GetValue();
388 SetMetricValue(*m_xMtrDistance
, std::abs(n
), m_ePoolUnit
);
391 // Tristate, e. g. multiple objects have been marked of which some have a shadow and some don't.
392 // The text (which shall be displayed) of the MetricFields is set to "" and serves as an
393 // identification in the method FillItemSet for the fact that the distance value was NOT changed !!!!
394 m_xMtrDistance
->set_text( "" );
395 m_aCtlPosition
.SetActualRP( RectPoint::MM
);
398 if( rAttrs
->GetItemState( SDRATTR_SHADOWCOLOR
) != SfxItemState::DONTCARE
)
400 m_xLbShadowColor
->SelectEntry( rAttrs
->Get( SDRATTR_SHADOWCOLOR
).GetColorValue() );
403 m_xLbShadowColor
->SetNoSelection();
405 if( rAttrs
->GetItemState( SDRATTR_SHADOWTRANSPARENCE
) != SfxItemState::DONTCARE
)
407 sal_uInt16 nTransp
= rAttrs
->Get( SDRATTR_SHADOWTRANSPARENCE
).GetValue();
408 m_xMtrTransparent
->set_value(nTransp
, FieldUnit::PERCENT
);
411 m_xMtrTransparent
->set_text("");
413 if( rAttrs
->GetItemState( SDRATTR_SHADOWBLUR
) != SfxItemState::DONTCARE
)
415 sal_uInt16 nBlur
= rAttrs
->Get( SDRATTR_SHADOWBLUR
).GetValue();
416 m_xLbShadowBlurMetric
->set_value(nBlur
, FieldUnit::MM_100TH
);
419 m_xLbShadowBlurMetric
->set_text("");
422 m_xMtrDistance
->save_value();
423 m_xLbShadowColor
->SaveValue();
424 m_xTsbShowShadow
->save_state();
425 m_xLbShadowBlurMetric
->save_value();
427 // #66832# This field was not saved, but used to determine changes.
428 // Why? Seems to be the error.
430 m_xMtrTransparent
->save_value();
432 ClickShadowHdl_Impl(*m_xTsbShowShadow
);
433 ModifyShadowHdl_Impl(*m_xMtrTransparent
);
436 std::unique_ptr
<SfxTabPage
> SvxShadowTabPage::Create( weld::Container
* pPage
, weld::DialogController
* pController
,
437 const SfxItemSet
* rAttrs
)
439 return std::make_unique
<SvxShadowTabPage
>(pPage
, pController
, *rAttrs
);
442 IMPL_LINK_NOARG(SvxShadowTabPage
, ClickShadowHdl_Impl
, weld::Toggleable
&, void)
444 if (m_xTsbShowShadow
->get_state() == TRISTATE_FALSE
)
446 m_xGridShadow
->set_sensitive(false);
447 m_xCtlPosition
->set_sensitive(false);
451 m_xGridShadow
->set_sensitive(true);
452 m_xCtlPosition
->set_sensitive(true);
454 m_aCtlPosition
.Invalidate();
455 ModifyShadowHdl_Impl(*m_xMtrTransparent
);
458 IMPL_LINK_NOARG(SvxShadowTabPage
, SelectShadowHdl_Impl
, ColorListBox
&, void)
460 ModifyShadowHdl_Impl(*m_xMtrTransparent
);
463 IMPL_LINK_NOARG(SvxShadowTabPage
, ModifyShadowHdl_Impl
, weld::MetricSpinButton
&, void)
465 if (m_xTsbShowShadow
->get_state() == TRISTATE_TRUE
)
466 m_rXFSet
.Put( XFillStyleItem( drawing::FillStyle_SOLID
) );
468 m_rXFSet
.Put( XFillStyleItem( drawing::FillStyle_NONE
) );
470 m_rXFSet
.Put( XFillColorItem( OUString(), m_xLbShadowColor
->GetSelectEntryColor() ) );
471 sal_uInt16 nVal
= static_cast<sal_uInt16
>(m_xMtrTransparent
->get_value(FieldUnit::PERCENT
));
472 m_rXFSet
.Put( XFillTransparenceItem( nVal
) );
475 sal_Int32 nX
= 0, nY
= 0;
476 sal_Int32 nXY
= GetCoreValue( *m_xMtrDistance
, m_ePoolUnit
);
477 switch( m_aCtlPosition
.GetActualRP() )
479 case RectPoint::LT
: nX
= nY
= -nXY
; break;
480 case RectPoint::MT
: nY
= -nXY
; break;
481 case RectPoint::RT
: nX
= nXY
; nY
= -nXY
; break;
482 case RectPoint::LM
: nX
= -nXY
; break;
483 case RectPoint::RM
: nX
= nXY
; break;
484 case RectPoint::LB
: nX
= -nXY
; nY
= nXY
; break;
485 case RectPoint::MB
: nY
= nXY
; break;
486 case RectPoint::RB
: nX
= nY
= nXY
; break;
487 case RectPoint::MM
: break;
490 m_aCtlXRectPreview
.SetShadowPosition(Point(nX
, nY
));
492 m_aCtlXRectPreview
.SetShadowAttributes(m_aXFillAttr
.GetItemSet());
493 m_aCtlXRectPreview
.Invalidate();
496 void SvxShadowTabPage::PointChanged( weld::DrawingArea
*, RectPoint
)
499 ModifyShadowHdl_Impl( *m_xMtrTransparent
);
502 void SvxShadowTabPage::PageCreated(const SfxAllItemSet
& aSet
)
504 const SvxColorListItem
* pColorListItem
= aSet
.GetItem
<SvxColorListItem
>(SID_COLOR_TABLE
, false);
505 const SfxUInt16Item
* pPageTypeItem
= aSet
.GetItem
<SfxUInt16Item
>(SID_PAGE_TYPE
, false);
506 const SfxUInt16Item
* pDlgTypeItem
= aSet
.GetItem
<SfxUInt16Item
>(SID_DLG_TYPE
, false);
509 SetColorList(pColorListItem
->GetColorList());
511 SetPageType(static_cast<PageType
>(pPageTypeItem
->GetValue()));
513 SetDlgType(pDlgTypeItem
->GetValue());
516 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */