[Libreoffice-commits] core.git: dbaccess/source include/sfx2 include/svl sfx2/source sw/inc sw/source

Mike Kaganski mike.kaganski at collabora.com
Tue Jul 10 16:39:02 UTC 2018


 dbaccess/source/core/dataaccess/databasedocument.cxx |   34 ++++++++++++-------
 dbaccess/source/core/dataaccess/databasedocument.hxx |   13 +++++++
 include/sfx2/objsh.hxx                               |    3 +
 include/sfx2/sfxsids.hrc                             |    7 ++-
 include/svl/itemset.hxx                              |    6 +++
 sfx2/source/appl/appuno.cxx                          |    1 
 sfx2/source/doc/objstor.cxx                          |   19 ++++++++--
 sw/inc/dbmgr.hxx                                     |    2 -
 sw/source/ui/dbui/mmlayoutpage.cxx                   |    5 ++
 sw/source/uibase/app/docsh.cxx                       |   25 ++++++++++++-
 sw/source/uibase/dbui/dbmgr.cxx                      |    7 ++-
 11 files changed, 98 insertions(+), 24 deletions(-)

New commits:
commit edc62adae9a354ca1305e83b10c98a545f58d341
Author: Mike Kaganski <mike.kaganski at collabora.com>
Date:   Mon Jul 9 19:49:34 2018 +1000

    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 at collabora.com>

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)


More information about the Libreoffice-commits mailing list