LibreOffice Module sc (master)  1
TablePivotCharts.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 <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>
24 #include <comphelper/classids.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>
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, "TablePivotCharts", "com.sun.star.table.TablePivotCharts")
46 
48  : m_pDocShell(pDocShell)
49  , m_nTab(nTab)
50 {
51  m_pDocShell->GetDocument().AddUnoObject(*this);
52 }
53 
54 TablePivotCharts::~TablePivotCharts()
55 {
56  SolarMutexGuard aGuard;
57 
58  if (m_pDocShell)
59  m_pDocShell->GetDocument().RemoveUnoObject(*this);
60 }
61 
62 void TablePivotCharts::Notify(SfxBroadcaster& /*rBroadcaster*/, const SfxHint& rHint)
63 {
64  if (rHint.GetId() == SfxHintId::Dying)
65  m_pDocShell = nullptr;
66 }
67 
68 // XTablePivotCharts
69 void SAL_CALL TablePivotCharts::addNewByName(OUString const & rName,
70  const awt::Rectangle& aRect,
71  OUString const & rDataPilotName)
72 {
73  SolarMutexGuard aGuard;
74 
75  if (!m_pDocShell)
76  return;
77 
78  ScDocument& rDoc = m_pDocShell->GetDocument();
79  ScDrawLayer* pModel = m_pDocShell->MakeDrawLayer();
80  SdrPage* pPage = pModel->GetPage(sal_uInt16(m_nTab));
81  if (!pPage)
82  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  OUString aName = rName;
88  SCTAB nDummy;
89  if (!aName.isEmpty() && pModel->GetNamedObject(aName, OBJ_OLE2, nDummy))
90  {
91  // object exists - only RuntimeException is specified
92  throw uno::RuntimeException();
93  }
94 
95  uno::Reference<embed::XEmbeddedObject> xObject;
96 
97  if (SvtModuleOptions().IsChart())
98  xObject = m_pDocShell->GetEmbeddedObjectContainer().CreateEmbeddedObject(SvGlobalName(SO3_SCH_CLASSID).GetByteSequence(), aName);
99 
100  if (!xObject.is())
101  return;
102 
103  Point aRectPos(aRect.X, aRect.Y);
104  bool bLayoutRTL = rDoc.IsLayoutRTL(m_nTab);
105  if ((aRectPos.X() < 0 && !bLayoutRTL) || (aRectPos.X() > 0 && bLayoutRTL))
106  aRectPos.setX( 0 );
107 
108  if (aRectPos.Y() < 0)
109  aRectPos.setY( 0 );
110 
111  Size aRectSize(aRect.Width, aRect.Height);
112  if (aRectSize.Width() <= 0)
113  aRectSize.setWidth( 5000 ); // default size
114 
115  if (aRectSize.Height() <= 0)
116  aRectSize.setHeight( 5000 );
117 
118  ::tools::Rectangle aInsRect(aRectPos, aRectSize);
119 
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));
124  awt::Size aAwtSize;
125  aAwtSize.Width = aSize.Width();
126  aAwtSize.Height = aSize.Height();
127 
128  std::unique_ptr<sc::PivotTableDataProvider> pPivotTableDataProvider(new sc::PivotTableDataProvider(&rDoc));
129  pPivotTableDataProvider->setPivotTableName(rDataPilotName);
130 
131  uno::Reference<chart2::data::XDataProvider> xDataProvider(pPivotTableDataProvider.release());
132 
133  uno::Reference<chart2::data::XDataReceiver> xReceiver;
134 
135  if (xObject.is())
136  xReceiver.set(xObject->getComponent(), uno::UNO_QUERY);
137 
138  if (xReceiver.is())
139  {
140  xReceiver->attachDataProvider(xDataProvider);
141 
142  uno::Reference<util::XNumberFormatsSupplier> xNumberFormatsSupplier(m_pDocShell->GetModel(), uno::UNO_QUERY);
143  xReceiver->attachNumberFormatsSupplier(xNumberFormatsSupplier);
144 
145  uno::Sequence<beans::PropertyValue> aArgs( comphelper::InitPropertySequence({
146  { "CellRangeRepresentation", uno::makeAny(rDataPilotName) },
147  { "HasCategories", uno::makeAny(true) },
148  { "DataRowSource", uno::makeAny(chart::ChartDataRowSource_COLUMNS) }
149  }));
150  xReceiver->setArguments(aArgs);
151  }
152 
154  *pModel,
155  svt::EmbeddedObjectRef(xObject, embed::Aspects::MSOLE_CONTENT),
156  aName,
157  aInsRect);
158 
159  if (xObject.is())
160  xObject->setVisualAreaSize(nAspect, aAwtSize);
161 
162  pPage->InsertObject(pObject);
163  pModel->AddUndo(std::make_unique<SdrUndoInsertObj>(*pObject));
164 }
165 
166 void SAL_CALL TablePivotCharts::removeByName(const OUString& rName)
167 {
168  SolarMutexGuard aGuard;
170  if (pObject)
171  {
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());
177  }
178 }
179 
180 // XIndexAccess
181 sal_Int32 SAL_CALL TablePivotCharts::getCount()
182 {
183  SolarMutexGuard aGuard;
184  sal_Int32 nCount = 0;
185 
186  if (!m_pDocShell)
187  return nCount;
188 
190 
191  SdrOle2Obj* pOleObject = aIterator.next();
192  while (pOleObject)
193  {
194  if (pOleObject->GetObjRef().is())
195  nCount++;
196  pOleObject = aIterator.next();
197  }
198  return nCount;
199 }
200 
201 uno::Any SAL_CALL TablePivotCharts::getByIndex(sal_Int32 nIndex)
202 {
203  SolarMutexGuard aGuard;
204  SdrOle2Obj* pObject = sc::tools::getChartByIndex(m_pDocShell, m_nTab, nIndex,
206  if (!pObject)
207  throw lang::IndexOutOfBoundsException();
208 
209  OUString aName;
210  uno::Reference<embed::XEmbeddedObject> xObject = pObject->GetObjRef();
211  if (xObject.is())
212  aName = m_pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName(xObject);
213 
214  if (aName.isEmpty())
215  throw lang::IndexOutOfBoundsException();
216 
217  uno::Reference<table::XTablePivotChart> xChart(new TablePivotChart(m_pDocShell, m_nTab, aName));
218  if (!xChart.is())
219  throw lang::IndexOutOfBoundsException();
220 
221  return uno::makeAny(xChart);
222 }
223 
224 uno::Type SAL_CALL TablePivotCharts::getElementType()
225 {
226  SolarMutexGuard aGuard;
228 }
229 
230 sal_Bool SAL_CALL TablePivotCharts::hasElements()
231 {
232  SolarMutexGuard aGuard;
233  return getCount() != 0;
234 }
235 
236 uno::Any SAL_CALL TablePivotCharts::getByName(OUString const & rName)
237 {
238  SolarMutexGuard aGuard;
239 
241  throw container::NoSuchElementException();
242 
243  uno::Reference<table::XTablePivotChart> xChart(new TablePivotChart(m_pDocShell, m_nTab, rName));
244  if (!xChart.is())
245  throw container::NoSuchElementException();
246 
247  return uno::makeAny(xChart);
248 }
249 
250 uno::Sequence<OUString> SAL_CALL TablePivotCharts::getElementNames()
251 {
252  SolarMutexGuard aGuard;
253 
254  std::vector<OUString> aElements;
256 
257  SdrOle2Obj* pOleObject = aIterator.next();
258  while (pOleObject)
259  {
260  uno::Reference<embed::XEmbeddedObject> xObject = pOleObject->GetObjRef();
261  if (xObject.is())
262  {
263  OUString aName = m_pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName(xObject);
264  aElements.push_back(aName);
265  }
266  pOleObject = aIterator.next();
267  }
268  return comphelper::containerToSequence(aElements);
269 }
270 
271 sal_Bool SAL_CALL TablePivotCharts::hasByName(OUString const & rName)
272 {
273  SolarMutexGuard aGuard;
274 
275  return sc::tools::findChartsByName(m_pDocShell, m_nTab, rName, sc::tools::ChartSourceType::PIVOT_TABLE) != nullptr;
276 }
277 
278 } // end sc namespace
279 
280 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
long Width() const
OBJ_OLE2
SdrOle2Obj * getChartByIndex(ScDocShell *pDocShell, SCTAB nTab, long nIndex, ChartSourceType eChartSourceType)
Definition: ChartTools.cxx:120
css::uno::Reference< css::embed::XEmbeddedObject > const & GetObjRef() const
Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
long Height() const
SdrObject * GetNamedObject(const OUString &rName, sal_uInt16 nId, SCTAB &rFoundTab) const
Definition: drwlayer.cxx:1915
virtual void InsertObject(SdrObject *pObj, size_t nPos=SAL_MAX_SIZE)
EmbeddedObjectRef * pObject
SfxHintId GetId() const
void AddUndo(std::unique_ptr< SdrUndoAction > pUndo)
int nCount
css::uno::Sequence< css::beans::PropertyValue > InitPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1059
void Notify(ScModelObj &rModelObj, const ScRangeList &rChangeRanges, const OUString &rType=OUString("cell-change"), const css::uno::Sequence< css::beans::PropertyValue > &rProperties=css::uno::Sequence< css::beans::PropertyValue >())
Definition: docsh.hxx:477
const SdrPage * GetPage(sal_uInt16 nPgNum) const
unsigned char sal_Bool
sal_uInt32 GetOrdNum() const
css::uno::Type const & get()
#define SC_SIMPLE_SERVICE_INFO(ClassName, ClassNameAscii, ServiceAscii)
Definition: miscuno.hxx:64
virtual SdrObject * RemoveObject(size_t nObjNum)
Size GetSize() const
static MapUnit UnoEmbed2VCLMapUnit(sal_Int32 nUnoEmbedMapUnit)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
OUString aName
#define SO3_SCH_CLASSID
SdrOle2Obj * findChartsByName(ScDocShell *pDocShell, SCTAB nTab, OUString const &rName, ChartSourceType eChartSourceType)
Definition: ChartTools.cxx:98
SC_DLLPUBLIC bool IsLayoutRTL(SCTAB nTab) const
Definition: document.cxx:994
MapUnit
void setWidth(long nWidth)
sal_Int16 SCTAB
Definition: types.hxx:23
void setHeight(long nHeight)