[Libreoffice-commits] core.git: include/xmloff sc/inc sc/Library_sc.mk sc/Module_sc.mk sc/source xmloff/source

Markus Mohrhard markus.mohrhard at googlemail.com
Mon Jul 31 02:31:21 UTC 2017


 include/xmloff/xmltoken.hxx            |    4 
 sc/Library_sc.mk                       |    1 
 sc/Module_sc.mk                        |    1 
 sc/inc/datamapper.hxx                  |  106 +++++++++++++
 sc/inc/document.hxx                    |    3 
 sc/source/core/data/documen2.cxx       |    1 
 sc/source/core/data/document10.cxx     |    9 +
 sc/source/filter/xml/xmlbodyi.cxx      |    5 
 sc/source/filter/xml/xmlexprt.cxx      |   28 +++
 sc/source/filter/xml/xmlexprt.hxx      |    1 
 sc/source/filter/xml/xmlmappingi.cxx   |  143 ++++++++++++++++++
 sc/source/filter/xml/xmlmappingi.hxx   |   52 ++++++
 sc/source/ui/docshell/dataprovider.cxx |  252 ++++++++++++++++++---------------
 sc/source/ui/inc/dataprovider.hxx      |   92 +++++-------
 sc/source/ui/view/gridwin.cxx          |   11 +
 xmloff/source/core/xmltoken.cxx        |    4 
 xmloff/source/token/tokens.txt         |    4 
 17 files changed, 557 insertions(+), 160 deletions(-)

New commits:
commit ce1b56ae4ad35fbb5e2f5cc6f4b7ce4839f4e285
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sun Jul 30 19:59:50 2017 +0200

    add initial file format representation for data import feature
    
    Change-Id: I51143ecfe4eb1584f13bd1590f927743de8fa91e
    Reviewed-on: https://gerrit.libreoffice.org/40572
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 02037f101b8c..e1c0c4d58aac 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -3256,6 +3256,10 @@ namespace xmloff { namespace token {
         XML_MARGIN, // #i117001#
 
         XML_PROPERTY_MAPPING,
+        XML_PROVIDER,
+        XML_DATA_MAPPINGS,
+        XML_DATA_MAPPING,
+        XML_DATA_FREQUENCY,
 
         // regina, ODF1.2 additional symbols in charts
         XML_STAR,
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
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 65829c298942..521e304cf3e1 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -3252,6 +3252,10 @@ namespace xmloff { namespace token {
         TOKEN( "margin", XML_MARGIN),
 
         TOKEN( "propertry-mapping", XML_PROPERTY_MAPPING),
+        TOKEN( "provider", XML_PROVIDER),
+        TOKEN( "data-mappings", XML_DATA_MAPPINGS),
+        TOKEN( "data-mapping", XML_DATA_MAPPING),
+        TOKEN( "frequency", XML_DATA_FREQUENCY),
 
         // regina, ODF1.2 additional symbols in charts
         TOKEN( "star",                         XML_STAR ),
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index e874670378bb..fc54aaf1b65b 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -3033,6 +3033,10 @@ min-value
 max-value
 margin
 propertry-mapping
+provider
+data-mappings
+data-mapping
+frequency
 star
 asterisk
 horizontal-bar


More information about the Libreoffice-commits mailing list