[Libreoffice-commits] core.git: Branch 'feature/datastreams' - 5 commits - sc/inc sc/source

Matúš Kukan matus.kukan at collabora.com
Wed Nov 27 04:10:41 PST 2013


Rebased ref, commits from common ancestor:
commit f0f384b9f721d793dc5877e0a8596d47280ba34e
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Wed Nov 27 12:42:59 2013 +0100

    Let's use ScRefreshTimer for data streams instead of our own thread.
    
    As was the original idea, for some reason abandoned, and as ScAreaLink does.
    
    The main advantage is that ImportData() is not called anymore with
    invalid mpScDocument (when we close it).
    There is surely something going on with SolarMutex and it just works better.
    
    Change-Id: I09256a18ffa14606fc8e06b968016bbc0562a6fa

diff --git a/sc/source/ui/docshell/datastream.cxx b/sc/source/ui/docshell/datastream.cxx
index 504a4dd..9c45df0 100644
--- a/sc/source/ui/docshell/datastream.cxx
+++ b/sc/source/ui/docshell/datastream.cxx
@@ -34,37 +34,6 @@
 
 namespace datastreams {
 
-class CallerThread : public salhelper::Thread
-{
-    DataStream *mpDataStream;
-public:
-    osl::Condition maStart;
-    bool mbTerminate;
-
-    CallerThread(DataStream *pData):
-        Thread("CallerThread")
-        ,mpDataStream(pData)
-        ,mbTerminate(false)
-    {}
-
-private:
-    virtual void execute()
-    {
-        while (!mbTerminate)
-        {
-            // wait for a small amount of time, so that
-            // painting methods have a chance to be called.
-            // And also to make UI more responsive.
-            TimeValue const aTime = {0, 100000};
-            maStart.wait();
-            maStart.reset();
-            if (!mbTerminate)
-                while (mpDataStream->ImportData())
-                    wait(aTime);
-        };
-    }
-};
-
 class ReaderThread : public salhelper::Thread
 {
     SvStream *mpStream;
@@ -215,7 +184,8 @@ DataStream* DataStream::Set(ScDocShell *pShell, const OUString& rURL, const OUSt
 
 DataStream::DataStream(ScDocShell *pShell, const OUString& rURL, const OUString& rRange,
         sal_Int32 nLimit, const OUString& rMove, sal_uInt32 nSettings)
-    : mpScDocShell(pShell)
+    : ScRefreshTimer()
+    , mpScDocShell(pShell)
     , mpScDocument(mpScDocShell->GetDocument())
     , meMove(NO_MOVE)
     , mbRunning(false)
@@ -223,9 +193,9 @@ DataStream::DataStream(ScDocShell *pShell, const OUString& rURL, const OUString&
     , mnLinesCount(0)
     , mpEndRange(NULL)
 {
-    mxThread = new datastreams::CallerThread( this );
-    mxThread->launch();
-
+    SetRefreshHandler(LINK( this, DataStream, RefreshHdl ));
+    SetRefreshControl(mpScDocument->GetRefreshTimerControlAddress());
+    SetTimeout( 1 );
     Decode(rURL, rRange, nLimit, rMove, nSettings);
 
     maStartRange = maRange;
@@ -241,10 +211,7 @@ DataStream::DataStream(ScDocShell *pShell, const OUString& rURL, const OUString&
 DataStream::~DataStream()
 {
     if (mbRunning)
-        Stop();
-    mxThread->mbTerminate = true;
-    mxThread->maStart.set();
-    mxThread->join();
+        StopImport();
     if (mxReaderThread.is())
         mxReaderThread->endThread();
 }
@@ -303,21 +270,22 @@ void DataStream::Decode(const OUString& rURL, const OUString& rRange,
         meMove = MOVE_DOWN;
 }
 
-void DataStream::Start()
+void DataStream::StartImport()
 {
     if (mbRunning)
         return;
     mbIsUndoEnabled = mpScDocument->IsUndoEnabled();
     mpScDocument->EnableUndo(false);
     mbRunning = true;
-    mxThread->maStart.set();
+    AutoTimer::Start();
 }
 
-void DataStream::Stop()
+void DataStream::StopImport()
 {
     if (!mbRunning)
         return;
     mbRunning = false;
+    AutoTimer::Stop();
     mpScDocument->EnableUndo(mbIsUndoEnabled);
 }
 
@@ -343,6 +311,12 @@ void DataStream::MoveData()
     }
 }
 
+IMPL_LINK_NOARG(DataStream, RefreshHdl)
+{
+    ImportData();
+    return 0;
+}
+
 bool DataStream::ImportData()
 {
     SolarMutexGuard aGuard;
@@ -410,7 +384,7 @@ sfx2::SvBaseLink::UpdateResult DataStream::DataChanged(
         const OUString& , const css::uno::Any& )
 {
     MakeToolbarVisible(mpScDocShell);
-    Stop();
+    StopImport();
     bool bStart = true;
     if (mnSettings & SCRIPT_STREAM &&
         officecfg::Office::Common::Security::Scripting::MacroSecurityLevel::get() >= 1)
@@ -421,7 +395,7 @@ sfx2::SvBaseLink::UpdateResult DataStream::DataChanged(
             bStart = false;
     }
     if (bStart)
-        Start();
+        StartImport();
     return SUCCESS;
 }
 
@@ -432,10 +406,10 @@ void DataStream::Edit(Window* pWindow, const Link& )
     if (aDialog.Execute() == RET_OK)
     {
         bool bWasRunning = mbRunning;
-        Stop();
+        StopImport();
         aDialog.StartStream(this);
         if (bWasRunning)
-            Start();
+            StartImport();
     }
 }
 
diff --git a/sc/source/ui/inc/datastream.hxx b/sc/source/ui/inc/datastream.hxx
index 19a522b..59d43fe 100644
--- a/sc/source/ui/inc/datastream.hxx
+++ b/sc/source/ui/inc/datastream.hxx
@@ -13,13 +13,13 @@
 #include <rtl/ustring.hxx>
 #include <sfx2/lnkbase.hxx>
 #include <address.hxx>
+#include <refreshtimer.hxx>
 
 #include <boost/noncopyable.hpp>
 #include <boost/scoped_ptr.hpp>
 #include <vector>
 
 namespace datastreams {
-    class CallerThread;
     class ReaderThread;
 }
 class ScDocShell;
@@ -28,10 +28,11 @@ class Window;
 
 typedef std::vector<OString> LinesList;
 
-class DataStream : boost::noncopyable, public sfx2::SvBaseLink
+class DataStream : boost::noncopyable, public sfx2::SvBaseLink, ScRefreshTimer
 {
     OString ConsumeLine();
     void MoveData();
+    DECL_LINK( RefreshHdl, void* );
 
 public:
     enum MoveEnum { NO_MOVE, RANGE_DOWN, MOVE_DOWN, MOVE_UP };
@@ -44,6 +45,7 @@ public:
     DataStream(ScDocShell *pShell, const OUString& rURL, const OUString& rRange,
             sal_Int32 nLimit, const OUString& rMove, sal_uInt32 nSettings);
     virtual ~DataStream() SAL_OVERRIDE;
+    // sfx2::SvBaseLink
     virtual sfx2::SvBaseLink::UpdateResult DataChanged(
             const OUString& , const css::uno::Any& ) SAL_OVERRIDE;
     virtual void Edit(Window* , const Link& ) SAL_OVERRIDE;
@@ -56,8 +58,8 @@ public:
     void Decode(const OUString& rURL, const OUString& rRange, const sal_Int32 nLimit,
             const OUString& rMove, const sal_uInt32 nSettings);
     bool ImportData();
-    void Start();
-    void Stop();
+    void StartImport();
+    void StopImport();
 
 private:
     ScDocShell *mpScDocShell;
@@ -76,7 +78,6 @@ private:
     ScRange maRange;
     ScRange maStartRange;
     boost::scoped_ptr<ScRange> mpEndRange;
-    rtl::Reference<datastreams::CallerThread> mxThread;
     rtl::Reference<datastreams::ReaderThread> mxReaderThread;
 };
 
diff --git a/sc/source/ui/miscdlgs/datastreamdlg.cxx b/sc/source/ui/miscdlgs/datastreamdlg.cxx
index 23adbd4..5dba0ae 100644
--- a/sc/source/ui/miscdlgs/datastreamdlg.cxx
+++ b/sc/source/ui/miscdlgs/datastreamdlg.cxx
@@ -127,7 +127,7 @@ void DataStreamDlg::StartStream(DataStream *pStream)
             , nSettings
             );
     DataStream::MakeToolbarVisible( mpDocShell );
-    pStream->Start();
+    pStream->StartImport();
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx
index aceb41c..a8d301e 100644
--- a/sc/source/ui/view/cellsh2.cxx
+++ b/sc/source/ui/view/cellsh2.cxx
@@ -750,7 +750,7 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
                     const sfx2::SvBaseLinks& rLinks = pDoc->GetLinkManager()->GetLinks();
                     for (size_t i = 0; i < rLinks.size(); i++)
                         if (DataStream *pStream = dynamic_cast<DataStream*>(&(*(*rLinks[i]))))
-                            pStream->Start();
+                            pStream->StartImport();
                 }
             }
             break;
@@ -762,7 +762,7 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
                     const sfx2::SvBaseLinks& rLinks = pDoc->GetLinkManager()->GetLinks();
                     for (size_t i = 0; i < rLinks.size(); i++)
                         if (DataStream *pStream = dynamic_cast<DataStream*>(&(*(*rLinks[i]))))
-                            pStream->Stop();
+                            pStream->StopImport();
                 }
             }
             break;
commit ab06ecfad1f3a0c9c417f490353ad20d00a78a3d
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Tue Nov 26 13:48:23 2013 +0100

    datastreams: for security, ask before executing a script when importing
    
    Change-Id: Ia6e4cb911958e903afa3abf7ccb0f1a163a97a65

diff --git a/sc/inc/globstr.hrc b/sc/inc/globstr.hrc
index f02ef51..e979c74 100644
--- a/sc/inc/globstr.hrc
+++ b/sc/inc/globstr.hrc
@@ -693,8 +693,9 @@
 
 #define STR_CTRLCLICKHYPERLINK      526
 #define STR_CLICKHYPERLINK          527
+#define STR_EXECUTE_SCRIPT          528
 
-#define SC_GLOBSTR_STR_COUNT        528     /**< the count of permanently resident strings */
+#define SC_GLOBSTR_STR_COUNT        529     /**< the count of permanently resident strings */
 
 #endif
 
diff --git a/sc/source/ui/docshell/datastream.cxx b/sc/source/ui/docshell/datastream.cxx
index e8e5674..504a4dd 100644
--- a/sc/source/ui/docshell/datastream.cxx
+++ b/sc/source/ui/docshell/datastream.cxx
@@ -11,17 +11,20 @@
 
 #include <com/sun/star/frame/XLayoutManager.hpp>
 #include <com/sun/star/ui/XUIElement.hpp>
+#include <officecfg/Office/Common.hxx>
 #include <osl/conditn.hxx>
 #include <rtl/strbuf.hxx>
 #include <salhelper/thread.hxx>
 #include <sfx2/linkmgr.hxx>
 #include <sfx2/viewfrm.hxx>
+#include <vcl/msgbox.hxx>
 #include <arealink.hxx>
 #include <asciiopt.hxx>
 #include <datastreamdlg.hxx>
 #include <dbfunc.hxx>
 #include <docsh.hxx>
 #include <documentimport.hxx>
+#include <globstr.hrc>
 #include <impex.hxx>
 #include <rangelst.hxx>
 #include <tabvwsh.hxx>
@@ -407,7 +410,18 @@ sfx2::SvBaseLink::UpdateResult DataStream::DataChanged(
         const OUString& , const css::uno::Any& )
 {
     MakeToolbarVisible(mpScDocShell);
-    Start();
+    Stop();
+    bool bStart = true;
+    if (mnSettings & SCRIPT_STREAM &&
+        officecfg::Office::Common::Security::Scripting::MacroSecurityLevel::get() >= 1)
+    {
+        QueryBox aQBox( NULL, WB_YES_NO | WB_DEF_YES, ScGlobal::GetRscString(
+                    STR_EXECUTE_SCRIPT ).replaceFirst("%URL", msURL) );
+        if (RET_YES != aQBox.Execute())
+            bStart = false;
+    }
+    if (bStart)
+        Start();
     return SUCCESS;
 }
 
diff --git a/sc/source/ui/src/globstr.src b/sc/source/ui/src/globstr.src
index ee46a95..f4bdf6a 100644
--- a/sc/source/ui/src/globstr.src
+++ b/sc/source/ui/src/globstr.src
@@ -1373,6 +1373,10 @@ Resource RID_GLOBSTR
     {
         Text [ en-US ] = "This file contains links to other files.\nShould they be updated?" ;
     };
+    String STR_EXECUTE_SCRIPT
+    {
+        Text [ en-US ] = "Do you want to execute \"%URL\"?" ;
+    };
     String STR_REIMPORT_AFTER_LOAD
     {
         Text [ en-US ] = "This file contains queries. The results of these queries were not saved.\nDo you want these queries to be repeated?" ;
commit d968f35ec07ec74d0b0ccfcc268ac95371d5286c
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Mon Nov 25 12:01:57 2013 +0100

    Allow to edit data stream from Edit-> Links... dialog.
    
    Change-Id: Ibb456da55f04c39ddb7b58eb71ca488cf209edb5

diff --git a/sc/source/ui/docshell/datastream.cxx b/sc/source/ui/docshell/datastream.cxx
index aef6c3b..e8e5674 100644
--- a/sc/source/ui/docshell/datastream.cxx
+++ b/sc/source/ui/docshell/datastream.cxx
@@ -18,6 +18,7 @@
 #include <sfx2/viewfrm.hxx>
 #include <arealink.hxx>
 #include <asciiopt.hxx>
+#include <datastreamdlg.hxx>
 #include <dbfunc.hxx>
 #include <docsh.hxx>
 #include <documentimport.hxx>
@@ -410,8 +411,18 @@ sfx2::SvBaseLink::UpdateResult DataStream::DataChanged(
     return SUCCESS;
 }
 
-void DataStream::Edit(Window* , const Link& )
+void DataStream::Edit(Window* pWindow, const Link& )
 {
+    DataStreamDlg aDialog(mpScDocShell, pWindow);
+    aDialog.Init(msURL, msRange, mnLimit, msMove, mnSettings);
+    if (aDialog.Execute() == RET_OK)
+    {
+        bool bWasRunning = mbRunning;
+        Stop();
+        aDialog.StartStream(this);
+        if (bWasRunning)
+            Start();
+    }
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/datastream.hxx b/sc/source/ui/inc/datastream.hxx
index b60a988..19a522b 100644
--- a/sc/source/ui/inc/datastream.hxx
+++ b/sc/source/ui/inc/datastream.hxx
@@ -31,8 +31,6 @@ typedef std::vector<OString> LinesList;
 class DataStream : boost::noncopyable, public sfx2::SvBaseLink
 {
     OString ConsumeLine();
-    void Decode(const OUString& rURL, const OUString& rRange, const sal_Int32 nLimit,
-            const OUString& rMove, const sal_uInt32 nSettings);
     void MoveData();
 
 public:
@@ -55,6 +53,8 @@ public:
     const sal_Int32& GetLimit() const { return mnLimit; }
     const OUString& GetMove() const { return msMove; }
     const sal_uInt32& GetSettings() const { return mnSettings; }
+    void Decode(const OUString& rURL, const OUString& rRange, const sal_Int32 nLimit,
+            const OUString& rMove, const sal_uInt32 nSettings);
     bool ImportData();
     void Start();
     void Stop();
diff --git a/sc/source/ui/inc/datastreamdlg.hxx b/sc/source/ui/inc/datastreamdlg.hxx
index cb469d7..5bb05f3 100644
--- a/sc/source/ui/inc/datastreamdlg.hxx
+++ b/sc/source/ui/inc/datastreamdlg.hxx
@@ -13,6 +13,7 @@
 #include <vcl/dialog.hxx>
 #include <vcl/layout.hxx>
 
+class DataStream;
 class ScDocShell;
 class SvtURLBox;
 
@@ -25,6 +26,7 @@ class DataStreamDlg : public ModalDialog
     RadioButton*    m_pRBScriptData;
     RadioButton*    m_pRBValuesInLine;
     RadioButton*    m_pRBAddressValue;
+    RadioButton*    m_pRBDataDown;
     RadioButton*    m_pRBRangeDown;
     RadioButton*    m_pRBNoMove;
     RadioButton*    m_pRBMaxLimit;
@@ -43,7 +45,9 @@ class DataStreamDlg : public ModalDialog
 public:
     DataStreamDlg(ScDocShell *pDocShell, Window* pParent);
     ~DataStreamDlg() {}
-    void StartStream();
+    void Init(const OUString& rURL, const OUString& rRange, const sal_Int32 nLimit,
+            const OUString& rMove, const sal_uInt32 nSettings);
+    void StartStream(DataStream *pStream = 0);
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/miscdlgs/datastreamdlg.cxx b/sc/source/ui/miscdlgs/datastreamdlg.cxx
index b266687..23adbd4 100644
--- a/sc/source/ui/miscdlgs/datastreamdlg.cxx
+++ b/sc/source/ui/miscdlgs/datastreamdlg.cxx
@@ -23,6 +23,7 @@ DataStreamDlg::DataStreamDlg(ScDocShell *pDocShell, Window* pParent)
     get(m_pRBScriptData, "scriptdata");
     get(m_pRBValuesInLine, "valuesinline");
     get(m_pRBAddressValue, "addressvalue");
+    get(m_pRBDataDown, "datadown");
     get(m_pRBRangeDown, "rangedown");
     get(m_pRBNoMove, "nomove");
     get(m_pRBMaxLimit, "maxlimit");
@@ -70,15 +71,35 @@ void DataStreamDlg::UpdateEnable()
     }
     else
     {
-        m_pVclFrameLimit->Show(true);
+        m_pVclFrameLimit->Show();
         m_pVclFrameMove->Show();
         m_pVclFrameRange->Show();
         bOk = bOk && !m_pEdRange->GetText().isEmpty();
     }
     m_pBtnOk->Enable(bOk);
+    setOptimalLayoutSize();
 }
 
-void DataStreamDlg::StartStream()
+void DataStreamDlg::Init(const OUString& rURL, const OUString& rRange, const sal_Int32 nLimit,
+        const OUString& rMove, const sal_uInt32 nSettings)
+{
+    m_pEdLimit->SetText(OUString::number(nLimit));
+    m_pCbUrl->SetText(rURL);
+    if (nSettings & DataStream::SCRIPT_STREAM)
+        m_pRBScriptData->Check();
+    if (!(nSettings & DataStream::VALUES_IN_LINE))
+        m_pRBAddressValue->Check();
+    m_pEdRange->SetText(rRange);
+    if (rMove == "NO_MOVE")
+        m_pRBNoMove->Check();
+    else if (rMove == "RANGE_DOWN")
+        m_pRBRangeDown->Check();
+    else if (rMove == "MOVE_DOWN")
+        m_pRBDataDown->Check();
+    UpdateEnable();
+}
+
+void DataStreamDlg::StartStream(DataStream *pStream)
 {
     sal_Int32 nLimit = 0;
     if (m_pRBMaxLimit->IsChecked())
@@ -89,7 +110,15 @@ void DataStreamDlg::StartStream()
        nSettings |= DataStream::SCRIPT_STREAM;
     if (m_pRBValuesInLine->IsChecked())
        nSettings |= DataStream::VALUES_IN_LINE;
-    DataStream *pStream = DataStream::Set( mpDocShell,
+    if (pStream)
+    {
+        pStream->Decode(rURL, m_pEdRange->GetText(), nLimit,
+                m_pRBNoMove->IsChecked() ? OUString("NO_MOVE") : m_pRBRangeDown->IsChecked()
+                    ? OUString("RANGE_DOWN") : OUString("MOVE_DOWN"),
+                nSettings);
+        return;
+    }
+    pStream = DataStream::Set( mpDocShell,
             rURL,
             m_pEdRange->GetText(),
             nLimit,
commit c006965bdb4b56924eba3c52b53fe294bf460c60
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Fri Nov 22 16:14:11 2013 +0100

    export data streams; pretend to be an area link
    
    Fix ScXMLExport::GetAreaLinks to not use UNO, so we can hack DataStreams
    into ScMyAreaLinksContainer.
    We need to connect them to cells for export / import - that does not make
    sense for DataStream without any attached range. We use an arbitrary one.
    But you might remove it, if you create another ScAreaLink / DataStream
    with the same range, without knowing about it.
    
    Maybe it wouldn't be that bad to let DataStream inherit from ScAreaLink.
    
    Change-Id: I5b85a9329ba1ca46fb2893b54fe5161d2fb22f47

diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 5ed08df..8fbeb8a 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -60,6 +60,8 @@
 #include "stylehelper.hxx"
 #include "edittextiterator.hxx"
 #include "editattributemap.hxx"
+#include <arealink.hxx>
+#include <datastream.hxx>
 
 #include <xmloff/xmltoken.hxx>
 #include <xmloff/xmlnmspe.hxx>
@@ -147,6 +149,7 @@
 
 #include "XMLCodeNameProvider.hxx"
 
+#include <sfx2/linkmgr.hxx>
 #include <sfx2/objsh.hxx>
 
 #include <vector>
@@ -814,37 +817,35 @@ table::CellRangeAddress ScXMLExport::GetEndAddress(const uno::Reference<sheet::X
     return aCellAddress;
 }
 
-void ScXMLExport::GetAreaLinks( uno::Reference< sheet::XSpreadsheetDocument>& xSpreadDoc,
-                                ScMyAreaLinksContainer& rAreaLinks )
+void ScXMLExport::GetAreaLinks( ScMyAreaLinksContainer& rAreaLinks )
 {
-    uno::Reference< beans::XPropertySet > xPropSet( xSpreadDoc, uno::UNO_QUERY );
-    if( !xPropSet.is() ) return;
-
-    uno::Reference< container::XIndexAccess > xLinksIAccess( xPropSet->getPropertyValue( OUString( SC_UNO_AREALINKS ) ), uno::UNO_QUERY);
-    if( xLinksIAccess.is() )
+    if (pDoc->GetLinkManager())
     {
-        const OUString sFilter( SC_UNONAME_FILTER );
-        const OUString sFilterOpt( SC_UNONAME_FILTOPT );
-        const OUString sURL( SC_UNONAME_LINKURL );
-        const OUString sRefresh( SC_UNONAME_REFDELAY );
-
-        sal_Int32 nCount(xLinksIAccess->getCount());
-        for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
+        const sfx2::SvBaseLinks& rLinks = pDoc->GetLinkManager()->GetLinks();
+        for (size_t i = 0; i < rLinks.size(); i++)
         {
-            uno::Reference< sheet::XAreaLink > xAreaLink(xLinksIAccess->getByIndex( nIndex ), uno::UNO_QUERY);
-            if( xAreaLink.is() )
+            ScAreaLink *pLink = dynamic_cast<ScAreaLink*>(&(*(*rLinks[i])));
+            if (pLink)
             {
                 ScMyAreaLink aAreaLink;
-                aAreaLink.aDestRange = xAreaLink->getDestArea();
-                aAreaLink.sSourceStr = xAreaLink->getSourceArea();
-                uno::Reference< beans::XPropertySet > xLinkProp( xAreaLink, uno::UNO_QUERY );
-                if( xLinkProp.is() )
-                {
-                    xLinkProp->getPropertyValue( sFilter ) >>= aAreaLink.sFilter;
-                    xLinkProp->getPropertyValue( sFilterOpt ) >>= aAreaLink.sFilterOptions;
-                    xLinkProp->getPropertyValue( sURL ) >>= aAreaLink.sURL;
-                    xLinkProp->getPropertyValue( sRefresh ) >>= aAreaLink.nRefresh;
-                }
+                ScUnoConversion::FillApiRange( aAreaLink.aDestRange, pLink->GetDestArea() );
+                aAreaLink.sSourceStr = pLink->GetSource();
+                aAreaLink.sFilter = pLink->GetFilter();
+                aAreaLink.sFilterOptions = pLink->GetOptions();
+                aAreaLink.sURL = pLink->GetFile();
+                aAreaLink.nRefresh = pLink->GetTimeout();
+                rAreaLinks.AddNewAreaLink( aAreaLink );
+            }
+            DataStream *pStream = dynamic_cast<DataStream*>(&(*(*rLinks[i])));
+            if (pStream)
+            {
+                ScMyAreaLink aAreaLink;
+                ScUnoConversion::FillApiRange( aAreaLink.aDestRange, pStream->GetRange() );
+                aAreaLink.sSourceStr = pStream->GetMove();
+                aAreaLink.sFilter = OUString::number(pStream->GetLimit());
+                aAreaLink.sFilterOptions = "DataStream";
+                aAreaLink.sURL = pStream->GetURL();
+                aAreaLink.nRefresh = pStream->GetSettings();
                 rAreaLinks.AddNewAreaLink( aAreaLink );
             }
         }
@@ -1904,7 +1905,7 @@ void ScXMLExport::_ExportContent()
         WriteCalculationSettings(xSpreadDoc);
         sal_Int32 nTableCount(xIndex->getCount());
         ScMyAreaLinksContainer aAreaLinks;
-        GetAreaLinks( xSpreadDoc, aAreaLinks );
+        GetAreaLinks( aAreaLinks );
         ScMyEmptyDatabaseRangesContainer aEmptyRanges(aExportDatabaseRanges.GetEmptyDatabaseRanges());
         ScMyDetectiveOpContainer aDetectiveOpContainer;
         GetDetectiveOpList( aDetectiveOpContainer );
diff --git a/sc/source/filter/xml/xmlexprt.hxx b/sc/source/filter/xml/xmlexprt.hxx
index cc649bd..4ece1d5 100644
--- a/sc/source/filter/xml/xmlexprt.hxx
+++ b/sc/source/filter/xml/xmlexprt.hxx
@@ -144,7 +144,7 @@ class ScXMLExport : public SvXMLExport
     com::sun::star::table::CellRangeAddress GetEndAddress(const com::sun::star::uno::Reference<com::sun::star::sheet::XSpreadsheet>& xTable,
                                                         const sal_Int32 nTable);
 //  ScMyEmptyDatabaseRangesContainer GetEmptyDatabaseRanges();
-    void GetAreaLinks( com::sun::star::uno::Reference< com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc, ScMyAreaLinksContainer& rAreaLinks );
+    void GetAreaLinks( ScMyAreaLinksContainer& rAreaLinks );
     void GetDetectiveOpList( ScMyDetectiveOpContainer& rDetOp );
     void WriteSingleColumn(const sal_Int32 nRepeatColumns, const sal_Int32 nStyleIndex,
         const sal_Int32 nIndex, const bool bIsAutoStyle, const bool bIsVisible);
diff --git a/sc/source/ui/docshell/datastream.cxx b/sc/source/ui/docshell/datastream.cxx
index a57512c..aef6c3b 100644
--- a/sc/source/ui/docshell/datastream.cxx
+++ b/sc/source/ui/docshell/datastream.cxx
@@ -16,6 +16,7 @@
 #include <salhelper/thread.hxx>
 #include <sfx2/linkmgr.hxx>
 #include <sfx2/viewfrm.hxx>
+#include <arealink.hxx>
 #include <asciiopt.hxx>
 #include <dbfunc.hxx>
 #include <docsh.hxx>
@@ -166,9 +167,44 @@ void DataStream::MakeToolbarVisible(ScDocShell *pShell)
 DataStream* DataStream::Set(ScDocShell *pShell, const OUString& rURL, const OUString& rRange,
         sal_Int32 nLimit, const OUString& rMove, sal_uInt32 nSettings)
 {
+    // Each DataStream needs a destination area in order to be exported.
+    // There can be only one ScAreaLink / DataStream per cell.
+    // So - if we don't need range (DataStream with mbValuesInLine == false),
+    // just find a free cell for now.
+    sfx2::LinkManager* pLinkManager = pShell->GetDocument()->GetLinkManager();
+    ScRange aDestArea;
+    aDestArea.Parse(rRange, pShell->GetDocument());
+    sal_uInt16 nLinkPos = 0;
+    while (nLinkPos < pLinkManager->GetLinks().size())
+    {
+        sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[nLinkPos];
+        if (rRange.isEmpty())
+        {
+            if ( (pBase->ISA(ScAreaLink) && dynamic_cast<ScAreaLink*>
+                        (&(*pBase))->GetDestArea().aStart == aDestArea.aStart)
+                || (pBase->ISA(DataStream) && dynamic_cast<DataStream*>
+                        (&(*pBase))->GetRange().aStart == aDestArea.aStart) )
+            {
+                aDestArea.Move(0, 1, 0);
+                nLinkPos = 0;
+                continue;
+            }
+            else
+                ++nLinkPos;
+        }
+        else if ( (pBase->ISA(ScAreaLink) && dynamic_cast<ScAreaLink*>
+                    (&(*pBase))->GetDestArea().aStart == aDestArea.aStart)
+                || (pBase->ISA(DataStream) && dynamic_cast<DataStream*>
+                    (&(*pBase))->GetRange().aStart == aDestArea.aStart) )
+        {
+            pLinkManager->Remove( pBase );
+        }
+        else
+            ++nLinkPos;
+    }
+
     sfx2::SvBaseLink *pLink = 0;
     pLink = new DataStream( pShell, rURL, rRange, nLimit, rMove, nSettings );
-    sfx2::LinkManager* pLinkManager = pShell->GetDocument()->GetLinkManager();
     pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, rURL, NULL, NULL );
     return dynamic_cast<DataStream*>(pLink);
 }
@@ -181,20 +217,19 @@ DataStream::DataStream(ScDocShell *pShell, const OUString& rURL, const OUString&
     , mbRunning(false)
     , mpLines(0)
     , mnLinesCount(0)
-    , mpRange(new ScRange())
     , mpEndRange(NULL)
 {
     mxThread = new datastreams::CallerThread( this );
     mxThread->launch();
 
-    Decode(rURL, rRange, rMove, nSettings);
+    Decode(rURL, rRange, nLimit, rMove, nSettings);
 
-    mpStartRange.reset( new ScRange(*mpRange.get()) );
-    sal_Int32 nHeight = mpRange->aEnd.Row() - mpRange->aStart.Row() + 1;
+    maStartRange = maRange;
+    sal_Int32 nHeight = maRange.aEnd.Row() - maRange.aStart.Row() + 1;
     nLimit = nHeight * (nLimit / nHeight);
-    if (nLimit && mpRange->aStart.Row() + nLimit - 1 < MAXROW)
+    if (nLimit && maRange.aStart.Row() + nLimit - 1 < MAXROW)
     {
-        mpEndRange.reset( new ScRange(*mpRange) );
+        mpEndRange.reset( new ScRange(maRange) );
         mpEndRange->Move(0, nLimit - nHeight, 0);
     }
 }
@@ -235,28 +270,32 @@ OString DataStream::ConsumeLine()
     return mpLines->at(mnLinesCount++);
 }
 
-void DataStream::Decode( const OUString& rURL, const OUString& rRange,
-        const OUString& rMove, sal_uInt32 nSettings)
+void DataStream::Decode(const OUString& rURL, const OUString& rRange,
+        const sal_Int32 nLimit, const OUString& rMove, const sal_uInt32 nSettings)
 {
+    msURL = rURL;
+    msRange = rRange;
+    mnLimit = nLimit;
+    msMove = rMove;
+    mnSettings = nSettings;
+    maRange.Parse(msRange);
     SvStream *pStream = 0;
-    if (nSettings & SCRIPT_STREAM)
-        pStream = new SvScriptStream(rURL);
+    if (mnSettings & SCRIPT_STREAM)
+        pStream = new SvScriptStream(msURL);
     else
-        pStream = new SvFileStream(rURL, STREAM_READ);
+        pStream = new SvFileStream(msURL, STREAM_READ);
     mxReaderThread = new datastreams::ReaderThread( pStream );
     mxReaderThread->launch();
 
-    mbValuesInLine = nSettings & VALUES_IN_LINE;
+    mbValuesInLine = mnSettings & VALUES_IN_LINE;
     if (!mbValuesInLine)
         return;
 
-    mpRange->Parse(rRange, mpScDocument);
-    
-    if (rMove == "NO_MOVE")
+    if (msMove == "NO_MOVE")
         meMove = NO_MOVE;
-    else if (rMove == "RANGE_DOWN")
+    else if (msMove == "RANGE_DOWN")
         meMove = RANGE_DOWN;
-    else if (rMove == "MOVE_DOWN")
+    else if (msMove == "MOVE_DOWN")
         meMove = MOVE_DOWN;
 }
 
@@ -283,17 +322,17 @@ void DataStream::MoveData()
     switch (meMove)
     {
         case RANGE_DOWN:
-            if (mpRange->aStart == mpEndRange->aStart)
+            if (maRange.aStart == mpEndRange->aStart)
                 meMove = MOVE_UP;
             break;
         case MOVE_UP:
-            mpScDocument->DeleteRow(*mpStartRange);
+            mpScDocument->DeleteRow(maStartRange);
             mpScDocument->InsertRow(*mpEndRange);
             break;
         case MOVE_DOWN:
             if (mpEndRange.get())
                 mpScDocument->DeleteRow(*mpEndRange);
-            mpScDocument->InsertRow(*mpRange);
+            mpScDocument->InsertRow(maRange);
             break;
         case NO_MOVE:
             break;
@@ -306,7 +345,7 @@ bool DataStream::ImportData()
     MoveData();
     if (mbValuesInLine)
     {
-        SCROW nHeight = mpRange->aEnd.Row() - mpRange->aStart.Row() + 1;
+        SCROW nHeight = maRange.aEnd.Row() - maRange.aStart.Row() + 1;
         OStringBuffer aBuf;
         while (nHeight--)
         {
@@ -314,7 +353,7 @@ bool DataStream::ImportData()
             aBuf.append('\n');
         }
         SvMemoryStream aMemoryStream((void *)aBuf.getStr(), aBuf.getLength(), STREAM_READ);
-        ScImportExport aImport(mpScDocument, *mpRange);
+        ScImportExport aImport(mpScDocument, maRange);
         aImport.SetSeparator(',');
         aImport.ImportStream(aMemoryStream, OUString(), FORMAT_STRING);
     }
@@ -352,13 +391,13 @@ bool DataStream::ImportData()
 
     if (meMove == RANGE_DOWN)
     {
-        mpRange->Move(0, mpRange->aEnd.Row() - mpRange->aStart.Row() + 1, 0);
+        maRange.Move(0, maRange.aEnd.Row() - maRange.aStart.Row() + 1, 0);
         mpScDocShell->GetViewData()->GetView()->AlignToCursor(
-                mpRange->aStart.Col(), mpRange->aStart.Row(), SC_FOLLOW_JUMP);
+                maRange.aStart.Col(), maRange.aStart.Row(), SC_FOLLOW_JUMP);
     }
     SCROW aEndRow = mpEndRange.get() ? mpEndRange->aEnd.Row() : MAXROW;
-    mpScDocShell->PostPaint( ScRange( mpStartRange->aStart, ScAddress( mpRange->aEnd.Col(),
-                    aEndRow, mpRange->aStart.Tab()) ), PAINT_GRID );
+    mpScDocShell->PostPaint( ScRange( maStartRange.aStart, ScAddress( maRange.aEnd.Col(),
+                    aEndRow, maRange.aStart.Tab()) ), PAINT_GRID );
 
     return mbRunning;
 }
diff --git a/sc/source/ui/inc/datastream.hxx b/sc/source/ui/inc/datastream.hxx
index 00c000f..b60a988 100644
--- a/sc/source/ui/inc/datastream.hxx
+++ b/sc/source/ui/inc/datastream.hxx
@@ -12,6 +12,7 @@
 #include <rtl/ref.hxx>
 #include <rtl/ustring.hxx>
 #include <sfx2/lnkbase.hxx>
+#include <address.hxx>
 
 #include <boost/noncopyable.hpp>
 #include <boost/scoped_ptr.hpp>
@@ -23,7 +24,6 @@ namespace datastreams {
 }
 class ScDocShell;
 class ScDocument;
-class ScRange;
 class Window;
 
 typedef std::vector<OString> LinesList;
@@ -31,7 +31,8 @@ typedef std::vector<OString> LinesList;
 class DataStream : boost::noncopyable, public sfx2::SvBaseLink
 {
     OString ConsumeLine();
-    void Decode(const OUString& rURL, const OUString& rRange, const OUString& rMove, sal_uInt32 nSettings);
+    void Decode(const OUString& rURL, const OUString& rRange, const sal_Int32 nLimit,
+            const OUString& rMove, const sal_uInt32 nSettings);
     void MoveData();
 
 public:
@@ -49,6 +50,11 @@ public:
             const OUString& , const css::uno::Any& ) SAL_OVERRIDE;
     virtual void Edit(Window* , const Link& ) SAL_OVERRIDE;
 
+    const ScRange& GetRange() const { return maRange; }
+    const OUString& GetURL() const { return msURL; }
+    const sal_Int32& GetLimit() const { return mnLimit; }
+    const OUString& GetMove() const { return msMove; }
+    const sal_uInt32& GetSettings() const { return mnSettings; }
     bool ImportData();
     void Start();
     void Stop();
@@ -56,14 +62,19 @@ public:
 private:
     ScDocShell *mpScDocShell;
     ScDocument *mpScDocument;
+    OUString msURL;
+    OUString msRange;
+    OUString msMove;
+    sal_Int32 mnLimit;
+    sal_uInt32 mnSettings;
     MoveEnum meMove;
     bool mbRunning;
     bool mbIsUndoEnabled;
     bool mbValuesInLine;
     LinesList *mpLines;
     size_t mnLinesCount;
-    boost::scoped_ptr<ScRange> mpRange;
-    boost::scoped_ptr<ScRange> mpStartRange;
+    ScRange maRange;
+    ScRange maStartRange;
     boost::scoped_ptr<ScRange> mpEndRange;
     rtl::Reference<datastreams::CallerThread> mxThread;
     rtl::Reference<datastreams::ReaderThread> mxReaderThread;
diff --git a/sc/source/ui/miscdlgs/datastreamdlg.cxx b/sc/source/ui/miscdlgs/datastreamdlg.cxx
index 92b3290..b266687 100644
--- a/sc/source/ui/miscdlgs/datastreamdlg.cxx
+++ b/sc/source/ui/miscdlgs/datastreamdlg.cxx
@@ -66,6 +66,7 @@ void DataStreamDlg::UpdateEnable()
         m_pVclFrameLimit->Hide();
         m_pVclFrameMove->Hide();
         m_pVclFrameRange->Hide();
+        m_pEdRange->SetText("");
     }
     else
     {
commit 792e43dedb0266bc24ec84cfb35ad723e7ab1d5b
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Thu Nov 21 21:20:17 2013 +0100

    Import data streams - reuse infrastructure for ScAreaLink.
    
    Change-Id: I18db991d2e8e665d5e4ca778344993e79772ccd5

diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index 47ad103..09bef92 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -86,6 +86,7 @@
 #include "columniterator.hxx"
 #include "globalnames.hxx"
 #include "stringutil.hxx"
+#include <datastream.hxx>
 
 #include <memory>
 #include <boost/scoped_ptr.hpp>
@@ -1193,7 +1194,7 @@ bool ScDocument::HasAreaLinks() const
         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
         sal_uInt16 nCount = rLinks.size();
         for (sal_uInt16 i=0; i<nCount; i++)
-            if ((*rLinks[i])->ISA(ScAreaLink))
+            if ((*rLinks[i])->ISA(ScAreaLink) || (*rLinks[i])->ISA(DataStream))
                 return true;
     }
 
@@ -1208,7 +1209,7 @@ void ScDocument::UpdateAreaLinks()
         for (sal_uInt16 i=0; i<rLinks.size(); i++)
         {
             ::sfx2::SvBaseLink* pBase = *rLinks[i];
-            if (pBase->ISA(ScAreaLink))
+            if (pBase->ISA(ScAreaLink) || (*rLinks[i])->ISA(DataStream))
                 pBase->Update();
         }
     }
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index e9f7d5b..5ca7129 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -52,6 +52,8 @@
 #include "tokenarray.hxx"
 #include "scmatrix.hxx"
 #include "documentimport.hxx"
+#include <datastream.hxx>
+#include <rangeutl.hxx>
 
 #include <xmloff/xmltkmap.hxx>
 #include <xmloff/xmltoken.hxx>
@@ -997,6 +999,19 @@ void ScXMLTableRowCellContext::SetCellRangeSource( const ScAddress& rPosition )
                 rPosition.Row() + static_cast<SCROW>(pCellRangeSource->nRows - 1), rPosition.Tab() );
             OUString sFilterName( pCellRangeSource->sFilterName );
             OUString sSourceStr( pCellRangeSource->sSourceStr );
+            OUString sRangeStr;
+            ScRangeStringConverter::GetStringFromRange( sRangeStr, aDestRange, pDoc, formula::FormulaGrammar::CONV_OOO );
+            if (pCellRangeSource->sFilterOptions == "DataStream")
+            {
+                DataStream::Set( dynamic_cast<ScDocShell*>(pDoc->GetDocumentShell())
+                        , pCellRangeSource->sURL // rURL
+                        , sRangeStr // rRange
+                        , sFilterName.toInt32() // nLimit
+                        , sSourceStr // rMove
+                        , pCellRangeSource->nRefresh // nSettings
+                        );
+                return;
+            }
             ScAreaLink* pLink = new ScAreaLink( pDoc->GetDocumentShell(), pCellRangeSource->sURL,
                 sFilterName, pCellRangeSource->sFilterOptions, sSourceStr, aDestRange, pCellRangeSource->nRefresh );
             sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
diff --git a/sc/source/ui/docshell/datastream.cxx b/sc/source/ui/docshell/datastream.cxx
index d58c72c..a57512c 100644
--- a/sc/source/ui/docshell/datastream.cxx
+++ b/sc/source/ui/docshell/datastream.cxx
@@ -138,10 +138,10 @@ private:
 
 }
 
-static void lcl_MakeToolbarVisible(SfxViewFrame *pViewFrame)
+void DataStream::MakeToolbarVisible(ScDocShell *pShell)
 {
     css::uno::Reference< css::frame::XFrame > xFrame =
-        pViewFrame->GetFrame().GetFrameInterface();
+        pShell->GetViewData()->GetViewShell()->GetViewFrame()->GetFrame().GetFrameInterface();
     if (!xFrame.is())
         return;
 
@@ -163,18 +163,18 @@ static void lcl_MakeToolbarVisible(SfxViewFrame *pViewFrame)
     }
 }
 
-void DataStream::Set(ScDocShell *pShell, const OUString& rURL, const OUString& rRange, sal_Int32 nLimit, const OUString& rMove)
+DataStream* DataStream::Set(ScDocShell *pShell, const OUString& rURL, const OUString& rRange,
+        sal_Int32 nLimit, const OUString& rMove, sal_uInt32 nSettings)
 {
     sfx2::SvBaseLink *pLink = 0;
-    pLink = new DataStream( pShell, rURL, rRange, nLimit, rMove );
+    pLink = new DataStream( pShell, rURL, rRange, nLimit, rMove, nSettings );
     sfx2::LinkManager* pLinkManager = pShell->GetDocument()->GetLinkManager();
     pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, rURL, NULL, NULL );
-
-    lcl_MakeToolbarVisible(pShell->GetViewData()->GetViewShell()->GetViewFrame());
+    return dynamic_cast<DataStream*>(pLink);
 }
 
-DataStream::DataStream(ScDocShell *pShell, const OUString& rURL,
-        const OUString& rRange, sal_Int32 nLimit, const OUString& rMove)
+DataStream::DataStream(ScDocShell *pShell, const OUString& rURL, const OUString& rRange,
+        sal_Int32 nLimit, const OUString& rMove, sal_uInt32 nSettings)
     : mpScDocShell(pShell)
     , mpScDocument(mpScDocShell->GetDocument())
     , meMove(NO_MOVE)
@@ -187,7 +187,7 @@ DataStream::DataStream(ScDocShell *pShell, const OUString& rURL,
     mxThread = new datastreams::CallerThread( this );
     mxThread->launch();
 
-    Decode(rURL, rRange, rMove);
+    Decode(rURL, rRange, rMove, nSettings);
 
     mpStartRange.reset( new ScRange(*mpRange.get()) );
     sal_Int32 nHeight = mpRange->aEnd.Row() - mpRange->aStart.Row() + 1;
@@ -215,6 +215,8 @@ OString DataStream::ConsumeLine()
     if (!mpLines || mnLinesCount >= mpLines->size())
     {
         mnLinesCount = 0;
+        if (mxReaderThread->mbTerminateReading)
+            return OString();
         osl::ResettableMutexGuard aGuard(mxReaderThread->maLinesProtector);
         if (mpLines)
             mxReaderThread->maUsedLines.push(mpLines);
@@ -233,18 +235,18 @@ OString DataStream::ConsumeLine()
     return mpLines->at(mnLinesCount++);
 }
 
-void DataStream::Decode( const OUString& rURL, const OUString& rRange, const OUString& rMove)
+void DataStream::Decode( const OUString& rURL, const OUString& rRange,
+        const OUString& rMove, sal_uInt32 nSettings)
 {
-    sal_Int32 nIndex = rURL.indexOf(sfx2::cTokenSeparator);
     SvStream *pStream = 0;
-    if (nIndex != -1)
-        pStream = new SvScriptStream(rURL.copy(0, nIndex));
+    if (nSettings & SCRIPT_STREAM)
+        pStream = new SvScriptStream(rURL);
     else
         pStream = new SvFileStream(rURL, STREAM_READ);
     mxReaderThread = new datastreams::ReaderThread( pStream );
     mxReaderThread->launch();
 
-    mbValuesInLine = !rRange.isEmpty();
+    mbValuesInLine = nSettings & VALUES_IN_LINE;
     if (!mbValuesInLine)
         return;
 
@@ -361,6 +363,14 @@ bool DataStream::ImportData()
     return mbRunning;
 }
 
+sfx2::SvBaseLink::UpdateResult DataStream::DataChanged(
+        const OUString& , const css::uno::Any& )
+{
+    MakeToolbarVisible(mpScDocShell);
+    Start();
+    return SUCCESS;
+}
+
 void DataStream::Edit(Window* , const Link& )
 {
 }
diff --git a/sc/source/ui/inc/datastream.hxx b/sc/source/ui/inc/datastream.hxx
index 6da62c9..00c000f 100644
--- a/sc/source/ui/inc/datastream.hxx
+++ b/sc/source/ui/inc/datastream.hxx
@@ -31,18 +31,22 @@ typedef std::vector<OString> LinesList;
 class DataStream : boost::noncopyable, public sfx2::SvBaseLink
 {
     OString ConsumeLine();
-    void Decode(const OUString& rURL, const OUString& rRange, const OUString& rMove);
+    void Decode(const OUString& rURL, const OUString& rRange, const OUString& rMove, sal_uInt32 nSettings);
     void MoveData();
 
 public:
     enum MoveEnum { NO_MOVE, RANGE_DOWN, MOVE_DOWN, MOVE_UP };
+    enum { SCRIPT_STREAM = 1, VALUES_IN_LINE = 2 };
 
-    static void Set(ScDocShell *pShell, const OUString& rURL,
-            const OUString& rRange, sal_Int32 nLimit, const OUString& rMove);
+    static void MakeToolbarVisible(ScDocShell *pShell);
+    static DataStream* Set(ScDocShell *pShell, const OUString& rURL, const OUString& rRange,
+            sal_Int32 nLimit, const OUString& rMove, sal_uInt32 nSettings);
 
-    DataStream(ScDocShell *pShell, const OUString& rURL,
-        const OUString& rRange, sal_Int32 nLimit, const OUString& rMove);
+    DataStream(ScDocShell *pShell, const OUString& rURL, const OUString& rRange,
+            sal_Int32 nLimit, const OUString& rMove, sal_uInt32 nSettings);
     virtual ~DataStream() SAL_OVERRIDE;
+    virtual sfx2::SvBaseLink::UpdateResult DataChanged(
+            const OUString& , const css::uno::Any& ) SAL_OVERRIDE;
     virtual void Edit(Window* , const Link& ) SAL_OVERRIDE;
 
     bool ImportData();
diff --git a/sc/source/ui/miscdlgs/datastreamdlg.cxx b/sc/source/ui/miscdlgs/datastreamdlg.cxx
index cd2d2c4..92b3290 100644
--- a/sc/source/ui/miscdlgs/datastreamdlg.cxx
+++ b/sc/source/ui/miscdlgs/datastreamdlg.cxx
@@ -10,7 +10,6 @@
 #include <datastreamdlg.hxx>
 
 #include <sfx2/filedlghelper.hxx>
-#include <sfx2/linkmgr.hxx>
 #include <svtools/inettbc.hxx>
 #include <vcl/layout.hxx>
 #include <datastream.hxx>
@@ -84,15 +83,21 @@ void DataStreamDlg::StartStream()
     if (m_pRBMaxLimit->IsChecked())
         nLimit = m_pEdLimit->GetText().toInt32();
     OUString rURL = m_pCbUrl->GetText();
+    sal_uInt32 nSettings = 0;
     if (m_pRBScriptData->IsChecked())
-       rURL += OUString(sfx2::cTokenSeparator);
-    DataStream::Set( mpDocShell,
+       nSettings |= DataStream::SCRIPT_STREAM;
+    if (m_pRBValuesInLine->IsChecked())
+       nSettings |= DataStream::VALUES_IN_LINE;
+    DataStream *pStream = DataStream::Set( mpDocShell,
             rURL,
             m_pEdRange->GetText(),
             nLimit,
             m_pRBNoMove->IsChecked() ? OUString("NO_MOVE") : m_pRBRangeDown->IsChecked()
                 ? OUString("RANGE_DOWN") : OUString("MOVE_DOWN")
+            , nSettings
             );
+    DataStream::MakeToolbarVisible( mpDocShell );
+    pStream->Start();
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list