LibreOffice Module chart2 (master) 1
ChartAreaPanel.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
10#include <sal/config.h>
11
12#include <string_view>
13
14#include "ChartAreaPanel.hxx"
15
16#include <ChartController.hxx>
17#include <ChartModel.hxx>
19#include <PropertyHelper.hxx>
20
22#include <com/sun/star/chart2/XDiagram.hpp>
23
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>
30
31#include <svx/tbcontrl.hxx>
32
33namespace chart::sidebar {
34
35namespace {
36
37SvxColorToolBoxControl* getColorToolBoxControl(const ToolbarUnoDispatcher& rColorDispatch)
38{
39 css::uno::Reference<css::frame::XToolbarController> xController = rColorDispatch.GetControllerForCommand(".uno:FillColor");
40 SvxColorToolBoxControl* pToolBoxColorControl = dynamic_cast<SvxColorToolBoxControl*>(xController.get());
41 return pToolBoxColorControl;
42}
43
44OUString getCID(const rtl::Reference<::chart::ChartModel>& xModel)
45{
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())
49 return OUString();
50
51 css::uno::Any aAny = xSelectionSupplier->getSelection();
52 if (!aAny.hasValue())
53 {
54 // if no selection, default to diagram wall so sidebar can show some editable properties
55 ChartController* pController = dynamic_cast<ChartController*>(xController.get());
56 if (pController)
57 {
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();
62 }
63
64 if (!aAny.hasValue())
65 return OUString();
66 }
67
68 OUString aCID;
69 aAny >>= aCID;
70
71 return aCID;
72}
73
74css::uno::Reference<css::beans::XPropertySet> getPropSet(
76{
77 OUString aCID = getCID(xModel);
78 css::uno::Reference<css::beans::XPropertySet> xPropSet =
80
82 if (eType == OBJECTTYPE_DIAGRAM)
83 {
84 css::uno::Reference<css::chart2::XDiagram> xDiagram(
85 xPropSet, css::uno::UNO_QUERY);
86 if (!xDiagram.is())
87 return xPropSet;
88
89 xPropSet.set(xDiagram->getWall());
90 }
91
92 return xPropSet;
93}
94
95ChartController* getController(const css::uno::Reference<css::frame::XModel>& xModel)
96{
97 css::uno::Reference<css::frame::XController>xController = xModel->getCurrentController();
98 if (!xController.is())
99 throw std::exception();
100
101 ChartController* pController = dynamic_cast<ChartController*>(xController.get());
102 if (!pController)
103 throw std::exception();
104
105 return pController;
106}
107
108ViewElementListProvider getViewElementListProvider( const css::uno::Reference<css::frame::XModel>& xModel)
109{
110 ChartController* pController = getController(xModel);
111 ViewElementListProvider aProvider = pController->getViewElementListProvider();
112 return aProvider;
113}
114
115DrawModelWrapper* getDrawModelWrapper(const css::uno::Reference<css::frame::XModel>& xModel)
116{
117 ChartController* pController = getController(xModel);
118 return pController->GetDrawModelWrapper();
119}
120
121XFillGradientItem getXGradientForName(const css::uno::Reference<css::frame::XModel>& xModel,
122 const OUString& rName)
123{
124 css::uno::Reference<css::lang::XMultiServiceFactory> xFact(xModel, css::uno::UNO_QUERY);
125 css::uno::Reference<css::container::XNameAccess> xNameAccess(
126 xFact->createInstance("com.sun.star.drawing.GradientTable"), css::uno::UNO_QUERY);
127 if (!xNameAccess.is())
128 return XFillGradientItem();
129
130 if (!xNameAccess->hasByName(rName))
131 return XFillGradientItem();
132
133 css::uno::Any aAny = xNameAccess->getByName(rName);
134
135 XFillGradientItem aItem;
136 aItem.SetName(rName);
137 aItem.PutValue(aAny, MID_FILLGRADIENT);
138
139 return aItem;
140
141}
142
143XFillFloatTransparenceItem getXTransparencyGradientForName(const css::uno::Reference<css::frame::XModel>& xModel,
144 const OUString& rName)
145{
146 css::uno::Reference<css::lang::XMultiServiceFactory> xFact(xModel, css::uno::UNO_QUERY);
147 css::uno::Reference<css::container::XNameAccess> xNameAccess(
148 xFact->createInstance("com.sun.star.drawing.TransparencyGradientTable"), css::uno::UNO_QUERY);
149 if (!xNameAccess.is())
151
152 if (!xNameAccess->hasByName(rName))
154
155 css::uno::Any aAny = xNameAccess->getByName(rName);
156
158 aItem.SetName(rName);
159 aItem.PutValue(aAny, MID_FILLGRADIENT);
160 aItem.SetEnabled(true);
161
162 return aItem;
163}
164
165XHatch getXHatchFromName(const css::uno::Reference<css::frame::XModel>& xModel,
166 OUString& rName)
167{
168 try
169 {
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)
174 {
175 const XHatchEntry* pHatch = aRef->GetHatch(i);
176 if (!pHatch)
177 continue;
178
179 if (pHatch->GetName().equalsIgnoreAsciiCase(rName))
180 {
181 // we need to update the hatch name
182 rName = pHatch->GetName();
183 return pHatch->GetHatch();
184 }
185 }
186 }
187 catch (...)
188 {
189 // ignore exception
190 }
191
192 return XHatch();
193}
194
195GraphicObject getXBitmapFromName(const css::uno::Reference<css::frame::XModel>& xModel,
196 std::u16string_view rName)
197{
198 try
199 {
200 ViewElementListProvider aProvider = getViewElementListProvider(xModel);
201 XBitmapListRef aBmpRef = aProvider.GetBitmapList();
202 XPatternListRef aPatRef = aProvider.GetPatternList();
203
204 size_t n = aBmpRef->Count();
205 for (size_t i = 0; i < n; ++i)
206 {
207 const XBitmapEntry* pBitmap = aBmpRef->GetBitmap(i);
208 if (!pBitmap)
209 continue;
210
211 if (pBitmap->GetName().equalsIgnoreAsciiCase(rName))
212 {
213 return pBitmap->GetGraphicObject();
214 }
215 }
216
217 // perhaps it's a pattern
218 size_t m = aPatRef->Count();
219 for (size_t i = 0; i < m; ++i)
220 {
221 const XBitmapEntry* pBitmap = aPatRef->GetBitmap(i);
222 if (!pBitmap)
223 continue;
224
225 if (pBitmap->GetName().equalsIgnoreAsciiCase(rName))
226 {
227 return pBitmap->GetGraphicObject();
228 }
229 }
230 }
231 catch (...)
232 {
233 // ignore exception
234 }
235
236 return GraphicObject();
237}
238
239class PreventUpdate
240{
241public:
242 explicit PreventUpdate(bool& bUpdate):
243 mbUpdate(bUpdate)
244 {
245 mbUpdate = false;
246 }
247
248 ~PreventUpdate()
249 {
250 mbUpdate = true;
251 }
252
253private:
254 bool& mbUpdate;
255};
256
257}
258
259std::unique_ptr<PanelLayout> ChartAreaPanel::Create(
260 weld::Widget* pParent,
261 const css::uno::Reference<css::frame::XFrame>& rxFrame,
262 ChartController* pController)
263{
264 if (pParent == nullptr)
265 throw css::lang::IllegalArgumentException("no parent Window given to ChartAxisPanel::Create", nullptr, 0);
266 if (!rxFrame.is())
267 throw css::lang::IllegalArgumentException("no XFrame given to ChartAxisPanel::Create", nullptr, 1);
268
269 return std::make_unique<ChartAreaPanel>(pParent, rxFrame, pController);
270}
271
273 const css::uno::Reference<css::frame::XFrame>& rxFrame,
274 ChartController* pController):
275 svx::sidebar::AreaPropertyPanelBase(pParent, rxFrame),
276 mxModel(pController->getChartModel()),
278 mxSelectionListener(new ChartSidebarSelectionListener(this)),
279 mbUpdate(true),
280 mbModelValid(true),
281 maFillColorWrapper(mxModel, getColorToolBoxControl(*mxColorDispatch), "FillColor")
282{
283 std::vector<ObjectType> aAcceptedTypes { OBJECTTYPE_PAGE, OBJECTTYPE_DIAGRAM,
286 mxSelectionListener->setAcceptedTypes(std::move(aAcceptedTypes));
287 Initialize();
288}
289
291{
292 doUpdateModel(nullptr);
293}
294
296{
297 mxModel->addModifyListener(mxListener);
298
299 css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(mxModel->getCurrentController(), css::uno::UNO_QUERY);
300 if (xSelectionSupplier.is())
301 xSelectionSupplier->addSelectionChangeListener(mxSelectionListener);
302
303 SvxColorToolBoxControl* pToolBoxColor = getColorToolBoxControl(*mxColorDispatch);
305
306 updateData();
307}
308
310{
311 PreventUpdate aProtector(mbUpdate);
312 css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
313 if (!xPropSet.is())
314 return;
315
316 xPropSet->setPropertyValue("FillTransparence", css::uno::Any(rItem.GetValue()));
317}
318
320 const XFillFloatTransparenceItem& rItem)
321{
322 PreventUpdate aProtector(mbUpdate);
323 css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
324 if (!xPropSet.is())
325 return;
326
327 if (!rItem.IsEnabled())
328 {
329 xPropSet->setPropertyValue("FillTransparenceGradientName", css::uno::Any(OUString()));
330 return;
331 }
332
333 const OUString& aName = rItem.GetName();
334 css::uno::Any aGradientVal;
335 rItem.QueryValue(aGradientVal, MID_FILLGRADIENT);
337 xPropSet->setPropertyValue("FillTransparenceGradientName", css::uno::Any(aNewName));
338}
339
341{
342 PreventUpdate aProtector(mbUpdate);
343 css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
344 if (!xPropSet.is())
345 return;
346
347 xPropSet->setPropertyValue("FillStyle", css::uno::Any(rItem.GetValue()));
348}
349
351 const XFillColorItem& rColorItem)
352{
353 css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
354 if (!xPropSet.is())
355 return;
356
357 if (pStyleItem)
358 xPropSet->setPropertyValue("FillStyle", css::uno::Any(pStyleItem->GetValue()));
359 xPropSet->setPropertyValue("FillColor", css::uno::Any(rColorItem.GetValue()));
360}
361
363 const XFillGradientItem& rGradientItem)
364{
365 PreventUpdate aProtector(mbUpdate);
366 css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
367 if (!xPropSet.is())
368 return;
369
370 if (pStyleItem)
371 xPropSet->setPropertyValue("FillStyle", css::uno::Any(pStyleItem->GetValue()));
372
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("FillGradientName", css::uno::Any(aNewName));
378}
379
381 const XFillHatchItem& rHatchItem)
382{
383 PreventUpdate aProtector(mbUpdate);
384 css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
385 if (!xPropSet.is())
386 return;
387
388 if (pStyleItem)
389 xPropSet->setPropertyValue("FillStyle", css::uno::Any(pStyleItem->GetValue()));
390 xPropSet->setPropertyValue("FillHatchName", css::uno::Any(rHatchItem.GetValue()));
391}
392
394 const XFillBitmapItem& rBitmapItem)
395{
396 PreventUpdate aProtector(mbUpdate);
397 css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
398 if (!xPropSet.is())
399 return;
400
401 if (pStyleItem)
402 xPropSet->setPropertyValue("FillStyle", css::uno::Any(pStyleItem->GetValue()));
403
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("FillBitmapName", aBitmap);
409}
410
412 const XFillUseSlideBackgroundItem& /*rItem*/)
413{
414 setFillStyle(*pStyleItem);
415}
416
418{
419 if (!mbUpdate || !mbModelValid)
420 return;
421
422 css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
423 if (!xPropSet.is())
424 return;
425
426 css::uno::Reference<css::beans::XPropertySetInfo> xInfo(xPropSet->getPropertySetInfo());
427 if (!xInfo.is())
428 return;
429
430 SolarMutexGuard aGuard;
431 if (xInfo->hasPropertyByName("FillStyle"))
432 {
433 css::drawing::FillStyle eFillStyle = css::drawing::FillStyle_SOLID;
434 xPropSet->getPropertyValue("FillStyle") >>= eFillStyle;
435 XFillStyleItem aFillStyleItem(eFillStyle);
436 updateFillStyle(false, true, &aFillStyleItem);
437 }
438
439 if (xInfo->hasPropertyByName("FillTransparence"))
440 {
441 sal_uInt16 nFillTransparence = 0;
442 xPropSet->getPropertyValue("FillTransparence") >>= nFillTransparence;
443 SfxUInt16Item aTransparenceItem(0, nFillTransparence);
444 updateFillTransparence(false, true, &aTransparenceItem);
445 }
446
447 if (xInfo->hasPropertyByName("FillGradientName"))
448 {
449 OUString aGradientName;
450 xPropSet->getPropertyValue("FillGradientName") >>= aGradientName;
451 XFillGradientItem aGradientItem = getXGradientForName(mxModel, aGradientName);
452 updateFillGradient(false, true, &aGradientItem);
453 }
454
455 if (xInfo->hasPropertyByName("FillHatchName"))
456 {
457 OUString aHatchName;
458 xPropSet->getPropertyValue("FillHatchName") >>= aHatchName;
459 XHatch aHatch = getXHatchFromName(mxModel, aHatchName);
460 XFillHatchItem aHatchItem(aHatchName, aHatch);
461 updateFillHatch(false, true, &aHatchItem);
462 }
463
464 if (xInfo->hasPropertyByName("FillBitmapName"))
465 {
466 OUString aBitmapName;
467 xPropSet->getPropertyValue("FillBitmapName") >>= aBitmapName;
468 GraphicObject aBitmap = getXBitmapFromName(mxModel, aBitmapName);
469 XFillBitmapItem aBitmapItem(aBitmapName, aBitmap);
470 std::unique_ptr<XFillBitmapItem> pBitmapItem;
471 try
472 {
473 DrawModelWrapper* pModelWrapper = getDrawModelWrapper(mxModel);
474 if (pModelWrapper)
475 {
476 pBitmapItem = aBitmapItem.checkForUniqueItem(&pModelWrapper->getSdrModel());
477 }
478 }
479 catch (...)
480 {
481 }
482 updateFillBitmap(false, true, pBitmapItem ? pBitmapItem.get() : &aBitmapItem);
483 }
484
485 if (xInfo->hasPropertyByName("FillTransparenceGradientName"))
486 {
487 OUString aFillFloatTransparenceName;
488 xPropSet->getPropertyValue("FillTransparenceGradientName") >>= aFillFloatTransparenceName;
489 XFillFloatTransparenceItem aFillFloatTransparenceItem = getXTransparencyGradientForName(mxModel, aFillFloatTransparenceName);
490 updateFillFloatTransparence(false, true, &aFillFloatTransparenceItem);
491
493 }
494
495 if (xInfo->hasPropertyByName("FillColor"))
496 {
497 sal_uInt32 nFillColor = 0;
498 xPropSet->getPropertyValue("FillColor") >>= nFillColor;
499 XFillColorItem aFillColorItem("", Color(ColorTransparency, nFillColor));
500 updateFillColor(true, &aFillColorItem);
501 }
502}
503
505{
506 mbModelValid = false;
507}
508
509void ChartAreaPanel::selectionChanged(bool bCorrectType)
510{
511 if (bCorrectType)
512 updateData();
513}
514
516{
517 if (mbModelValid)
518 {
519 mxModel->removeModifyListener(mxListener);
520
521 css::uno::Reference<css::view::XSelectionSupplier> oldSelectionSupplier(
522 mxModel->getCurrentController(), css::uno::UNO_QUERY);
523 if (oldSelectionSupplier.is()) {
524 oldSelectionSupplier->removeSelectionChangeListener(mxSelectionListener);
525 }
526 }
527
528 mxModel = xModel;
529 mbModelValid = mxModel.is();
530
531 if (!mbModelValid)
532 return;
533
534 mxModel->addModifyListener(mxListener);
535
536 css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(mxModel->getCurrentController(), css::uno::UNO_QUERY);
537 if (xSelectionSupplier.is())
538 xSelectionSupplier->addSelectionChangeListener(mxSelectionListener);
539}
540
541void ChartAreaPanel::updateModel( css::uno::Reference<css::frame::XModel> xModel)
542{
543 ::chart::ChartModel* pModel = dynamic_cast<::chart::ChartModel*>(xModel.get());
544 assert(!xModel || pModel);
545 doUpdateModel(pModel);
546}
547
548
549}
550
551/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool & mbUpdate
css::uno::Reference< css::frame::XModel2 > mxModel
OUString const & GetName() const
void SetName(const OUString &rName)
void setColorSelectFunction(const ColorSelectFunction &aColorSelectFunction)
css::uno::Reference< css::frame::XToolbarController > GetControllerForCommand(const OUString &rCommand) const
const GraphicObject & GetGraphicObject() const
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const override
std::unique_ptr< XFillBitmapItem > checkForUniqueItem(SdrModel *pModel) const
void SetEnabled(bool bEnable)
virtual bool PutValue(const css::uno::Any &rVal, sal_uInt8 nMemberId) override
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const override
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const override
virtual bool PutValue(const css::uno::Any &rVal, sal_uInt8 nMemberId) override
const XHatch & GetHatch() const
const OUString & GetName() const
static OUString createClassifiedIdentifier(enum ObjectType eObjectType, std::u16string_view rParticleID)
static css::uno::Reference< css::beans::XPropertySet > getObjectPropertySet(std::u16string_view rObjectCID, const rtl::Reference< ::chart::ChartModel > &xChartDocument)
ObjectType getObjectType() const
css::uno::Reference< css::util::XModifyListener > mxListener
virtual void updateData() override
rtl::Reference< ChartSidebarSelectionListener > mxSelectionListener
rtl::Reference<::chart::ChartModel > mxModel
virtual void modelInvalid() override
void doUpdateModel(rtl::Reference<::chart::ChartModel > xModel)
virtual void setFillStyle(const XFillStyleItem &rItem) override
virtual void setFillStyleAndColor(const XFillStyleItem *pStyleItem, const XFillColorItem &rColorItem) override
ChartAreaPanel(weld::Widget *pParent, const css::uno::Reference< css::frame::XFrame > &rxFrame, ChartController *pController)
virtual void setFillUseBackground(const XFillStyleItem *pStyleItem, const XFillUseSlideBackgroundItem &rItem) override
virtual void setFillStyleAndHatch(const XFillStyleItem *pStyleItem, const XFillHatchItem &rHatchItem) override
virtual void setFillFloatTransparence(const XFillFloatTransparenceItem &rItem) override
virtual ~ChartAreaPanel() override
virtual void setFillTransparence(const XFillTransparenceItem &rItem) override
virtual void selectionChanged(bool bCorrectType) override
ChartColorWrapper maFillColorWrapper
virtual void setFillStyleAndGradient(const XFillStyleItem *pStyleItem, const XFillGradientItem &rGradientItem) override
static std::unique_ptr< PanelLayout > Create(weld::Widget *pParent, const css::uno::Reference< css::frame::XFrame > &rxFrame, ChartController *pController)
virtual void updateModel(css::uno::Reference< css::frame::XModel > xModel) override
virtual void setFillStyleAndBitmap(const XFillStyleItem *pStyleItem, const XFillBitmapItem &rBitmapItem) override
std::unique_ptr< ToolbarUnoDispatcher > mxColorDispatch
void updateFillFloatTransparence(bool bDisabled, bool bDefaultOrSet, const SfxPoolItem *pState)
void updateFillColor(bool bDefaultOrSet, const SfxPoolItem *pState)
void updateFillHatch(bool bDisabled, bool bDefaultOrSet, const SfxPoolItem *pState)
void updateFillStyle(bool bDisabled, bool bDefaultOrSet, const SfxPoolItem *pState)
void updateFillBitmap(bool BDisabled, bool bDefaultOrSet, const SfxPoolItem *pState)
void updateFillGradient(bool bDisabled, bool bDefaultOrSet, const SfxPoolItem *pState)
void updateFillTransparence(bool bDisabled, bool bDefaultOrSet, const SfxPoolItem *pState)
ColorTransparency
Reference< script::XScriptListener > mxListener
DocumentType eType
OUString aName
sal_Int64 n
OOO_DLLPUBLIC_CHARTTOOLS OUString addGradientUniqueNameToTable(const css::uno::Any &rValue, const css::uno::Reference< css::lang::XMultiServiceFactory > &xFact, const OUString &rPreferredName)
adds a gradient with a unique name to the gradient obtained by the given factory.
OOO_DLLPUBLIC_CHARTTOOLS OUString addBitmapUniqueNameToTable(const css::uno::Any &rValue, const css::uno::Reference< css::lang::XMultiServiceFactory > &xFact, const OUString &rPreferredName)
adds a bitmap with a unique name to the gradient obtained by the given factory.
OOO_DLLPUBLIC_CHARTTOOLS OUString addTransparencyGradientUniqueNameToTable(const css::uno::Any &rValue, const css::uno::Reference< css::lang::XMultiServiceFactory > &xFact, const OUString &rPreferredName)
adds a transparency gradient with a unique name to the gradient obtained by the given factory.
@ OBJECTTYPE_DATA_SERIES
@ OBJECTTYPE_DIAGRAM
@ OBJECTTYPE_DATA_POINT
int i
m
ObjectType
Reference< XController > xController
Reference< XModel > xModel
#define MID_FILLGRADIENT
#define MID_BITMAP