summaryrefslogtreecommitdiffstats
path: root/sc/source/ui/unoobj/TablePivotCharts.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/unoobj/TablePivotCharts.cxx')
-rw-r--r--sc/source/ui/unoobj/TablePivotCharts.cxx280
1 files changed, 280 insertions, 0 deletions
diff --git a/sc/source/ui/unoobj/TablePivotCharts.cxx b/sc/source/ui/unoobj/TablePivotCharts.cxx
new file mode 100644
index 000000000..9c896e27f
--- /dev/null
+++ b/sc/source/ui/unoobj/TablePivotCharts.cxx
@@ -0,0 +1,280 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <memory>
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/chart/ChartDataRowSource.hpp>
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+
+#include <tools/gen.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdundo.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/classids.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <tools/globname.hxx>
+#include <svtools/embedhlp.hxx>
+#include <comphelper/sequence.hxx>
+#include <vcl/svapp.hxx>
+
+#include <TablePivotChart.hxx>
+#include <TablePivotCharts.hxx>
+#include <PivotTableDataProvider.hxx>
+#include <ChartTools.hxx>
+
+#include <miscuno.hxx>
+#include <docsh.hxx>
+#include <drwlayer.hxx>
+
+using namespace css;
+
+namespace sc
+{
+
+SC_SIMPLE_SERVICE_INFO(TablePivotCharts, "TablePivotCharts", "com.sun.star.table.TablePivotCharts")
+
+TablePivotCharts::TablePivotCharts(ScDocShell* pDocShell, SCTAB nTab)
+ : m_pDocShell(pDocShell)
+ , m_nTab(nTab)
+{
+ m_pDocShell->GetDocument().AddUnoObject(*this);
+}
+
+TablePivotCharts::~TablePivotCharts()
+{
+ SolarMutexGuard aGuard;
+
+ if (m_pDocShell)
+ m_pDocShell->GetDocument().RemoveUnoObject(*this);
+}
+
+void TablePivotCharts::Notify(SfxBroadcaster& /*rBroadcaster*/, const SfxHint& rHint)
+{
+ if (rHint.GetId() == SfxHintId::Dying)
+ m_pDocShell = nullptr;
+}
+
+// XTablePivotCharts
+void SAL_CALL TablePivotCharts::addNewByName(OUString const & rName,
+ const awt::Rectangle& aRect,
+ OUString const & rDataPilotName)
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pDocShell)
+ return;
+
+ ScDocument& rDoc = m_pDocShell->GetDocument();
+ ScDrawLayer* pModel = m_pDocShell->MakeDrawLayer();
+ SdrPage* pPage = pModel->GetPage(sal_uInt16(m_nTab));
+ if (!pPage)
+ return;
+
+ // chart can't be inserted if any ole object with that name exists on any table
+ // (empty string: generate valid name)
+
+ OUString aName = rName;
+ SCTAB nDummy;
+ if (!aName.isEmpty() && pModel->GetNamedObject(aName, OBJ_OLE2, nDummy))
+ {
+ // object exists - only RuntimeException is specified
+ throw uno::RuntimeException();
+ }
+
+ uno::Reference<embed::XEmbeddedObject> xObject;
+
+ if (SvtModuleOptions().IsChart())
+ xObject = m_pDocShell->GetEmbeddedObjectContainer().CreateEmbeddedObject(SvGlobalName(SO3_SCH_CLASSID).GetByteSequence(), aName);
+
+ if (xObject.is())
+ {
+ Point aRectPos(aRect.X, aRect.Y);
+ bool bLayoutRTL = rDoc.IsLayoutRTL(m_nTab);
+ if ((aRectPos.X() < 0 && !bLayoutRTL) || (aRectPos.X() > 0 && bLayoutRTL))
+ aRectPos.setX( 0 );
+
+ if (aRectPos.Y() < 0)
+ aRectPos.setY( 0 );
+
+ Size aRectSize(aRect.Width, aRect.Height);
+ if (aRectSize.Width() <= 0)
+ aRectSize.setWidth( 5000 ); // default size
+
+ if (aRectSize.Height() <= 0)
+ aRectSize.setHeight( 5000 );
+
+ ::tools::Rectangle aInsRect(aRectPos, aRectSize);
+
+ sal_Int64 nAspect(embed::Aspects::MSOLE_CONTENT);
+ MapUnit aMapUnit(VCLUnoHelper::UnoEmbed2VCLMapUnit(xObject->getMapUnit(nAspect)));
+ Size aSize(aInsRect.GetSize());
+ aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(aMapUnit));
+ awt::Size aAwtSize;
+ aAwtSize.Width = aSize.Width();
+ aAwtSize.Height = aSize.Height();
+
+ std::unique_ptr<sc::PivotTableDataProvider> pPivotTableDataProvider(new sc::PivotTableDataProvider(&rDoc));
+ pPivotTableDataProvider->setPivotTableName(rDataPilotName);
+
+ uno::Reference<chart2::data::XDataProvider> xDataProvider(pPivotTableDataProvider.release());
+
+ uno::Reference<chart2::data::XDataReceiver> xReceiver;
+
+ if (xObject.is())
+ xReceiver.set(xObject->getComponent(), uno::UNO_QUERY);
+
+ if (xReceiver.is())
+ {
+ xReceiver->attachDataProvider(xDataProvider);
+
+ uno::Reference<util::XNumberFormatsSupplier> xNumberFormatsSupplier(m_pDocShell->GetModel(), uno::UNO_QUERY);
+ xReceiver->attachNumberFormatsSupplier(xNumberFormatsSupplier);
+
+ uno::Sequence<beans::PropertyValue> aArgs( comphelper::InitPropertySequence({
+ { "CellRangeRepresentation", uno::makeAny(rDataPilotName) },
+ { "HasCategories", uno::makeAny(true) },
+ { "DataRowSource", uno::makeAny(chart::ChartDataRowSource_COLUMNS) }
+ }));
+ xReceiver->setArguments(aArgs);
+ }
+
+ SdrOle2Obj* pObject = new SdrOle2Obj(
+ *pModel,
+ svt::EmbeddedObjectRef(xObject, embed::Aspects::MSOLE_CONTENT),
+ aName,
+ aInsRect);
+
+ if (xObject.is())
+ xObject->setVisualAreaSize(nAspect, aAwtSize);
+
+ pPage->InsertObject(pObject);
+ pModel->AddUndo(std::make_unique<SdrUndoInsertObj>(*pObject));
+ }
+}
+
+void SAL_CALL TablePivotCharts::removeByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ SdrOle2Obj* pObject = sc::tools::findChartsByName(m_pDocShell, m_nTab, rName, sc::tools::ChartSourceType::PIVOT_TABLE);
+ if (pObject)
+ {
+ ScDocument& rDoc = m_pDocShell->GetDocument();
+ ScDrawLayer* pModel = rDoc.GetDrawLayer();
+ SdrPage* pPage = pModel->GetPage(sal_uInt16(m_nTab));
+ pModel->AddUndo(std::make_unique<SdrUndoDelObj>(*pObject));
+ pPage->RemoveObject(pObject->GetOrdNum());
+ }
+}
+
+// XIndexAccess
+sal_Int32 SAL_CALL TablePivotCharts::getCount()
+{
+ SolarMutexGuard aGuard;
+ sal_Int32 nCount = 0;
+
+ if (!m_pDocShell)
+ return nCount;
+
+ sc::tools::ChartIterator aIterator(m_pDocShell, m_nTab, sc::tools::ChartSourceType::PIVOT_TABLE);
+
+ SdrOle2Obj* pOleObject = aIterator.next();
+ while (pOleObject)
+ {
+ if (pOleObject->GetObjRef().is())
+ nCount++;
+ pOleObject = aIterator.next();
+ }
+ return nCount;
+}
+
+uno::Any SAL_CALL TablePivotCharts::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ SdrOle2Obj* pObject = sc::tools::getChartByIndex(m_pDocShell, m_nTab, nIndex,
+ sc::tools::ChartSourceType::PIVOT_TABLE);
+ if (!pObject)
+ throw lang::IndexOutOfBoundsException();
+
+ OUString aName;
+ uno::Reference<embed::XEmbeddedObject> xObject = pObject->GetObjRef();
+ if (xObject.is())
+ aName = m_pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName(xObject);
+
+ if (aName.isEmpty())
+ throw lang::IndexOutOfBoundsException();
+
+ uno::Reference<table::XTablePivotChart> xChart(new TablePivotChart(m_pDocShell, m_nTab, aName));
+ if (!xChart.is())
+ throw lang::IndexOutOfBoundsException();
+
+ return uno::makeAny(xChart);
+}
+
+uno::Type SAL_CALL TablePivotCharts::getElementType()
+{
+ SolarMutexGuard aGuard;
+ return cppu::UnoType<table::XTablePivotChart>::get();
+}
+
+sal_Bool SAL_CALL TablePivotCharts::hasElements()
+{
+ SolarMutexGuard aGuard;
+ return getCount() != 0;
+}
+
+uno::Any SAL_CALL TablePivotCharts::getByName(OUString const & rName)
+{
+ SolarMutexGuard aGuard;
+
+ if (!sc::tools::findChartsByName(m_pDocShell, m_nTab, rName, sc::tools::ChartSourceType::PIVOT_TABLE))
+ throw container::NoSuchElementException();
+
+ uno::Reference<table::XTablePivotChart> xChart(new TablePivotChart(m_pDocShell, m_nTab, rName));
+ if (!xChart.is())
+ throw container::NoSuchElementException();
+
+ return uno::makeAny(xChart);
+}
+
+uno::Sequence<OUString> SAL_CALL TablePivotCharts::getElementNames()
+{
+ SolarMutexGuard aGuard;
+
+ std::vector<OUString> aElements;
+ sc::tools::ChartIterator aIterator(m_pDocShell, m_nTab, sc::tools::ChartSourceType::PIVOT_TABLE);
+
+ SdrOle2Obj* pOleObject = aIterator.next();
+ while (pOleObject)
+ {
+ uno::Reference<embed::XEmbeddedObject> xObject = pOleObject->GetObjRef();
+ if (xObject.is())
+ {
+ OUString aName = m_pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName(xObject);
+ aElements.push_back(aName);
+ }
+ pOleObject = aIterator.next();
+ }
+ return comphelper::containerToSequence(aElements);
+}
+
+sal_Bool SAL_CALL TablePivotCharts::hasByName(OUString const & rName)
+{
+ SolarMutexGuard aGuard;
+
+ return sc::tools::findChartsByName(m_pDocShell, m_nTab, rName, sc::tools::ChartSourceType::PIVOT_TABLE) != nullptr;
+}
+
+} // end sc namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */