diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2018-07-09 19:49:34 +1000 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2018-07-10 18:38:40 +0200 |
commit | edc62adae9a354ca1305e83b10c98a545f58d341 (patch) | |
tree | 5bdbcf8901df3e18183fcffc8c4ac6c9c6ae610a | |
parent | d7cdb7fcc48a580cd5183ba899f73f2ad9bdbec9 (diff) |
tdf#118634: Don't save embedded data source to a temporary preview document
Also don't use storeAsURL to store embedded datasource when the document
is being saved using storeToURL.
Change-Id: I69a7ee5ae066e591be5e45c87bcf57dff370decc
Reviewed-on: https://gerrit.libreoffice.org/57178
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r-- | dbaccess/source/core/dataaccess/databasedocument.cxx | 34 | ||||
-rw-r--r-- | dbaccess/source/core/dataaccess/databasedocument.hxx | 13 | ||||
-rw-r--r-- | include/sfx2/objsh.hxx | 3 | ||||
-rw-r--r-- | include/sfx2/sfxsids.hrc | 7 | ||||
-rw-r--r-- | include/svl/itemset.hxx | 6 | ||||
-rw-r--r-- | sfx2/source/appl/appuno.cxx | 1 | ||||
-rw-r--r-- | sfx2/source/doc/objstor.cxx | 19 | ||||
-rw-r--r-- | sw/inc/dbmgr.hxx | 2 | ||||
-rw-r--r-- | sw/source/ui/dbui/mmlayoutpage.cxx | 5 | ||||
-rw-r--r-- | sw/source/uibase/app/docsh.cxx | 25 | ||||
-rw-r--r-- | sw/source/uibase/dbui/dbmgr.cxx | 7 |
11 files changed, 98 insertions, 24 deletions
diff --git a/dbaccess/source/core/dataaccess/databasedocument.cxx b/dbaccess/source/core/dataaccess/databasedocument.cxx index 516766ca81e3..44e43b9b2435 100644 --- a/dbaccess/source/core/dataaccess/databasedocument.cxx +++ b/dbaccess/source/core/dataaccess/databasedocument.cxx @@ -1029,15 +1029,8 @@ void ODatabaseDocument::impl_storeAs_throw( const OUString& _rURL, const ::comph if ( bLocationChanged ) { // create storage for target URL - uno::Reference<embed::XStorage> xTargetStorage; - _rArguments.get("TargetStorage") >>= xTargetStorage; - if (!xTargetStorage.is()) - xTargetStorage = impl_createStorageFor_throw(_rURL); - - // In case we got a StreamRelPath, then xTargetStorage should reference that sub-storage. - OUString sStreamRelPath = _rArguments.getOrDefault("StreamRelPath", OUString()); - if (!sStreamRelPath.isEmpty()) - xTargetStorage = xTargetStorage->openStorageElement(sStreamRelPath, embed::ElementModes::READWRITE); + uno::Reference<embed::XStorage> xTargetStorage( + impl_GetStorageOrCreateFor_throw(_rArguments, _rURL)); if ( m_pImpl->isEmbeddedDatabase() ) m_pImpl->clearConnections(); @@ -1130,6 +1123,24 @@ Reference< XStorage > ODatabaseDocument::impl_createStorageFor_throw( const OUSt return Reference< XStorage >( xStorageFactory->createInstanceWithArguments( aParam ), UNO_QUERY_THROW ); } +css::uno::Reference<css::embed::XStorage> ODatabaseDocument::impl_GetStorageOrCreateFor_throw( + const ::comphelper::NamedValueCollection& _rArguments, const OUString& _rURL) const +{ + // Try to get the storage from arguments, then create storage for target URL + uno::Reference<embed::XStorage> xTargetStorage; + _rArguments.get("TargetStorage") >>= xTargetStorage; + if (!xTargetStorage.is()) + xTargetStorage = impl_createStorageFor_throw(_rURL); + + // In case we got a StreamRelPath, then xTargetStorage should reference that sub-storage. + OUString sStreamRelPath = _rArguments.getOrDefault("StreamRelPath", OUString()); + if (!sStreamRelPath.isEmpty()) + xTargetStorage + = xTargetStorage->openStorageElement(sStreamRelPath, embed::ElementModes::READWRITE); + + return xTargetStorage; +} + void SAL_CALL ODatabaseDocument::storeAsURL( const OUString& _rURL, const Sequence< PropertyValue >& _rArguments ) { // SYNCHRONIZED -> @@ -1232,11 +1243,12 @@ void SAL_CALL ODatabaseDocument::storeToURL( const OUString& _rURL, const Sequen try { + const ::comphelper::NamedValueCollection aArguments(_rArguments); // create storage for target URL - Reference< XStorage > xTargetStorage( impl_createStorageFor_throw( _rURL ) ); + Reference<XStorage> xTargetStorage(impl_GetStorageOrCreateFor_throw(aArguments, _rURL)); // extend media descriptor with URL - Sequence< PropertyValue > aMediaDescriptor( lcl_appendFileNameToDescriptor( _rArguments, _rURL ) ); + Sequence<PropertyValue> aMediaDescriptor(lcl_appendFileNameToDescriptor(aArguments, _rURL)); // store to this storage impl_storeToStorage_throw( xTargetStorage, aMediaDescriptor, aGuard ); diff --git a/dbaccess/source/core/dataaccess/databasedocument.hxx b/dbaccess/source/core/dataaccess/databasedocument.hxx index 9479511367ce..e910bff75d3e 100644 --- a/dbaccess/source/core/dataaccess/databasedocument.hxx +++ b/dbaccess/source/core/dataaccess/databasedocument.hxx @@ -546,6 +546,19 @@ private: const OUString& _rURL ) const; + /** Extracts storage from arguments, or creates for the given URL, truncating it if a file with + this name already exists + + @throws Exception + if creating the storage failed + + @return + the storage that is either extracted from arguments, or newly created for the file at + the given URL + */ + css::uno::Reference<css::embed::XStorage> impl_GetStorageOrCreateFor_throw( + const ::comphelper::NamedValueCollection& _rArguments, const OUString& _rURL) const; + /** sets our "modified" flag will notify all our respective listeners, if the "modified" state actually changed diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx index b5e5fb0b498d..a6bff464d369 100644 --- a/include/sfx2/objsh.hxx +++ b/include/sfx2/objsh.hxx @@ -584,7 +584,8 @@ public: static bool CopyStoragesOfUnknownMediaType( const css::uno::Reference< css::embed::XStorage >& xSource, - const css::uno::Reference< css::embed::XStorage >& xTarget ); + const css::uno::Reference<css::embed::XStorage>& xTarget, + const css::uno::Sequence<OUString>& rExceptions = css::uno::Sequence<OUString>()); // The functions from SvPersist void EnableSetModified( bool bEnable = true ); diff --git a/include/sfx2/sfxsids.hrc b/include/sfx2/sfxsids.hrc index 49bfb72846f2..bbf108841bd1 100644 --- a/include/sfx2/sfxsids.hrc +++ b/include/sfx2/sfxsids.hrc @@ -174,7 +174,7 @@ class SfxDocumentInfoItem; #define SID_CONTENTTYPE (SID_SFX_START + 1541) -#define SID_SAVETO (SID_SFX_START + 1546) +#define SID_SAVETO TypedWhichId<SfxBoolItem>(SID_SFX_START + 1546) #define SID_VERSION (SID_SFX_START + 1583) @@ -251,8 +251,11 @@ class SfxDocumentInfoItem; #define SID_TOOLBAR_MODE (SID_SFX_START + 1728) #define SID_NO_FILE_SYNC (SID_SFX_START + 1729) #define SID_NO_THUMBNAIL (SID_SFX_START + 1730) +// Used to export a temporary file for preview in Mail Merge Wizard, where saving the data source is +// not required for preview, but interferes with not-yet-saved embedded data source for main document. +#define SID_NO_EMBEDDED_DS TypedWhichId<SfxBoolItem>(SID_SFX_START + 1731) -// SID_SFX_free_START (SID_SFX_START + 1731) +// SID_SFX_free_START (SID_SFX_START + 1732) // SID_SFX_free_END (SID_SFX_START + 3999) #define SID_OPEN_NEW_VIEW (SID_SFX_START + 520) diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx index d3fa0d17fc8d..bf1e4bde664b 100644 --- a/include/svl/itemset.hxx +++ b/include/svl/itemset.hxx @@ -170,6 +170,12 @@ public: return nullptr; } + template <class T> + static const T* GetItem(const SfxItemSet* pItemSet, TypedWhichId<T> nWhich, + bool bSearchInParent) + { + return GetItem<T>(pItemSet, static_cast<sal_uInt16>(nWhich), bSearchInParent); + } sal_uInt16 GetWhichByPos(sal_uInt16 nPos) const; diff --git a/sfx2/source/appl/appuno.cxx b/sfx2/source/appl/appuno.cxx index 5b50b2e7a145..bfb3d651458d 100644 --- a/sfx2/source/appl/appuno.cxx +++ b/sfx2/source/appl/appuno.cxx @@ -107,6 +107,7 @@ SfxFormalArgument const aFormalArgs[] = { { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "SaveACopy", SID_SAVEACOPYITEM }, { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "NoFileSync", SID_NO_FILE_SYNC }, { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "NoThumbnail", SID_NO_THUMBNAIL }, + { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "NoEmbDataSet", SID_NO_EMBEDDED_DS }, }; static sal_uInt16 nMediaArgsCount = SAL_N_ELEMENTS(aFormalArgs); diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx index 20c9d6bf1da6..5bc9da2d76dd 100644 --- a/sfx2/source/doc/objstor.cxx +++ b/sfx2/source/doc/objstor.cxx @@ -3121,7 +3121,16 @@ bool SfxObjectShell::SaveAsChildren( SfxMedium& rMedium ) GetEmbeddedObjectContainer().StoreAsChildren(bOasis,SfxObjectCreateMode::EMBEDDED == eCreateMode,xStorage); } - return CopyStoragesOfUnknownMediaType(GetStorage(), xStorage); + uno::Sequence<OUString> aExceptions; + if (const SfxBoolItem* pNoEmbDS + = SfxItemSet::GetItem(rMedium.GetItemSet(), SID_NO_EMBEDDED_DS, false)) + { + // Don't save data source in case a temporary is being saved for preview in MM wizard + if (pNoEmbDS->GetValue()) + aExceptions = uno::Sequence<OUString>{ "EmbeddedDatabase" }; + } + + return CopyStoragesOfUnknownMediaType(GetStorage(), xStorage, aExceptions); } bool SfxObjectShell::SaveCompletedChildren() @@ -3350,8 +3359,9 @@ bool SfxObjectShell::SwitchPersistance( const uno::Reference< embed::XStorage >& return bResult; } -bool SfxObjectShell::CopyStoragesOfUnknownMediaType( const uno::Reference< embed::XStorage >& xSource, - const uno::Reference< embed::XStorage >& xTarget ) +bool SfxObjectShell::CopyStoragesOfUnknownMediaType(const uno::Reference< embed::XStorage >& xSource, + const uno::Reference< embed::XStorage >& xTarget, + const uno::Sequence<OUString>& rExceptions) { // This method does not commit the target storage and should not do it bool bResult = true; @@ -3360,6 +3370,9 @@ bool SfxObjectShell::CopyStoragesOfUnknownMediaType( const uno::Reference< embed { for (const OUString& rSubElement : xSource->getElementNames()) { + if (std::find(rExceptions.begin(), rExceptions.end(), rSubElement) != rExceptions.end()) + continue; + if (rSubElement == "Configurations") { // The workaround for compatibility with SO7, "Configurations" substorage must be preserved diff --git a/sw/inc/dbmgr.hxx b/sw/inc/dbmgr.hxx index fda615a62b17..09bd02196528 100644 --- a/sw/inc/dbmgr.hxx +++ b/sw/inc/dbmgr.hxx @@ -460,7 +460,7 @@ public: static void StoreEmbeddedDataSource(const css::uno::Reference<css::frame::XStorable>& xStorable, const css::uno::Reference<css::embed::XStorage>& xStorage, const OUString& rStreamRelPath, - const OUString& rOwnURL); + const OUString& rOwnURL, bool bCopyTo = false); SwDoc* getDoc() const; /// Stop reacting to removed database registrations. diff --git a/sw/source/ui/dbui/mmlayoutpage.cxx b/sw/source/ui/dbui/mmlayoutpage.cxx index ff38b6d75aa8..4fb050c0096d 100644 --- a/sw/source/ui/dbui/mmlayoutpage.cxx +++ b/sw/source/ui/dbui/mmlayoutpage.cxx @@ -111,10 +111,13 @@ SwMailMergeLayoutPage::SwMailMergeLayoutPage( SwMailMergeWizard* _pParent) : aTempFile.EnableKillingFile(); } SwView* pView = m_pWizard->GetSwView(); - uno::Sequence< beans::PropertyValue > aValues(1); + uno::Sequence< beans::PropertyValue > aValues(2); beans::PropertyValue* pValues = aValues.getArray(); pValues[0].Name = "FilterName"; pValues[0].Value <<= pSfxFlt->GetFilterName(); + // Don't save embedded data set! It would steal it from current document. + pValues[1].Name = "NoEmbDataSet"; + pValues[1].Value <<= true; uno::Reference< frame::XStorable > xStore( pView->GetDocShell()->GetModel(), uno::UNO_QUERY); xStore->storeToURL( m_sExampleURL, aValues ); diff --git a/sw/source/uibase/app/docsh.cxx b/sw/source/uibase/app/docsh.cxx index 6220954d1b35..d1ed88666246 100644 --- a/sw/source/uibase/app/docsh.cxx +++ b/sw/source/uibase/app/docsh.cxx @@ -424,8 +424,17 @@ bool SwDocShell::SaveAs( SfxMedium& rMedium ) CalcLayoutForOLEObjects(); // format for OLE objects - bool bURLChanged = !GetMedium() || GetMedium()->GetURLObject() != rMedium.GetURLObject(); - if (!m_xDoc->GetDBManager()->getEmbeddedName().isEmpty() && bURLChanged) + const bool bURLChanged = !GetMedium() || GetMedium()->GetURLObject() != rMedium.GetURLObject(); + const bool bHasEmbedded = !m_xDoc->GetDBManager()->getEmbeddedName().isEmpty(); + bool bSaveDS = bHasEmbedded && bURLChanged; + if (bSaveDS) + { + // Don't save data source in case a temporary is being saved for preview in MM wizard + if (const SfxBoolItem* pNoEmbDS + = SfxItemSet::GetItem(rMedium.GetItemSet(), SID_NO_EMBEDDED_DS, false)) + bSaveDS = !pNoEmbDS->GetValue(); + } + if (bSaveDS) { // We have an embedded data source definition, need to re-store it, // otherwise relative references will break when the new file is in a @@ -443,9 +452,19 @@ bool SwDocShell::SaveAs( SfxMedium& rMedium ) + INetURLObject::encode(m_xDoc->GetDBManager()->getEmbeddedName(), INetURLObject::PART_FPATH, INetURLObject::EncodeMechanism::All); + bool bCopyTo = GetCreateMode() == SfxObjectCreateMode::EMBEDDED; + if (!bCopyTo) + { + if (const SfxBoolItem* pSaveToItem + = SfxItemSet::GetItem(rMedium.GetItemSet(), SID_SAVETO, false)) + bCopyTo = pSaveToItem->GetValue(); + } + uno::Reference<sdb::XDocumentDataSource> xDataSource(xDatabaseContext->getByName(aURL), uno::UNO_QUERY); uno::Reference<frame::XStorable> xStorable(xDataSource->getDatabaseDocument(), uno::UNO_QUERY); - SwDBManager::StoreEmbeddedDataSource(xStorable, rMedium.GetOutputStorage(), m_xDoc->GetDBManager()->getEmbeddedName(), rMedium.GetName()); + SwDBManager::StoreEmbeddedDataSource(xStorable, rMedium.GetOutputStorage(), + m_xDoc->GetDBManager()->getEmbeddedName(), + rMedium.GetName(), bCopyTo); } // #i62875# diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx index 2119b825ef5c..3ce9d2c14156 100644 --- a/sw/source/uibase/dbui/dbmgr.cxx +++ b/sw/source/uibase/dbui/dbmgr.cxx @@ -2932,7 +2932,7 @@ OUString SwDBManager::LoadAndRegisterDataSource(weld::Window* pParent, SwDocShel void SwDBManager::StoreEmbeddedDataSource(const uno::Reference<frame::XStorable>& xStorable, const uno::Reference<embed::XStorage>& xStorage, const OUString& rStreamRelPath, - const OUString& rOwnURL) + const OUString& rOwnURL, bool bCopyTo) { // Construct vnd.sun.star.pkg:// URL for later loading, and TargetStorage/StreamRelPath for storing. OUString const sTmpName = ConstructVndSunStarPkgUrl(rOwnURL, rStreamRelPath); @@ -2943,7 +2943,10 @@ void SwDBManager::StoreEmbeddedDataSource(const uno::Reference<frame::XStorable> {"StreamRelPath", uno::makeAny(rStreamRelPath)}, {"BaseURI", uno::makeAny(rOwnURL)} }); - xStorable->storeAsURL(sTmpName, aSequence); + if (bCopyTo) + xStorable->storeToURL(sTmpName, aSequence); + else + xStorable->storeAsURL(sTmpName, aSequence); } OUString SwDBManager::LoadAndRegisterDataSource(const OUString &rURI, const OUString *pDestDir) |