/src/libreoffice/sc/source/ui/unoobj/TablePivotCharts.cxx
Line | Count | Source |
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 <memory> |
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> |
17 | | |
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> |
30 | | |
31 | | #include <TablePivotChart.hxx> |
32 | | #include <TablePivotCharts.hxx> |
33 | | #include <PivotTableDataProvider.hxx> |
34 | | #include <ChartTools.hxx> |
35 | | |
36 | | #include <miscuno.hxx> |
37 | | #include <docsh.hxx> |
38 | | #include <drwlayer.hxx> |
39 | | |
40 | | using namespace css; |
41 | | |
42 | | namespace sc |
43 | | { |
44 | | |
45 | | SC_SIMPLE_SERVICE_INFO(TablePivotCharts, u"TablePivotCharts"_ustr, u"com.sun.star.table.TablePivotCharts"_ustr) |
46 | | |
47 | | TablePivotCharts::TablePivotCharts(ScDocShell* pDocShell, SCTAB nTab) |
48 | 0 | : m_pDocShell(pDocShell) |
49 | 0 | , m_nTab(nTab) |
50 | 0 | { |
51 | 0 | m_pDocShell->GetDocument().AddUnoObject(*this); |
52 | 0 | } |
53 | | |
54 | | TablePivotCharts::~TablePivotCharts() |
55 | 0 | { |
56 | 0 | SolarMutexGuard aGuard; |
57 | |
|
58 | 0 | if (m_pDocShell) |
59 | 0 | m_pDocShell->GetDocument().RemoveUnoObject(*this); |
60 | 0 | } |
61 | | |
62 | | void TablePivotCharts::Notify(SfxBroadcaster& /*rBroadcaster*/, const SfxHint& rHint) |
63 | 0 | { |
64 | 0 | if (rHint.GetId() == SfxHintId::Dying) |
65 | 0 | m_pDocShell = nullptr; |
66 | 0 | } |
67 | | |
68 | | // XTablePivotCharts |
69 | | void SAL_CALL TablePivotCharts::addNewByName(OUString const & rName, |
70 | | const awt::Rectangle& aRect, |
71 | | OUString const & rDataPilotName) |
72 | 0 | { |
73 | 0 | SolarMutexGuard aGuard; |
74 | |
|
75 | 0 | if (!m_pDocShell) |
76 | 0 | return; |
77 | | |
78 | 0 | ScDocument& rDoc = m_pDocShell->GetDocument(); |
79 | 0 | ScDrawLayer* pModel = m_pDocShell->MakeDrawLayer(); |
80 | 0 | SdrPage* pPage = pModel->GetPage(sal_uInt16(m_nTab)); |
81 | 0 | if (!pPage) |
82 | 0 | return; |
83 | | |
84 | | // chart can't be inserted if any ole object with that name exists on any table |
85 | | // (empty string: generate valid name) |
86 | | |
87 | 0 | OUString aName = rName; |
88 | 0 | SCTAB nDummy; |
89 | 0 | if (!aName.isEmpty() && pModel->GetNamedObject(aName, SdrObjKind::OLE2, nDummy)) |
90 | 0 | { |
91 | | // object exists - only RuntimeException is specified |
92 | 0 | throw uno::RuntimeException(); |
93 | 0 | } |
94 | | |
95 | 0 | uno::Reference<embed::XEmbeddedObject> xObject; |
96 | |
|
97 | 0 | if (SvtModuleOptions().IsChartInstalled()) |
98 | 0 | xObject = m_pDocShell->GetEmbeddedObjectContainer().CreateEmbeddedObject(SvGlobalName(SO3_SCH_CLASSID).GetByteSequence(), aName); |
99 | |
|
100 | 0 | if (!xObject.is()) |
101 | 0 | return; |
102 | | |
103 | 0 | Point aRectPos(aRect.X, aRect.Y); |
104 | 0 | bool bLayoutRTL = rDoc.IsLayoutRTL(m_nTab); |
105 | 0 | if ((aRectPos.X() < 0 && !bLayoutRTL) || (aRectPos.X() > 0 && bLayoutRTL)) |
106 | 0 | aRectPos.setX( 0 ); |
107 | |
|
108 | 0 | if (aRectPos.Y() < 0) |
109 | 0 | aRectPos.setY( 0 ); |
110 | |
|
111 | 0 | Size aRectSize(aRect.Width, aRect.Height); |
112 | 0 | if (aRectSize.Width() <= 0) |
113 | 0 | aRectSize.setWidth( 5000 ); // default size |
114 | |
|
115 | 0 | if (aRectSize.Height() <= 0) |
116 | 0 | aRectSize.setHeight( 5000 ); |
117 | |
|
118 | 0 | ::tools::Rectangle aInsRect(aRectPos, aRectSize); |
119 | |
|
120 | 0 | sal_Int64 nAspect(embed::Aspects::MSOLE_CONTENT); |
121 | 0 | MapUnit aMapUnit(VCLUnoHelper::UnoEmbed2VCLMapUnit(xObject->getMapUnit(nAspect))); |
122 | 0 | Size aSize(aInsRect.GetSize()); |
123 | 0 | aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(aMapUnit)); |
124 | 0 | awt::Size aAwtSize; |
125 | 0 | aAwtSize.Width = aSize.Width(); |
126 | 0 | aAwtSize.Height = aSize.Height(); |
127 | |
|
128 | 0 | rtl::Reference<sc::PivotTableDataProvider> pPivotTableDataProvider(new sc::PivotTableDataProvider(rDoc)); |
129 | 0 | pPivotTableDataProvider->setPivotTableName(rDataPilotName); |
130 | |
|
131 | 0 | uno::Reference<chart2::data::XDataReceiver> xReceiver; |
132 | |
|
133 | 0 | if (xObject.is()) |
134 | 0 | xReceiver.set(xObject->getComponent(), uno::UNO_QUERY); |
135 | |
|
136 | 0 | if (xReceiver.is()) |
137 | 0 | { |
138 | 0 | xReceiver->attachDataProvider(uno::Reference<chart2::data::XDataProvider>(pPivotTableDataProvider)); |
139 | |
|
140 | 0 | uno::Reference<util::XNumberFormatsSupplier> xNumberFormatsSupplier(cppu::getXWeak(m_pDocShell->GetModel()), uno::UNO_QUERY); |
141 | 0 | xReceiver->attachNumberFormatsSupplier(xNumberFormatsSupplier); |
142 | |
|
143 | 0 | uno::Sequence<beans::PropertyValue> aArgs( comphelper::InitPropertySequence({ |
144 | 0 | { "CellRangeRepresentation", uno::Any(rDataPilotName) }, |
145 | 0 | { "HasCategories", uno::Any(true) }, |
146 | 0 | { "DataRowSource", uno::Any(chart::ChartDataRowSource_COLUMNS) } |
147 | 0 | })); |
148 | 0 | xReceiver->setArguments(aArgs); |
149 | 0 | } |
150 | |
|
151 | 0 | rtl::Reference<SdrOle2Obj> pObject = new SdrOle2Obj( |
152 | 0 | *pModel, |
153 | 0 | svt::EmbeddedObjectRef(xObject, embed::Aspects::MSOLE_CONTENT), |
154 | 0 | aName, |
155 | 0 | aInsRect); |
156 | |
|
157 | 0 | if (xObject.is()) |
158 | 0 | xObject->setVisualAreaSize(nAspect, aAwtSize); |
159 | |
|
160 | 0 | pPage->InsertObject(pObject.get()); |
161 | 0 | pModel->AddUndo(std::make_unique<SdrUndoInsertObj>(*pObject)); |
162 | 0 | } |
163 | | |
164 | | void SAL_CALL TablePivotCharts::removeByName(const OUString& rName) |
165 | 0 | { |
166 | 0 | SolarMutexGuard aGuard; |
167 | 0 | SdrOle2Obj* pObject = sctools::findChartsByName(m_pDocShell, m_nTab, rName, sctools::ChartSourceType::PIVOT_TABLE); |
168 | 0 | if (pObject) |
169 | 0 | { |
170 | 0 | ScDocument& rDoc = m_pDocShell->GetDocument(); |
171 | 0 | ScDrawLayer* pModel = rDoc.GetDrawLayer(); |
172 | 0 | SdrPage* pPage = pModel->GetPage(sal_uInt16(m_nTab)); |
173 | 0 | pModel->AddUndo(std::make_unique<SdrUndoDelObj>(*pObject)); |
174 | 0 | pPage->RemoveObject(pObject->GetOrdNum()); |
175 | 0 | } |
176 | 0 | } |
177 | | |
178 | | // XIndexAccess |
179 | | sal_Int32 SAL_CALL TablePivotCharts::getCount() |
180 | 0 | { |
181 | 0 | SolarMutexGuard aGuard; |
182 | 0 | sal_Int32 nCount = 0; |
183 | |
|
184 | 0 | if (!m_pDocShell) |
185 | 0 | return nCount; |
186 | | |
187 | 0 | sctools::ChartIterator aIterator(m_pDocShell, m_nTab, sctools::ChartSourceType::PIVOT_TABLE); |
188 | |
|
189 | 0 | SdrOle2Obj* pOleObject = aIterator.next(); |
190 | 0 | while (pOleObject) |
191 | 0 | { |
192 | 0 | if (pOleObject->GetObjRef().is()) |
193 | 0 | nCount++; |
194 | 0 | pOleObject = aIterator.next(); |
195 | 0 | } |
196 | 0 | return nCount; |
197 | 0 | } |
198 | | |
199 | | uno::Any SAL_CALL TablePivotCharts::getByIndex(sal_Int32 nIndex) |
200 | 0 | { |
201 | 0 | SolarMutexGuard aGuard; |
202 | 0 | SdrOle2Obj* pObject = sctools::getChartByIndex(m_pDocShell, m_nTab, nIndex, |
203 | 0 | sctools::ChartSourceType::PIVOT_TABLE); |
204 | 0 | if (!pObject) |
205 | 0 | throw lang::IndexOutOfBoundsException(); |
206 | | |
207 | 0 | OUString aName; |
208 | 0 | uno::Reference<embed::XEmbeddedObject> xObject = pObject->GetObjRef(); |
209 | 0 | if (xObject.is()) |
210 | 0 | aName = m_pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName(xObject); |
211 | |
|
212 | 0 | if (aName.isEmpty()) |
213 | 0 | throw lang::IndexOutOfBoundsException(); |
214 | | |
215 | 0 | uno::Reference<table::XTablePivotChart> xChart(new TablePivotChart(m_pDocShell, m_nTab, aName)); |
216 | 0 | if (!xChart.is()) |
217 | 0 | throw lang::IndexOutOfBoundsException(); |
218 | | |
219 | 0 | return uno::Any(xChart); |
220 | 0 | } |
221 | | |
222 | | uno::Type SAL_CALL TablePivotCharts::getElementType() |
223 | 0 | { |
224 | 0 | return cppu::UnoType<table::XTablePivotChart>::get(); |
225 | 0 | } |
226 | | |
227 | | sal_Bool SAL_CALL TablePivotCharts::hasElements() |
228 | 0 | { |
229 | 0 | SolarMutexGuard aGuard; |
230 | 0 | return getCount() != 0; |
231 | 0 | } |
232 | | |
233 | | uno::Any SAL_CALL TablePivotCharts::getByName(OUString const & rName) |
234 | 0 | { |
235 | 0 | SolarMutexGuard aGuard; |
236 | |
|
237 | 0 | if (!sctools::findChartsByName(m_pDocShell, m_nTab, rName, sctools::ChartSourceType::PIVOT_TABLE)) |
238 | 0 | throw container::NoSuchElementException(); |
239 | | |
240 | 0 | uno::Reference<table::XTablePivotChart> xChart(new TablePivotChart(m_pDocShell, m_nTab, rName)); |
241 | 0 | if (!xChart.is()) |
242 | 0 | throw container::NoSuchElementException(); |
243 | | |
244 | 0 | return uno::Any(xChart); |
245 | 0 | } |
246 | | |
247 | | uno::Sequence<OUString> SAL_CALL TablePivotCharts::getElementNames() |
248 | 0 | { |
249 | 0 | SolarMutexGuard aGuard; |
250 | |
|
251 | 0 | std::vector<OUString> aElements; |
252 | 0 | sctools::ChartIterator aIterator(m_pDocShell, m_nTab, sctools::ChartSourceType::PIVOT_TABLE); |
253 | |
|
254 | 0 | SdrOle2Obj* pOleObject = aIterator.next(); |
255 | 0 | while (pOleObject) |
256 | 0 | { |
257 | 0 | uno::Reference<embed::XEmbeddedObject> xObject = pOleObject->GetObjRef(); |
258 | 0 | if (xObject.is()) |
259 | 0 | { |
260 | 0 | OUString aName = m_pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName(xObject); |
261 | 0 | aElements.push_back(aName); |
262 | 0 | } |
263 | 0 | pOleObject = aIterator.next(); |
264 | 0 | } |
265 | 0 | return comphelper::containerToSequence(aElements); |
266 | 0 | } |
267 | | |
268 | | sal_Bool SAL_CALL TablePivotCharts::hasByName(OUString const & rName) |
269 | 0 | { |
270 | 0 | SolarMutexGuard aGuard; |
271 | |
|
272 | 0 | return sctools::findChartsByName(m_pDocShell, m_nTab, rName, sctools::ChartSourceType::PIVOT_TABLE) != nullptr; |
273 | 0 | } |
274 | | |
275 | | } // end sc namespace |
276 | | |
277 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |