summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
Diffstat (limited to 'sc')
-rw-r--r--sc/Library_sc.mk1
-rw-r--r--sc/Module_sc.mk1
-rw-r--r--sc/inc/datamapper.hxx106
-rw-r--r--sc/inc/document.hxx3
-rw-r--r--sc/source/core/data/documen2.cxx1
-rw-r--r--sc/source/core/data/document10.cxx9
-rw-r--r--sc/source/filter/xml/xmlbodyi.cxx5
-rw-r--r--sc/source/filter/xml/xmlexprt.cxx28
-rw-r--r--sc/source/filter/xml/xmlexprt.hxx1
-rw-r--r--sc/source/filter/xml/xmlmappingi.cxx143
-rw-r--r--sc/source/filter/xml/xmlmappingi.hxx52
-rw-r--r--sc/source/ui/docshell/dataprovider.cxx252
-rw-r--r--sc/source/ui/inc/dataprovider.hxx92
-rw-r--r--sc/source/ui/view/gridwin.cxx11
14 files changed, 545 insertions, 160 deletions
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 87bd70ada626..e9220df0bd9c 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -325,6 +325,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/filter/xml/xmlfonte \
sc/source/filter/xml/xmlimprt \
sc/source/filter/xml/xmllabri \
+ sc/source/filter/xml/xmlmappingi \
sc/source/filter/xml/xmlnexpi \
sc/source/filter/xml/xmlrowi \
sc/source/filter/xml/xmlsceni \
diff --git a/sc/Module_sc.mk b/sc/Module_sc.mk
index 338ad5cdf609..25c987ff4ae2 100644
--- a/sc/Module_sc.mk
+++ b/sc/Module_sc.mk
@@ -60,7 +60,6 @@ $(eval $(call gb_Module_add_slowcheck_targets,sc, \
CppunitTest_sc_subsequent_export_test \
CppunitTest_sc_html_export_test \
CppunitTest_sc_copypaste \
- CppunitTest_sc_dataproviders_test \
))
# Various function tests fail in 32-bit linux_x86 build due to dreaded floating
diff --git a/sc/inc/datamapper.hxx b/sc/inc/datamapper.hxx
new file mode 100644
index 000000000000..28476df8d8dd
--- /dev/null
+++ b/sc/inc/datamapper.hxx
@@ -0,0 +1,106 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_SC_INC_EXTERNALDATAMAPPER_HXX
+#define INCLUDED_SC_INC_EXTERNALDATAMAPPER_HXX
+
+#include <memory>
+
+#include <rtl/ustring.hxx>
+
+class ScDocument;
+class ScDBData;
+
+namespace sc {
+
+class ScDBDataManager;
+class DataProvider;
+class ScDBDataManager;
+
+class ExternalDataSource
+{
+private:
+
+ /**
+ * The URL for the external data provider. The URL
+ * will be passed to the data provider together with
+ * the ID.
+ *
+ * A data provider may decide to ignore the URL string.
+ */
+ OUString maURL;
+
+ /**
+ * The data provider is a unique identifier that will
+ * allow to identify and instantiate the required data
+ * provider.
+ *
+ * Examples for the internal data providers are:
+ *
+ * org.libreoffice.dataprovider.calc.csv
+ * org.libreoffice.dataprovider.calc.json
+ *
+ * Only internal data providers should use the:
+ * "org.libreoffice.dataprovider prefix".
+ */
+ OUString maProvider;
+
+ /**
+ * The ID allows the same data provider to support different
+ * data streams.
+ *
+ * A data provider may decide to ignore the ID string.
+ */
+ OUString maID;
+
+ double mnUpdateFrequency;
+
+ std::shared_ptr<DataProvider> mpDataProvider;
+ std::shared_ptr<ScDBDataManager> mpDBDataManager;
+
+public:
+
+ ExternalDataSource(const OUString& rURL,
+ const OUString& rProvider);
+
+ void setUpdateFrequency(double nUpdateFrequency);
+
+ void setID(const OUString& rID);
+
+ const OUString& getURL() const;
+ const OUString& getProvider() const;
+ const OUString& getID() const;
+ double getUpdateFrequency() const;
+ OUString getDBName() const;
+ void setDBData(ScDBData* pDBData);
+
+ void refresh(ScDocument* pDoc);
+};
+
+class SC_DLLPUBLIC ExternalDataMapper
+{
+ //ScDocument* mpDoc;
+ std::vector<ExternalDataSource> maDataSources;
+
+public:
+ ExternalDataMapper(ScDocument* pDoc);
+
+ ~ExternalDataMapper();
+
+ void insertDataSource(const ExternalDataSource& rSource);
+
+ const std::vector<ExternalDataSource>& getDataSources() const;
+ std::vector<ExternalDataSource>& getDataSources();
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index bf5934381e92..2cc5f02ed70e 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -86,6 +86,7 @@ class ColumnSet;
class UpdatedRangeNames;
class TableColumnBlockPositionSet;
class ColumnIterator;
+class ExternalDataMapper;
}
@@ -350,6 +351,7 @@ private:
ScRefreshTimerControl* pRefreshTimerControl;
std::shared_ptr<SvxForbiddenCharactersTable> xForbiddenCharacters;
ScDBData* mpAnonymousDBData;
+ std::unique_ptr<sc::ExternalDataMapper> mpDataMapper;
ScFieldEditEngine* pCacheFieldEditEngine;
@@ -708,6 +710,7 @@ public:
const ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
void RefreshDirtyTableColumnNames();
+ sc::ExternalDataMapper& GetExternalDataMapper();
SC_DLLPUBLIC const ScRangeData* GetRangeAtBlock( const ScRange& rBlock, OUString* pName ) const;
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 104cd45f9663..973231dc389d 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -103,6 +103,7 @@
#include "docsh.hxx"
#include "clipoptions.hxx"
#include <listenercontext.hxx>
+#include "datamapper.hxx"
using namespace com::sun::star;
diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx
index 4768bfeadf10..89c1975ab0cb 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -29,6 +29,7 @@
#include <svl/whiter.hxx>
#include <editeng/colritem.hxx>
#include "scitems.hxx"
+#include "datamapper.hxx"
// Add totally brand-new methods to this source file.
@@ -930,4 +931,12 @@ void ScDocument::EnsureFormulaCellResults( const ScRange& rRange )
}
}
+sc::ExternalDataMapper& ScDocument::GetExternalDataMapper()
+{
+ if (!mpDataMapper)
+ mpDataMapper.reset(new sc::ExternalDataMapper(this));
+
+ return *mpDataMapper;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlbodyi.cxx b/sc/source/filter/xml/xmlbodyi.cxx
index ec36351fa27d..159c25a2e023 100644
--- a/sc/source/filter/xml/xmlbodyi.cxx
+++ b/sc/source/filter/xml/xmlbodyi.cxx
@@ -32,6 +32,7 @@
#include "xmlcvali.hxx"
#include "xmlstyli.hxx"
#include "xmllabri.hxx"
+#include "xmlmappingi.hxx"
#include "XMLConsolidationContext.hxx"
#include "XMLDDELinksContext.hxx"
#include "XMLCalculationSettingsContext.hxx"
@@ -172,6 +173,10 @@ uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
pContext = new ScXMLDatabaseRangesContext ( GetScImport(), nElement,
xAttrList );
break;
+ case XML_ELEMENT( CALC_EXT, XML_DATA_MAPPINGS ):
+ pContext = new ScXMLMappingsContext(GetScImport(), nElement,
+ xAttrList);
+ break;
case XML_ELEMENT( TABLE, XML_DATABASE_RANGE ):
pContext = new ScXMLDatabaseRangeContext ( GetScImport(), nElement,
xAttrList );
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 7d79adb440ba..60113982f85a 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -68,6 +68,7 @@
#include <documentlinkmgr.hxx>
#include <tokenstringcontext.hxx>
#include <cellform.hxx>
+#include "datamapper.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmlnmspe.hxx>
@@ -1933,6 +1934,7 @@ void ScXMLExport::ExportContent_()
WriteNamedExpressions();
WriteDataStream();
aExportDatabaseRanges.WriteDatabaseRanges();
+ WriteExternalDataMapping();
ScXMLExportDataPilot aExportDataPilot(*this);
aExportDataPilot.WriteDataPilots(xSpreadDoc);
WriteConsolidation();
@@ -4018,6 +4020,32 @@ void ScXMLExport::WriteNamedExpressions()
WriteNamedRange(pNamedRanges);
}
+void ScXMLExport::WriteExternalDataMapping()
+{
+ if (!pDoc)
+ return;
+
+ if (getDefaultVersion() <= SvtSaveOptions::ODFVER_012)
+ // Export this only for 1.2 extended and above.
+ return;
+
+ sc::ExternalDataMapper& rDataMapper = pDoc->GetExternalDataMapper();
+ auto& rDataSources = rDataMapper.getDataSources();
+ if (!rDataSources.empty())
+ {
+ SvXMLElementExport aMappings(*this, XML_NAMESPACE_CALC_EXT, XML_DATA_MAPPINGS, true, true);
+ for (auto& itr : rDataSources)
+ {
+ AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, itr.getURL());
+ AddAttribute(XML_NAMESPACE_CALC_EXT, XML_PROVIDER, itr.getProvider());
+ AddAttribute(XML_NAMESPACE_CALC_EXT, XML_DATA_FREQUENCY, OUString::number(itr.getUpdateFrequency()));
+ AddAttribute(XML_NAMESPACE_CALC_EXT, XML_ID, itr.getID());
+ AddAttribute(XML_NAMESPACE_CALC_EXT, XML_DATABASE_NAME, itr.getDBName());
+ SvXMLElementExport aMapping(*this, XML_NAMESPACE_CALC_EXT, XML_DATA_MAPPING, true, true);
+ }
+ }
+}
+
void ScXMLExport::WriteDataStream()
{
if (!pDoc)
diff --git a/sc/source/filter/xml/xmlexprt.hxx b/sc/source/filter/xml/xmlexprt.hxx
index 675b8183fd07..e23241596d8a 100644
--- a/sc/source/filter/xml/xmlexprt.hxx
+++ b/sc/source/filter/xml/xmlexprt.hxx
@@ -197,6 +197,7 @@ class ScXMLExport : public SvXMLExport
void WriteTheLabelRanges(const css::uno::Reference< css::sheet::XSpreadsheetDocument >& xSpreadDoc);
void WriteLabelRanges( const css::uno::Reference< css::container::XIndexAccess >& xRangesIAccess, bool bColumn );
void WriteNamedExpressions();
+ void WriteExternalDataMapping();
void WriteDataStream();
void WriteNamedRange(ScRangeName* pRangeName);
void ExportConditionalFormat(SCTAB nTab);
diff --git a/sc/source/filter/xml/xmlmappingi.cxx b/sc/source/filter/xml/xmlmappingi.cxx
new file mode 100644
index 000000000000..f65c929c070c
--- /dev/null
+++ b/sc/source/filter/xml/xmlmappingi.cxx
@@ -0,0 +1,143 @@
+/* -*- 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 "xmlmappingi.hxx"
+
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmlerror.hxx>
+
+#include "datamapper.hxx"
+#include "document.hxx"
+#include "dbdata.hxx"
+
+#include <sax/tools/converter.hxx>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+ScXMLMappingsContext::ScXMLMappingsContext( ScXMLImport& rImport,
+ sal_Int32 /*nElement*/,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& /* xAttrList */ ) :
+ ScXMLImportContext( rImport )
+{
+ // has no attributes
+ rImport.LockSolarMutex();
+}
+
+ScXMLMappingsContext::~ScXMLMappingsContext()
+{
+ GetScImport().UnlockSolarMutex();
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLMappingsContext::createFastChildContext(
+ sal_Int32 nElement,
+ const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
+{
+ SvXMLImportContext *pContext = nullptr;
+
+ switch( nElement )
+ {
+ case XML_ELEMENT( CALC_EXT, XML_DATA_MAPPING ):
+ {
+ pContext = new ScXMLMappingContext( GetScImport(), nElement, xAttrList );
+ }
+ break;
+ }
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport() );
+
+ return pContext;
+}
+
+ScXMLMappingContext::ScXMLMappingContext( ScXMLImport& rImport,
+ sal_Int32 /*nElement*/,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList) :
+ ScXMLImportContext( rImport )
+{
+ OUString aProvider;
+ OUString aID;
+ OUString aURL;
+ // OUString aFrequency;
+ OUString aDBName;
+ if( xAttrList.is() )
+ {
+ sax_fastparser::FastAttributeList *pAttribList =
+ sax_fastparser::FastAttributeList::castToFastAttributeList( xAttrList );
+
+ for( auto &aIter : *pAttribList )
+ {
+ switch( aIter.getToken() )
+ {
+ case XML_ELEMENT( XLINK, XML_HREF ):
+ {
+ aURL = aIter.toString();
+ }
+ break;
+ case XML_ELEMENT( CALC_EXT, XML_PROVIDER ):
+ {
+ aProvider = aIter.toString();
+ }
+ break;
+ case XML_ELEMENT( CALC_EXT, XML_ID ):
+ {
+ aID = aIter.toString();
+ }
+ break;
+ case XML_ELEMENT( CALC_EXT, XML_DATABASE_NAME ):
+ {
+ aDBName = aIter.toString();
+ }
+ break;
+ case XML_ELEMENT( CALC_EXT, XML_DATA_FREQUENCY ):
+ {
+ }
+ break;
+ }
+ }
+ }
+
+ if (!aProvider.isEmpty())
+ {
+ ScDocument* pDoc = GetScImport().GetDocument();
+ ScDBData* pDBData = pDoc->GetDBCollection()->getNamedDBs().findByUpperName(ScGlobal::pCharClass->uppercase(aDBName));
+ if (pDBData)
+ {
+ auto& rDataMapper = pDoc->GetExternalDataMapper();
+ sc::ExternalDataSource aSource(aURL, aProvider);
+ aSource.setID(aID);
+ aSource.setDBData(pDBData);
+ rDataMapper.insertDataSource(aSource);
+ }
+ }
+}
+
+ScXMLMappingContext::~ScXMLMappingContext()
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLMappingContext::createFastChildContext(
+ sal_Int32 /*nElement*/, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
+{
+ SvXMLImportContext *pContext = nullptr;
+
+ if( !pContext )
+ pContext = new SvXMLImportContext( GetImport() );
+
+ return pContext;
+}
+
+void SAL_CALL ScXMLMappingContext::endFastElement( sal_Int32 /*nElement*/ )
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlmappingi.hxx b/sc/source/filter/xml/xmlmappingi.hxx
new file mode 100644
index 000000000000..2fafd98ed74b
--- /dev/null
+++ b/sc/source/filter/xml/xmlmappingi.hxx
@@ -0,0 +1,52 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_SC_SOURCE_FILTER_XML_XMLMAPPINGI_HXX
+#define INCLUDED_SC_SOURCE_FILTER_XML_XMLMAPPINGI_HXX
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimp.hxx>
+
+#include "xmlimprt.hxx"
+#include "importcontext.hxx"
+
+class ScXMLMappingsContext : public ScXMLImportContext
+{
+public:
+
+ ScXMLMappingsContext( ScXMLImport& rImport, sal_Int32 nElement,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList);
+
+ virtual ~ScXMLMappingsContext() override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+};
+
+class ScXMLMappingContext : public ScXMLImportContext
+{
+
+public:
+
+ ScXMLMappingContext( ScXMLImport& rImport, sal_Int32 nElement,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList);
+
+ virtual ~ScXMLMappingContext() override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
+ virtual void SAL_CALL endFastElement( sal_Int32 nElement ) override;
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/docshell/dataprovider.cxx b/sc/source/ui/docshell/dataprovider.cxx
index 31b0732d8e73..0f39adca5b20 100644
--- a/sc/source/ui/docshell/dataprovider.cxx
+++ b/sc/source/ui/docshell/dataprovider.cxx
@@ -6,6 +6,7 @@
* 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 <dataprovider.hxx>
#include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
#include <com/sun/star/ucb/SimpleFileAccess.hpp>
@@ -56,30 +57,101 @@ std::unique_ptr<SvStream> FetchStreamFromURL(const OUString& rURL, OStringBuffer
}
-ExternalDataMapper::ExternalDataMapper(ScDocShell* pDocShell, const OUString& rURL, const OUString& rName, SCTAB nTab,
- SCCOL nCol1,SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bAllowResize, bool& bSuccess):
- maRange (ScRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab)),
- mpDocShell(pDocShell),
- mpDBCollection (pDocShell->GetDocument().GetDBCollection())
+ExternalDataSource::ExternalDataSource(const OUString& rURL,
+ const OUString& rProvider):
+ maURL(rURL),
+ maProvider(rProvider),
+ mnUpdateFrequency(0)
+{
+}
+
+void ExternalDataSource::setID(const OUString& rID)
+{
+ maID = rID;
+}
+
+const OUString& ExternalDataSource::getURL() const
+{
+ return maURL;
+}
+
+const OUString& ExternalDataSource::getProvider() const
+{
+ return maProvider;
+}
+
+const OUString& ExternalDataSource::getID() const
+{
+ return maID;
+}
+
+OUString ExternalDataSource::getDBName() const
+{
+ if (mpDBDataManager)
+ {
+ ScDBData* pDBData = mpDBDataManager->getDBData();
+ if (pDBData)
+ return pDBData->GetName();
+ }
+ return OUString();
+}
+
+void ExternalDataSource::setDBData(ScDBData* pDBData)
{
- bSuccess = true;
- ScDBCollection::NamedDBs& rNamedDBS = mpDBCollection->getNamedDBs();
- ScDBData* aDBData = new ScDBData (rName, nTab, nCol1, nRow1, nCol2, nRow2);
- if(!rNamedDBS.insert (aDBData))
- bSuccess = false;
- mpDBDataManager = std::shared_ptr<ScDBDataManager>(new ScDBDataManager(aDBData, bAllowResize));
- mpDBDataManager->SetDestinationRange(maRange);
+ if (!mpDBDataManager)
+ {
+ mpDBDataManager.reset(new ScDBDataManager(pDBData, false));
+ }
+ else
+ {
+ mpDBDataManager->SetDatabase(pDBData);
+ }
+}
- mpDataProvider = std::unique_ptr<DataProvider> (new CSVDataProvider(mpDocShell, rURL, maRange, mpDBDataManager.get()));
+double ExternalDataSource::getUpdateFrequency() const
+{
+ return mnUpdateFrequency;
+}
+
+void ExternalDataSource::refresh(ScDocument* pDoc)
+{
+ // no DB data available
+ if (!mpDBDataManager)
+ return;
+
+ // if no data provider exists, try to create one
+ if (!mpDataProvider)
+ mpDataProvider = DataProviderFactory::getDataProvider(pDoc, maProvider, maURL, maID, mpDBDataManager.get());
+
+ // if we still have not been able to create one, we can not refresh the data
+ if (!mpDataProvider)
+ return;
+
+ mpDataProvider->Import();
+}
+
+ExternalDataMapper::ExternalDataMapper(ScDocument* /*pDoc*/)
+ //mpDoc(pDoc)
+{
}
ExternalDataMapper::~ExternalDataMapper()
{
}
-void ExternalDataMapper::StartImport()
+void ExternalDataMapper::insertDataSource(const sc::ExternalDataSource& rSource)
+{
+ maDataSources.push_back(rSource);
+}
+
+const std::vector<sc::ExternalDataSource>& ExternalDataMapper::getDataSources() const
{
- mpDataProvider->StartImport();
+ return maDataSources;
+}
+
+std::vector<sc::ExternalDataSource>& ExternalDataMapper::getDataSources()
+{
+ return maDataSources;
}
DataProvider::~DataProvider()
@@ -137,18 +209,14 @@ public:
}
};
-CSVFetchThread::CSVFetchThread(ScDocument& rDoc, ScDBDataManager* pBDDataManager, const OUString& mrURL, size_t nColCount):
- Thread("ReaderThread"),
- mpStream(nullptr),
+CSVFetchThread::CSVFetchThread(ScDocument& rDoc, const OUString& mrURL):
+ Thread("CSV Fetch Thread"),
mrDocument(rDoc),
maURL (mrURL),
- mnColCount(nColCount),
- mpDBDataManager(pBDDataManager),
mbTerminate(false)
{
maConfig.delimiters.push_back(',');
maConfig.text_qualifier = '"';
- mrDocument.InsertTab(0, "blah");
}
CSVFetchThread::~CSVFetchThread()
@@ -175,17 +243,20 @@ void CSVFetchThread::EndThread()
void CSVFetchThread::execute()
{
OStringBuffer aBuffer(64000);
- mpStream = FetchStreamFromURL(maURL, aBuffer);
- if (mpStream->good())
+ std::unique_ptr<SvStream> pStream = FetchStreamFromURL(maURL, aBuffer);
+ if (pStream->good())
{
LinesType aLines(10);
SCROW nCurRow = 0;
SCCOL nCol = 0;
for (Line & rLine : aLines)
{
+ if (mbTerminate)
+ return;
+
rLine.maCells.clear();
- mpStream->ReadLine(rLine.maLine);
- CSVHandler aHdl(rLine, mnColCount);
+ pStream->ReadLine(rLine.maLine);
+ CSVHandler aHdl(rLine, MAXCOL);
orcus::csv_parser<CSVHandler> parser(rLine.maLine.getStr(), rLine.maLine.getLength(), aHdl, maConfig);
parser.parse();
@@ -210,8 +281,6 @@ void CSVFetchThread::execute()
}
nCurRow++;
}
- mpDBDataManager->SetSourceRange(nCol, nCurRow);
-
}
}
@@ -243,49 +312,40 @@ void CSVFetchThread::ResumeFetchStream()
maCondReadStream.set();
}
-CSVDataProvider::CSVDataProvider(ScDocShell* pDocShell, const OUString& rURL, ScRange& rRange, ScDBDataManager* pBDDataManager):
+CSVDataProvider::CSVDataProvider(ScDocument* pDoc, const OUString& rURL, ScDBDataManager* pBDDataManager):
maURL(rURL),
- mrRange(rRange),
- mpDocShell(pDocShell),
- mpDocument(&pDocShell->GetDocument()),
+ mpDocument(pDoc),
mpDBDataManager(pBDDataManager),
mpLines(nullptr),
- mnLineCount(0),
- mbImportUnderway(false)
+ mnLineCount(0)
{
- mpDBDataManager->SetDestinationRange(rRange);
}
CSVDataProvider::~CSVDataProvider()
{
}
-void CSVDataProvider::StartImport()
+void CSVDataProvider::Import()
{
- if (mbImportUnderway)
- return;
-
- if (!mxCSVFetchThread.is())
+ ScDocument aDoc(SCDOCMODE_CLIP);
+ aDoc.ResetClip(mpDocument, (SCTAB)0);
+ mxCSVFetchThread = new CSVFetchThread(aDoc, maURL);
+ mxCSVFetchThread->launch();
+ if (mxCSVFetchThread.is())
{
- ScDocument aDoc;
- mxCSVFetchThread = new CSVFetchThread(aDoc, mpDBDataManager, maURL, mrRange.aEnd.Col() - mrRange.aStart.Col() + 1);
- mxCSVFetchThread->launch();
- if (mxCSVFetchThread.is())
- {
- mxCSVFetchThread->EndThread();
- mxCSVFetchThread->join();
- }
-
- WriteToDoc(aDoc);
+ mxCSVFetchThread->join();
}
+ WriteToDoc(aDoc, mpDBDataManager->getDBData());
+
Refresh();
}
void CSVDataProvider::Refresh()
{
- mpDocShell->DoHardRecalc();
- mpDocShell->SetDocumentModified();
+ ScDocShell* pDocShell = static_cast<ScDocShell*>(mpDocument->GetDocumentShell());
+ pDocShell->DoHardRecalc();
+ pDocShell->SetDocumentModified();
}
Line CSVDataProvider::GetLine()
@@ -310,35 +370,42 @@ Line CSVDataProvider::GetLine()
return mpLines->at(mnLineCount++);
}
-void CSVDataProvider::WriteToDoc(ScDocument& rDoc)
+// TODO: why don't we use existing copy functionality
+void CSVDataProvider::WriteToDoc(ScDocument& rDoc, ScDBData* pDBData)
{
- if (mpDBDataManager->Resize())
- mrRange = mpDBDataManager->GetDestinationRange();
+ bool bShrunk = false;
+ SCCOL nStartCol = 0;
+ SCROW nStartRow = 0;
+ SCCOL nEndCol = MAXCOL;
+ SCROW nEndRow = MAXROW;
+ rDoc.ShrinkToUsedDataArea(bShrunk, 0, nStartCol, nStartRow, nEndCol, nEndRow, false, true, true);
+ ScRange aDestRange;
+ pDBData->GetArea(aDestRange);
double* pfValue;
- for (int nRow = mrRange.aStart.Row(); nRow < mrRange.aEnd.Row(); ++nRow)
+ for (int nRow = nStartRow; nRow < nEndRow; ++nRow)
{
- for (int nCol = mrRange.aStart.Col(); nCol < mrRange.aEnd.Col(); ++nCol)
+ for (int nCol = nStartCol; nCol < nEndCol; ++nCol)
{
- ScAddress aAddr = ScAddress(nCol, nRow, mrRange.aStart.Tab());
+ ScAddress aAddr = ScAddress(nCol, nRow, 0);
pfValue = rDoc.GetValueCell(aAddr);
if (pfValue == nullptr)
{
- OUString aString = rDoc.GetString(nCol, nRow, mrRange.aStart.Tab());
- mpDocument->SetString(nCol, nRow, mrRange.aStart.Tab(), aString);
+ OUString aString = rDoc.GetString(nCol, nRow, 0);
+ mpDocument->SetString(aDestRange.aStart.Col() + nCol, aDestRange.aStart.Row() + nRow, aDestRange.aStart.Tab(), aString);
}
else
{
- mpDocument->SetValue(nCol, nRow, mrRange.aStart.Tab(), *pfValue);
+ mpDocument->SetValue(aDestRange.aStart.Col() + nCol, aDestRange.aStart.Row() + nRow, aDestRange.aStart.Tab(), *pfValue);
}
}
}
}
-ScDBDataManager::ScDBDataManager(ScDBData* pDBData, bool bAllowResize = false):
-mpDBData(pDBData),
-mbAllowResize(bAllowResize)
+ScDBDataManager::ScDBDataManager(ScDBData* pDBData, bool /*bAllowResize*/):
+ mpDBData(pDBData)
+ //mbAllowResize(bAllowResize)
{
}
@@ -351,60 +418,31 @@ void ScDBDataManager::SetDatabase(ScDBData* pDbData)
mpDBData = pDbData;
}
-bool ScDBDataManager::IsResizeAllowed()
+ScDBData* ScDBDataManager::getDBData()
{
- return mbAllowResize;
+ return mpDBData;
}
-bool ScDBDataManager::RequiresResize(SCROW& RowDifference, SCCOL& ColDifference)
+bool DataProviderFactory::isInternalDataProvider(const OUString& rProvider)
{
- SCROW nTotalSourceRows = maSourceRange.aStart.Row() - maSourceRange.aEnd.Row();
- SCCOL nTotalSourceCols = maSourceRange.aStart.Col() - maSourceRange.aEnd.Col();
-
- SCROW nTotalDestinationRows = maDestinationRange.aStart.Row() - maDestinationRange.aEnd.Row();
- SCCOL nTotalDestinationCols = maDestinationRange.aStart.Col() - maDestinationRange.aEnd.Col();
-
- RowDifference = nTotalSourceRows - nTotalDestinationRows;
- ColDifference = nTotalSourceCols - nTotalDestinationCols;
-
- if (nTotalSourceRows != nTotalDestinationRows || nTotalSourceCols != nTotalDestinationCols)
- return true;
-
- return false;
+ return rProvider.startsWith("org.libreoffice.calc");
}
-bool ScDBDataManager::Resize()
+std::shared_ptr<DataProvider> DataProviderFactory::getDataProvider(ScDocument* pDoc, const OUString& rProvider, const OUString& rURL, const OUString& /*rID*/, ScDBDataManager* pManager)
{
- SCROW RowDifference =0;
- SCCOL ColDifference = 0;
-
- if (IsResizeAllowed() && RequiresResize(RowDifference, ColDifference))
+ bool bInternal = DataProviderFactory::isInternalDataProvider(rProvider);
+ if (bInternal)
{
- maDestinationRange.aEnd = ScAddress(maDestinationRange.aEnd.Row() + RowDifference, maDestinationRange.aEnd.Col() + ColDifference, maDestinationRange.aEnd.Tab());
-
- return true;
+ if (rProvider == "org.libreoffice.calc.csv")
+ return std::shared_ptr<DataProvider>(new CSVDataProvider(pDoc, rURL, pManager));
+ }
+ else
+ {
+ SAL_WARN("sc", "no external data provider supported yet");
+ return std::shared_ptr<DataProvider>();
}
- return false;
-}
-
-void ScDBDataManager::SetSourceRange(SCCOL nCol, SCROW nRow)
-{
- maSourceRange = ScRange(0, 0, 0, nCol, nRow, 0);
-}
-
-void ScDBDataManager::SetDestinationRange(ScRange& aRange)
-{
- maDestinationRange = aRange;
-}
-
-ScRange& ScDBDataManager::GetSourceRange()
-{
- return maSourceRange;
-}
-ScRange& ScDBDataManager::GetDestinationRange()
-{
- return maDestinationRange;
+ return std::shared_ptr<DataProvider>();
}
}
diff --git a/sc/source/ui/inc/dataprovider.hxx b/sc/source/ui/inc/dataprovider.hxx
index 8f943ec082bc..7f50b2ddbc5f 100644
--- a/sc/source/ui/inc/dataprovider.hxx
+++ b/sc/source/ui/inc/dataprovider.hxx
@@ -23,6 +23,7 @@
#include "docsh.hxx"
#include "scdllapi.h"
+#include "datamapper.hxx"
#include <queue>
@@ -39,24 +40,6 @@ class DataProvider;
class CSVDataProvider;
class ScDBDataManager;
-class SC_DLLPUBLIC ExternalDataMapper
-{
- ScRange maRange;
- ScDocShell* mpDocShell;
- std::unique_ptr<DataProvider> mpDataProvider;
- ScDocument maDocument;
- ScDBCollection* mpDBCollection;
- std::shared_ptr<ScDBDataManager> mpDBDataManager;
-
-public:
- ExternalDataMapper(ScDocShell* pDocShell, const OUString& rUrl, const OUString& rName,
- SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCOL2, SCROW nRow2, bool bAllowResize, bool& bSuccess);
-
- ~ExternalDataMapper();
-
- void StartImport();
-};
-
struct Cell
{
struct Str
@@ -87,11 +70,8 @@ typedef std::vector<Line> LinesType;
class CSVFetchThread : public salhelper::Thread
{
- std::unique_ptr<SvStream> mpStream;
ScDocument& mrDocument;
OUString maURL;
- size_t mnColCount;
- ScDBDataManager* mpDBDataManager;
bool mbTerminate;
osl::Mutex maMtxTerminate;
@@ -104,10 +84,9 @@ class CSVFetchThread : public salhelper::Thread
orcus::csv::parser_config maConfig;
- virtual void execute() override;
public:
- CSVFetchThread(ScDocument& rDoc, ScDBDataManager*, const OUString&, size_t);
+ CSVFetchThread(ScDocument& rDoc, const OUString&);
virtual ~CSVFetchThread() override;
void RequestTerminate();
@@ -120,72 +99,81 @@ public:
void WaitForNewLines();
LinesType* GetNewLines();
void ResumeFetchStream();
+
+ virtual void execute() override;
};
+/**
+ * Abstract class for all data provider.
+ *
+ */
class DataProvider
{
public:
virtual ~DataProvider() = 0;
- virtual void StartImport() = 0;
- virtual void Refresh() = 0;
- virtual void WriteToDoc(ScDocument&) = 0;
+ virtual void Import() = 0;
+ virtual void WriteToDoc(ScDocument& rDoc, ScDBData* pDBData) = 0;
- virtual ScRange GetRange() const = 0;
virtual const OUString& GetURL() const = 0;
};
class CSVDataProvider : public DataProvider
{
OUString maURL;
- ScRange mrRange;
rtl::Reference<CSVFetchThread> mxCSVFetchThread;
- ScDocShell* mpDocShell;
ScDocument* mpDocument;
ScDBDataManager* mpDBDataManager;
LinesType* mpLines;
size_t mnLineCount;
- bool mbImportUnderway;
-
+ void Refresh();
+ Line GetLine();
public:
- CSVDataProvider (ScDocShell* pDocShell, const OUString& rUrl, ScRange& rRange, ScDBDataManager*);
+ CSVDataProvider (ScDocument* pDoc, const OUString& rURL, ScDBDataManager* pDBManager);
virtual ~CSVDataProvider() override;
- virtual void StartImport() override;
- virtual void Refresh() override;
- virtual void WriteToDoc(ScDocument&) override;
- Line GetLine();
+ virtual void Import() override;
- ScRange GetRange() const override
- {
- return mrRange;
- }
+ // TODO: this method should be moved to the ScDBDataManager
+ virtual void WriteToDoc(ScDocument& rDoc, ScDBData* pDBData) override;
const OUString& GetURL() const override { return maURL; }
};
+
+/**
+ * This class handles the copying of the data from the imported
+ * temporary document to the actual document. Additionally, in the future
+ * we may decide to store data transformations in this class.
+ *
+ * In addition this class also handles how to deal with excess data by for example extending the ScDBData or by only showing the first or last entries.
+ *
+ * TODO: move the DataProvider::WriteToDoc here
+ *
+ */
class ScDBDataManager
{
ScDBData* mpDBData;
- ScRange maSourceRange;
- ScRange maDestinationRange;
- bool mbAllowResize;
public:
- ScDBDataManager(ScDBData*, bool);
+ ScDBDataManager(ScDBData* pDBData, bool bAllowResize);
~ScDBDataManager();
- bool IsResizeAllowed();
- bool Resize();
- bool RequiresResize(SCROW&, SCCOL&);
+ void SetDatabase(ScDBData* pDBData);
+
+ ScDBData* getDBData();
+};
- void SetDatabase(ScDBData*);
- void SetSourceRange(SCCOL, SCROW);
- void SetDestinationRange(ScRange&);
+class DataProviderFactory
+{
+private:
+
+ static bool isInternalDataProvider(const OUString& rProvider);
+
+public:
- ScRange& GetDestinationRange();
- ScRange& GetSourceRange();
+ static std::shared_ptr<DataProvider> getDataProvider(ScDocument* pDoc, const OUString& rProvider, const OUString& rURL, const OUString& rID, ScDBDataManager* pManager);
};
}
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index b37b6d1f2e99..77865b57f8e7 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -133,6 +133,7 @@
#include "uiobject.hxx"
#include "scabstdlg.hxx"
#include "undoblk.hxx"
+#include "datamapper.hxx"
#include <svx/sdrpagewindow.hxx>
#include <svx/sdr/overlay/overlaymanager.hxx>
@@ -3087,6 +3088,16 @@ void ScGridWindow::KeyInput(const KeyEvent& rKEvt)
{
dumpColumnCellStorage();
}
+ else if (rKeyCode.GetCode() == KEY_F7)
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+ auto& rMapper = pDoc->GetExternalDataMapper();
+ for (auto& itr : rMapper.getDataSources())
+ {
+ itr.refresh(pDoc);
+ }
+ return;
+ }
}
#endif