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/.
11 #include <com/sun/star/embed/Aspects.hpp>
12 #include <com/sun/star/embed/XEmbeddedObject.hpp>
13 #include <com/sun/star/awt/Size.hpp>
14 #include <com/sun/star/chart/ChartDataRowSource.hpp>
15 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
16 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
18 #include <tools/gen.hxx>
19 #include <svx/svdoole2.hxx>
20 #include <svx/svdpage.hxx>
21 #include <svx/svdundo.hxx>
22 #include <unotools/moduleoptions.hxx>
23 #include <comphelper/propertysequence.hxx>
24 #include <comphelper/classids.hxx>
25 #include <toolkit/helper/vclunohelper.hxx>
26 #include <tools/globname.hxx>
27 #include <svtools/embedhlp.hxx>
28 #include <comphelper/sequence.hxx>
29 #include <vcl/svapp.hxx>
31 #include <TablePivotChart.hxx>
32 #include <TablePivotCharts.hxx>
33 #include <PivotTableDataProvider.hxx>
34 #include <ChartTools.hxx>
36 #include <miscuno.hxx>
38 #include <drwlayer.hxx>
45 SC_SIMPLE_SERVICE_INFO(TablePivotCharts
, u
"TablePivotCharts"_ustr
, u
"com.sun.star.table.TablePivotCharts"_ustr
)
47 TablePivotCharts::TablePivotCharts(ScDocShell
* pDocShell
, SCTAB nTab
)
48 : m_pDocShell(pDocShell
)
51 m_pDocShell
->GetDocument().AddUnoObject(*this);
54 TablePivotCharts::~TablePivotCharts()
56 SolarMutexGuard aGuard
;
59 m_pDocShell
->GetDocument().RemoveUnoObject(*this);
62 void TablePivotCharts::Notify(SfxBroadcaster
& /*rBroadcaster*/, const SfxHint
& rHint
)
64 if (rHint
.GetId() == SfxHintId::Dying
)
65 m_pDocShell
= nullptr;
69 void SAL_CALL
TablePivotCharts::addNewByName(OUString
const & rName
,
70 const awt::Rectangle
& aRect
,
71 OUString
const & rDataPilotName
)
73 SolarMutexGuard aGuard
;
78 ScDocument
& rDoc
= m_pDocShell
->GetDocument();
79 ScDrawLayer
* pModel
= m_pDocShell
->MakeDrawLayer();
80 SdrPage
* pPage
= pModel
->GetPage(sal_uInt16(m_nTab
));
84 // chart can't be inserted if any ole object with that name exists on any table
85 // (empty string: generate valid name)
87 OUString aName
= rName
;
89 if (!aName
.isEmpty() && pModel
->GetNamedObject(aName
, SdrObjKind::OLE2
, nDummy
))
91 // object exists - only RuntimeException is specified
92 throw uno::RuntimeException();
95 uno::Reference
<embed::XEmbeddedObject
> xObject
;
97 if (SvtModuleOptions().IsChartInstalled())
98 xObject
= m_pDocShell
->GetEmbeddedObjectContainer().CreateEmbeddedObject(SvGlobalName(SO3_SCH_CLASSID
).GetByteSequence(), aName
);
103 Point
aRectPos(aRect
.X
, aRect
.Y
);
104 bool bLayoutRTL
= rDoc
.IsLayoutRTL(m_nTab
);
105 if ((aRectPos
.X() < 0 && !bLayoutRTL
) || (aRectPos
.X() > 0 && bLayoutRTL
))
108 if (aRectPos
.Y() < 0)
111 Size
aRectSize(aRect
.Width
, aRect
.Height
);
112 if (aRectSize
.Width() <= 0)
113 aRectSize
.setWidth( 5000 ); // default size
115 if (aRectSize
.Height() <= 0)
116 aRectSize
.setHeight( 5000 );
118 ::tools::Rectangle
aInsRect(aRectPos
, aRectSize
);
120 sal_Int64
nAspect(embed::Aspects::MSOLE_CONTENT
);
121 MapUnit
aMapUnit(VCLUnoHelper::UnoEmbed2VCLMapUnit(xObject
->getMapUnit(nAspect
)));
122 Size
aSize(aInsRect
.GetSize());
123 aSize
= OutputDevice::LogicToLogic(aSize
, MapMode(MapUnit::Map100thMM
), MapMode(aMapUnit
));
125 aAwtSize
.Width
= aSize
.Width();
126 aAwtSize
.Height
= aSize
.Height();
128 rtl::Reference
<sc::PivotTableDataProvider
> pPivotTableDataProvider(new sc::PivotTableDataProvider(rDoc
));
129 pPivotTableDataProvider
->setPivotTableName(rDataPilotName
);
131 uno::Reference
<chart2::data::XDataProvider
> xDataProvider(pPivotTableDataProvider
);
133 uno::Reference
<chart2::data::XDataReceiver
> xReceiver
;
136 xReceiver
.set(xObject
->getComponent(), uno::UNO_QUERY
);
140 xReceiver
->attachDataProvider(xDataProvider
);
142 uno::Reference
<util::XNumberFormatsSupplier
> xNumberFormatsSupplier(cppu::getXWeak(m_pDocShell
->GetModel()), uno::UNO_QUERY
);
143 xReceiver
->attachNumberFormatsSupplier(xNumberFormatsSupplier
);
145 uno::Sequence
<beans::PropertyValue
> aArgs( comphelper::InitPropertySequence({
146 { "CellRangeRepresentation", uno::Any(rDataPilotName
) },
147 { "HasCategories", uno::Any(true) },
148 { "DataRowSource", uno::Any(chart::ChartDataRowSource_COLUMNS
) }
150 xReceiver
->setArguments(aArgs
);
153 rtl::Reference
<SdrOle2Obj
> pObject
= new SdrOle2Obj(
155 svt::EmbeddedObjectRef(xObject
, embed::Aspects::MSOLE_CONTENT
),
160 xObject
->setVisualAreaSize(nAspect
, aAwtSize
);
162 pPage
->InsertObject(pObject
.get());
163 pModel
->AddUndo(std::make_unique
<SdrUndoInsertObj
>(*pObject
));
166 void SAL_CALL
TablePivotCharts::removeByName(const OUString
& rName
)
168 SolarMutexGuard aGuard
;
169 SdrOle2Obj
* pObject
= sc::tools::findChartsByName(m_pDocShell
, m_nTab
, rName
, sc::tools::ChartSourceType::PIVOT_TABLE
);
172 ScDocument
& rDoc
= m_pDocShell
->GetDocument();
173 ScDrawLayer
* pModel
= rDoc
.GetDrawLayer();
174 SdrPage
* pPage
= pModel
->GetPage(sal_uInt16(m_nTab
));
175 pModel
->AddUndo(std::make_unique
<SdrUndoDelObj
>(*pObject
));
176 pPage
->RemoveObject(pObject
->GetOrdNum());
181 sal_Int32 SAL_CALL
TablePivotCharts::getCount()
183 SolarMutexGuard aGuard
;
184 sal_Int32 nCount
= 0;
189 sc::tools::ChartIterator
aIterator(m_pDocShell
, m_nTab
, sc::tools::ChartSourceType::PIVOT_TABLE
);
191 SdrOle2Obj
* pOleObject
= aIterator
.next();
194 if (pOleObject
->GetObjRef().is())
196 pOleObject
= aIterator
.next();
201 uno::Any SAL_CALL
TablePivotCharts::getByIndex(sal_Int32 nIndex
)
203 SolarMutexGuard aGuard
;
204 SdrOle2Obj
* pObject
= sc::tools::getChartByIndex(m_pDocShell
, m_nTab
, nIndex
,
205 sc::tools::ChartSourceType::PIVOT_TABLE
);
207 throw lang::IndexOutOfBoundsException();
210 uno::Reference
<embed::XEmbeddedObject
> xObject
= pObject
->GetObjRef();
212 aName
= m_pDocShell
->GetEmbeddedObjectContainer().GetEmbeddedObjectName(xObject
);
215 throw lang::IndexOutOfBoundsException();
217 uno::Reference
<table::XTablePivotChart
> xChart(new TablePivotChart(m_pDocShell
, m_nTab
, aName
));
219 throw lang::IndexOutOfBoundsException();
221 return uno::Any(xChart
);
224 uno::Type SAL_CALL
TablePivotCharts::getElementType()
226 return cppu::UnoType
<table::XTablePivotChart
>::get();
229 sal_Bool SAL_CALL
TablePivotCharts::hasElements()
231 SolarMutexGuard aGuard
;
232 return getCount() != 0;
235 uno::Any SAL_CALL
TablePivotCharts::getByName(OUString
const & rName
)
237 SolarMutexGuard aGuard
;
239 if (!sc::tools::findChartsByName(m_pDocShell
, m_nTab
, rName
, sc::tools::ChartSourceType::PIVOT_TABLE
))
240 throw container::NoSuchElementException();
242 uno::Reference
<table::XTablePivotChart
> xChart(new TablePivotChart(m_pDocShell
, m_nTab
, rName
));
244 throw container::NoSuchElementException();
246 return uno::Any(xChart
);
249 uno::Sequence
<OUString
> SAL_CALL
TablePivotCharts::getElementNames()
251 SolarMutexGuard aGuard
;
253 std::vector
<OUString
> aElements
;
254 sc::tools::ChartIterator
aIterator(m_pDocShell
, m_nTab
, sc::tools::ChartSourceType::PIVOT_TABLE
);
256 SdrOle2Obj
* pOleObject
= aIterator
.next();
259 uno::Reference
<embed::XEmbeddedObject
> xObject
= pOleObject
->GetObjRef();
262 OUString aName
= m_pDocShell
->GetEmbeddedObjectContainer().GetEmbeddedObjectName(xObject
);
263 aElements
.push_back(aName
);
265 pOleObject
= aIterator
.next();
267 return comphelper::containerToSequence(aElements
);
270 sal_Bool SAL_CALL
TablePivotCharts::hasByName(OUString
const & rName
)
272 SolarMutexGuard aGuard
;
274 return sc::tools::findChartsByName(m_pDocShell
, m_nTab
, rName
, sc::tools::ChartSourceType::PIVOT_TABLE
) != nullptr;
277 } // end sc namespace
279 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */