Rebased ref, commits from common ancestor: commit f0f384b9f721d793dc5877e0a8596d47280ba34e Author: Matúš Kukan <matus.ku...@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.ku...@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.ku...@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.ku...@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.ku...@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: */
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits