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/.
10 #include <sal/config.h>
12 #include <string_view>
14 #include "ChartAreaPanel.hxx"
16 #include <ChartController.hxx>
17 #include <ChartModel.hxx>
18 #include <ViewElementListProvider.hxx>
19 #include <PropertyHelper.hxx>
21 #include <chartview/DrawModelWrapper.hxx>
22 #include <com/sun/star/chart2/XDiagram.hpp>
24 #include <sfx2/weldutils.hxx>
25 #include <svx/xfltrit.hxx>
26 #include <svx/xflftrit.hxx>
27 #include <svx/xbtmpit.hxx>
28 #include <svx/unomid.hxx>
29 #include <vcl/svapp.hxx>
31 #include <svx/tbcontrl.hxx>
33 namespace chart::sidebar
{
37 SvxColorToolBoxControl
* getColorToolBoxControl(const ToolbarUnoDispatcher
& rColorDispatch
)
39 css::uno::Reference
<css::frame::XToolbarController
> xController
= rColorDispatch
.GetControllerForCommand(u
".uno:FillColor"_ustr
);
40 SvxColorToolBoxControl
* pToolBoxColorControl
= dynamic_cast<SvxColorToolBoxControl
*>(xController
.get());
41 return pToolBoxColorControl
;
44 OUString
getCID(const rtl::Reference
<::chart::ChartModel
>& xModel
)
46 css::uno::Reference
<css::frame::XController
> xController(xModel
->getCurrentController());
47 css::uno::Reference
<css::view::XSelectionSupplier
> xSelectionSupplier(xController
, css::uno::UNO_QUERY
);
48 if (!xSelectionSupplier
.is())
51 css::uno::Any aAny
= xSelectionSupplier
->getSelection();
54 // if no selection, default to diagram wall so sidebar can show some editable properties
55 ChartController
* pController
= dynamic_cast<ChartController
*>(xController
.get());
58 pController
->select( css::uno::Any( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE
, u
"" ) ) );
59 xSelectionSupplier
= css::uno::Reference
<css::view::XSelectionSupplier
>(xController
, css::uno::UNO_QUERY
);
60 if (xSelectionSupplier
.is())
61 aAny
= xSelectionSupplier
->getSelection();
74 css::uno::Reference
<css::beans::XPropertySet
> getPropSet(
75 const rtl::Reference
<::chart::ChartModel
>& xModel
)
77 OUString aCID
= getCID(xModel
);
78 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
=
79 ObjectIdentifier::getObjectPropertySet(aCID
, xModel
);
81 ObjectType eType
= ObjectIdentifier::getObjectType(aCID
);
82 if (eType
== OBJECTTYPE_DIAGRAM
)
84 css::uno::Reference
<css::chart2::XDiagram
> xDiagram(
85 xPropSet
, css::uno::UNO_QUERY
);
89 xPropSet
.set(xDiagram
->getWall());
95 ChartController
* getController(const css::uno::Reference
<css::frame::XModel
>& xModel
)
97 css::uno::Reference
<css::frame::XController
>xController
= xModel
->getCurrentController();
98 if (!xController
.is())
99 throw std::exception();
101 ChartController
* pController
= dynamic_cast<ChartController
*>(xController
.get());
103 throw std::exception();
108 ViewElementListProvider
getViewElementListProvider( const css::uno::Reference
<css::frame::XModel
>& xModel
)
110 ChartController
* pController
= getController(xModel
);
111 ViewElementListProvider aProvider
= pController
->getViewElementListProvider();
115 DrawModelWrapper
* getDrawModelWrapper(const css::uno::Reference
<css::frame::XModel
>& xModel
)
117 ChartController
* pController
= getController(xModel
);
118 return pController
->GetDrawModelWrapper();
121 XFillGradientItem
getXGradientForName(const css::uno::Reference
<css::frame::XModel
>& xModel
,
122 const OUString
& rName
)
124 css::uno::Reference
<css::lang::XMultiServiceFactory
> xFact(xModel
, css::uno::UNO_QUERY
);
125 css::uno::Reference
<css::container::XNameAccess
> xNameAccess(
126 xFact
->createInstance(u
"com.sun.star.drawing.GradientTable"_ustr
), css::uno::UNO_QUERY
);
127 if (!xNameAccess
.is())
128 return XFillGradientItem();
130 if (!xNameAccess
->hasByName(rName
))
131 return XFillGradientItem();
133 css::uno::Any aAny
= xNameAccess
->getByName(rName
);
135 XFillGradientItem aItem
;
136 aItem
.SetName(rName
);
137 aItem
.PutValue(aAny
, MID_FILLGRADIENT
);
143 XFillFloatTransparenceItem
getXTransparencyGradientForName(const css::uno::Reference
<css::frame::XModel
>& xModel
,
144 const OUString
& rName
)
146 css::uno::Reference
<css::lang::XMultiServiceFactory
> xFact(xModel
, css::uno::UNO_QUERY
);
147 css::uno::Reference
<css::container::XNameAccess
> xNameAccess(
148 xFact
->createInstance(u
"com.sun.star.drawing.TransparencyGradientTable"_ustr
), css::uno::UNO_QUERY
);
149 if (!xNameAccess
.is())
150 return XFillFloatTransparenceItem();
152 if (!xNameAccess
->hasByName(rName
))
153 return XFillFloatTransparenceItem();
155 css::uno::Any aAny
= xNameAccess
->getByName(rName
);
157 XFillFloatTransparenceItem aItem
;
158 aItem
.SetName(rName
);
159 aItem
.PutValue(aAny
, MID_FILLGRADIENT
);
160 aItem
.SetEnabled(true);
165 XHatch
getXHatchFromName(const css::uno::Reference
<css::frame::XModel
>& xModel
,
170 ViewElementListProvider aProvider
= getViewElementListProvider(xModel
);
171 XHatchListRef aRef
= aProvider
.GetHatchList();
172 size_t n
= aRef
->Count();
173 for (size_t i
= 0; i
< n
; ++i
)
175 const XHatchEntry
* pHatch
= aRef
->GetHatch(i
);
179 if (pHatch
->GetName().equalsIgnoreAsciiCase(rName
))
181 // we need to update the hatch name
182 rName
= pHatch
->GetName();
183 return pHatch
->GetHatch();
195 GraphicObject
getXBitmapFromName(const css::uno::Reference
<css::frame::XModel
>& xModel
,
196 std::u16string_view rName
)
200 ViewElementListProvider aProvider
= getViewElementListProvider(xModel
);
201 XBitmapListRef aBmpRef
= aProvider
.GetBitmapList();
202 XPatternListRef aPatRef
= aProvider
.GetPatternList();
204 size_t n
= aBmpRef
->Count();
205 for (size_t i
= 0; i
< n
; ++i
)
207 const XBitmapEntry
* pBitmap
= aBmpRef
->GetBitmap(i
);
211 if (pBitmap
->GetName().equalsIgnoreAsciiCase(rName
))
213 return pBitmap
->GetGraphicObject();
217 // perhaps it's a pattern
218 size_t m
= aPatRef
->Count();
219 for (size_t i
= 0; i
< m
; ++i
)
221 const XBitmapEntry
* pBitmap
= aPatRef
->GetBitmap(i
);
225 if (pBitmap
->GetName().equalsIgnoreAsciiCase(rName
))
227 return pBitmap
->GetGraphicObject();
236 return GraphicObject();
242 explicit PreventUpdate(bool& bUpdate
):
259 std::unique_ptr
<PanelLayout
> ChartAreaPanel::Create(
260 weld::Widget
* pParent
,
261 const css::uno::Reference
<css::frame::XFrame
>& rxFrame
,
262 ChartController
* pController
)
264 if (pParent
== nullptr)
265 throw css::lang::IllegalArgumentException(u
"no parent Window given to ChartAxisPanel::Create"_ustr
, nullptr, 0);
267 throw css::lang::IllegalArgumentException(u
"no XFrame given to ChartAxisPanel::Create"_ustr
, nullptr, 1);
269 return std::make_unique
<ChartAreaPanel
>(pParent
, rxFrame
, pController
);
272 ChartAreaPanel::ChartAreaPanel(weld::Widget
* pParent
,
273 const css::uno::Reference
<css::frame::XFrame
>& rxFrame
,
274 ChartController
* pController
):
275 svx::sidebar::AreaPropertyPanelBase(pParent
, rxFrame
),
276 mxModel(pController
->getChartModel()),
277 mxListener(new ChartSidebarModifyListener(this)),
278 mxSelectionListener(new ChartSidebarSelectionListener(this)),
281 maFillColorWrapper(mxModel
, getColorToolBoxControl(*mxColorDispatch
), u
"FillColor"_ustr
)
283 std::vector
<ObjectType
> aAcceptedTypes
{ OBJECTTYPE_PAGE
, OBJECTTYPE_DIAGRAM
,
284 OBJECTTYPE_DATA_SERIES
, OBJECTTYPE_DATA_POINT
,
285 OBJECTTYPE_TITLE
, OBJECTTYPE_LEGEND
};
286 mxSelectionListener
->setAcceptedTypes(std::move(aAcceptedTypes
));
290 ChartAreaPanel::~ChartAreaPanel()
292 doUpdateModel(nullptr);
295 void ChartAreaPanel::Initialize()
297 mxModel
->addModifyListener(mxListener
);
299 css::uno::Reference
<css::view::XSelectionSupplier
> xSelectionSupplier(mxModel
->getCurrentController(), css::uno::UNO_QUERY
);
300 if (xSelectionSupplier
.is())
301 xSelectionSupplier
->addSelectionChangeListener(mxSelectionListener
);
303 SvxColorToolBoxControl
* pToolBoxColor
= getColorToolBoxControl(*mxColorDispatch
);
304 pToolBoxColor
->setColorSelectFunction(maFillColorWrapper
);
309 void ChartAreaPanel::setFillTransparence(const XFillTransparenceItem
& rItem
)
311 PreventUpdate
aProtector(mbUpdate
);
312 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
= getPropSet(mxModel
);
316 xPropSet
->setPropertyValue(u
"FillTransparence"_ustr
, css::uno::Any(rItem
.GetValue()));
319 void ChartAreaPanel::setFillFloatTransparence(
320 const XFillFloatTransparenceItem
& rItem
)
322 PreventUpdate
aProtector(mbUpdate
);
323 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
= getPropSet(mxModel
);
327 if (!rItem
.IsEnabled())
329 xPropSet
->setPropertyValue(u
"FillTransparenceGradientName"_ustr
, css::uno::Any(OUString()));
333 const OUString
& aName
= rItem
.GetName();
334 css::uno::Any aGradientVal
;
335 rItem
.QueryValue(aGradientVal
, MID_FILLGRADIENT
);
336 OUString aNewName
= PropertyHelper::addTransparencyGradientUniqueNameToTable(aGradientVal
, mxModel
, aName
);
337 xPropSet
->setPropertyValue(u
"FillTransparenceGradientName"_ustr
, css::uno::Any(aNewName
));
340 void ChartAreaPanel::setFillStyle(const XFillStyleItem
& rItem
)
342 PreventUpdate
aProtector(mbUpdate
);
343 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
= getPropSet(mxModel
);
347 xPropSet
->setPropertyValue(u
"FillStyle"_ustr
, css::uno::Any(rItem
.GetValue()));
350 void ChartAreaPanel::setFillStyleAndColor(const XFillStyleItem
* pStyleItem
,
351 const XFillColorItem
& rColorItem
)
353 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
= getPropSet(mxModel
);
358 xPropSet
->setPropertyValue(u
"FillStyle"_ustr
, css::uno::Any(pStyleItem
->GetValue()));
359 xPropSet
->setPropertyValue(u
"FillColor"_ustr
, css::uno::Any(rColorItem
.GetValue()));
362 void ChartAreaPanel::setFillStyleAndGradient(const XFillStyleItem
* pStyleItem
,
363 const XFillGradientItem
& rGradientItem
)
365 PreventUpdate
aProtector(mbUpdate
);
366 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
= getPropSet(mxModel
);
371 xPropSet
->setPropertyValue(u
"FillStyle"_ustr
, css::uno::Any(pStyleItem
->GetValue()));
373 const OUString
& aName
= rGradientItem
.GetName();
374 css::uno::Any aGradientVal
;
375 rGradientItem
.QueryValue(aGradientVal
, MID_FILLGRADIENT
);
376 OUString aNewName
= PropertyHelper::addGradientUniqueNameToTable(aGradientVal
, mxModel
, aName
);
377 xPropSet
->setPropertyValue(u
"FillGradientName"_ustr
, css::uno::Any(aNewName
));
380 void ChartAreaPanel::setFillStyleAndHatch(const XFillStyleItem
* pStyleItem
,
381 const XFillHatchItem
& rHatchItem
)
383 PreventUpdate
aProtector(mbUpdate
);
384 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
= getPropSet(mxModel
);
389 xPropSet
->setPropertyValue(u
"FillStyle"_ustr
, css::uno::Any(pStyleItem
->GetValue()));
390 xPropSet
->setPropertyValue(u
"FillHatchName"_ustr
, css::uno::Any(rHatchItem
.GetValue()));
393 void ChartAreaPanel::setFillStyleAndBitmap(const XFillStyleItem
* pStyleItem
,
394 const XFillBitmapItem
& rBitmapItem
)
396 PreventUpdate
aProtector(mbUpdate
);
397 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
= getPropSet(mxModel
);
402 xPropSet
->setPropertyValue(u
"FillStyle"_ustr
, css::uno::Any(pStyleItem
->GetValue()));
404 css::uno::Any aBitmap
;
405 rBitmapItem
.QueryValue(aBitmap
, MID_BITMAP
);
406 const OUString
& aPreferredName
= rBitmapItem
.GetName();
407 aBitmap
<<= PropertyHelper::addBitmapUniqueNameToTable(aBitmap
, mxModel
, aPreferredName
);
408 xPropSet
->setPropertyValue(u
"FillBitmapName"_ustr
, aBitmap
);
411 void ChartAreaPanel::setFillUseBackground(const XFillStyleItem
* pStyleItem
,
412 const XFillUseSlideBackgroundItem
& /*rItem*/)
414 setFillStyle(*pStyleItem
);
417 void ChartAreaPanel::updateData()
419 if (!mbUpdate
|| !mbModelValid
)
422 css::uno::Reference
<css::beans::XPropertySet
> xPropSet
= getPropSet(mxModel
);
426 css::uno::Reference
<css::beans::XPropertySetInfo
> xInfo(xPropSet
->getPropertySetInfo());
430 SolarMutexGuard aGuard
;
431 if (xInfo
->hasPropertyByName(u
"FillStyle"_ustr
))
433 css::drawing::FillStyle eFillStyle
= css::drawing::FillStyle_SOLID
;
434 xPropSet
->getPropertyValue(u
"FillStyle"_ustr
) >>= eFillStyle
;
435 XFillStyleItem
aFillStyleItem(eFillStyle
);
436 updateFillStyle(false, true, &aFillStyleItem
);
439 if (xInfo
->hasPropertyByName(u
"FillTransparence"_ustr
))
441 sal_uInt16 nFillTransparence
= 0;
442 xPropSet
->getPropertyValue(u
"FillTransparence"_ustr
) >>= nFillTransparence
;
443 SfxUInt16Item
aTransparenceItem(0, nFillTransparence
);
444 updateFillTransparence(false, true, &aTransparenceItem
);
447 if (xInfo
->hasPropertyByName(u
"FillGradientName"_ustr
))
449 OUString aGradientName
;
450 xPropSet
->getPropertyValue(u
"FillGradientName"_ustr
) >>= aGradientName
;
451 XFillGradientItem aGradientItem
= getXGradientForName(mxModel
, aGradientName
);
452 updateFillGradient(false, true, &aGradientItem
);
455 if (xInfo
->hasPropertyByName(u
"FillHatchName"_ustr
))
458 xPropSet
->getPropertyValue(u
"FillHatchName"_ustr
) >>= aHatchName
;
459 XHatch aHatch
= getXHatchFromName(mxModel
, aHatchName
);
460 XFillHatchItem
aHatchItem(aHatchName
, aHatch
);
461 updateFillHatch(false, true, &aHatchItem
);
464 if (xInfo
->hasPropertyByName(u
"FillBitmapName"_ustr
))
466 OUString aBitmapName
;
467 xPropSet
->getPropertyValue(u
"FillBitmapName"_ustr
) >>= aBitmapName
;
468 GraphicObject aBitmap
= getXBitmapFromName(mxModel
, aBitmapName
);
469 XFillBitmapItem
aBitmapItem(aBitmapName
, aBitmap
);
470 std::unique_ptr
<XFillBitmapItem
> pBitmapItem
;
473 DrawModelWrapper
* pModelWrapper
= getDrawModelWrapper(mxModel
);
476 pBitmapItem
= aBitmapItem
.checkForUniqueItem(pModelWrapper
->getSdrModel());
482 updateFillBitmap(false, true, pBitmapItem
? pBitmapItem
.get() : &aBitmapItem
);
485 if (xInfo
->hasPropertyByName(u
"FillTransparenceGradientName"_ustr
))
487 OUString aFillFloatTransparenceName
;
488 xPropSet
->getPropertyValue(u
"FillTransparenceGradientName"_ustr
) >>= aFillFloatTransparenceName
;
489 XFillFloatTransparenceItem aFillFloatTransparenceItem
= getXTransparencyGradientForName(mxModel
, aFillFloatTransparenceName
);
490 updateFillFloatTransparence(false, true, &aFillFloatTransparenceItem
);
492 maFillColorWrapper
.updateData();
495 if (xInfo
->hasPropertyByName(u
"FillColor"_ustr
))
497 sal_uInt32 nFillColor
= 0;
498 xPropSet
->getPropertyValue(u
"FillColor"_ustr
) >>= nFillColor
;
499 XFillColorItem
aFillColorItem(u
""_ustr
, Color(ColorTransparency
, nFillColor
));
500 updateFillColor(true, &aFillColorItem
);
504 void ChartAreaPanel::modelInvalid()
506 mbModelValid
= false;
509 void ChartAreaPanel::selectionChanged(bool bCorrectType
)
515 void ChartAreaPanel::doUpdateModel(const rtl::Reference
<::chart::ChartModel
>& xModel
)
519 mxModel
->removeModifyListener(mxListener
);
521 css::uno::Reference
<css::view::XSelectionSupplier
> oldSelectionSupplier(
522 mxModel
->getCurrentController(), css::uno::UNO_QUERY
);
523 if (oldSelectionSupplier
.is()) {
524 oldSelectionSupplier
->removeSelectionChangeListener(mxSelectionListener
);
529 mbModelValid
= mxModel
.is();
534 mxModel
->addModifyListener(mxListener
);
536 css::uno::Reference
<css::view::XSelectionSupplier
> xSelectionSupplier(mxModel
->getCurrentController(), css::uno::UNO_QUERY
);
537 if (xSelectionSupplier
.is())
538 xSelectionSupplier
->addSelectionChangeListener(mxSelectionListener
);
541 void ChartAreaPanel::updateModel( css::uno::Reference
<css::frame::XModel
> xModel
)
543 ::chart::ChartModel
* pModel
= dynamic_cast<::chart::ChartModel
*>(xModel
.get());
544 assert(!xModel
|| pModel
);
545 doUpdateModel(pModel
);
551 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */