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>
This commit is contained in:
@@ -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 );
|
||||
|
@@ -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
|
||||
|
@@ -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 );
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
@@ -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 );
|
||||
|
@@ -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#
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user