summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2018-07-09 19:49:34 +1000
committerMike Kaganski <mike.kaganski@collabora.com>2018-07-10 18:38:40 +0200
commitedc62adae9a354ca1305e83b10c98a545f58d341 (patch)
tree5bdbcf8901df3e18183fcffc8c4ac6c9c6ae610a
parentd7cdb7fcc48a580cd5183ba899f73f2ad9bdbec9 (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.cxx34
-rw-r--r--dbaccess/source/core/dataaccess/databasedocument.hxx13
-rw-r--r--include/sfx2/objsh.hxx3
-rw-r--r--include/sfx2/sfxsids.hrc7
-rw-r--r--include/svl/itemset.hxx6
-rw-r--r--sfx2/source/appl/appuno.cxx1
-rw-r--r--sfx2/source/doc/objstor.cxx19
-rw-r--r--sw/inc/dbmgr.hxx2
-rw-r--r--sw/source/ui/dbui/mmlayoutpage.cxx5
-rw-r--r--sw/source/uibase/app/docsh.cxx25
-rw-r--r--sw/source/uibase/dbui/dbmgr.cxx7
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)