include/sal/log-areas.dox                |    1 +
 ucb/source/ucp/tdoc/tdoc_content.cxx     |   26 ++++++++++++++++++++++++++
 ucb/source/ucp/tdoc/tdoc_contentcaps.cxx |    9 +++++++++
 ucb/source/ucp/tdoc/tdoc_docmgr.cxx      |   26 ++++++++++++++++++++++++++
 ucb/source/ucp/tdoc/tdoc_docmgr.hxx      |    7 +++++++
 ucb/source/ucp/tdoc/tdoc_provider.cxx    |    5 +++++
 ucb/source/ucp/tdoc/tdoc_provider.hxx    |    6 ++++++
 ucb/source/ucp/tdoc/tdoc_stgelems.cxx    |    5 +++++
 ucb/source/ucp/tdoc/tdoc_stgelems.hxx    |    5 +++++
 ucb/source/ucp/tdoc/tdoc_storage.cxx     |    2 +-
 10 files changed, 91 insertions(+), 1 deletion(-)

New commits:
commit d4512d391bc7f96af9b66a8ee44f3f2be38dc5ec
Author:     Stephan Bergmann <sberg...@redhat.com>
AuthorDate: Tue Oct 18 11:15:46 2022 +0200
Commit:     Stephan Bergmann <sberg...@redhat.com>
CommitDate: Tue Oct 18 12:26:19 2022 +0200

    tdf#105609: Support DateModified for updated tdoc stream contents
    
    ...so that the Python script provider, based on those DateModified values, 
will
    reload a script embedded in a document after that script has 
(programmatically)
    been modified.
    
    As long as a stream content in a tdoc document has not been modified, it 
will
    report a default-initialized (all zero) DateModified.  Only when the stream 
has
    been modified will that be changed to the current date.  While that might 
not be
    the most beautiful implementation, it at least gets the job done of fixing
    tdf#105609 "Python script provider does not reload modified embedded 
scripts".
    
    (The DateModified values cannot be stored directly in the tdoc_ucp::Content
    instances, as those are thrown away and recreated on demand.  So they 
needed to
    be stored more persistently at the tdoc_ucp::OfficeDocumentsManager.)
    
    Change-Id: Iee809960e1a1bc40961f0df2b3729e58b75e6028
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141491
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sberg...@redhat.com>

diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox
index e1c89b1f7df2..bf3a269f2f66 100644
--- a/include/sal/log-areas.dox
+++ b/include/sal/log-areas.dox
@@ -433,6 +433,7 @@ certain functionality.
 @li @c ucb.ucp.file
 @li @c ucb.ucp.ftp
 @li @c ucb.ucp.gio
+@li @c ucb.ucp.tdoc
 @li @c ucb.ucp.webdav
 @li @c ucb.ucp.webdav.curl
 
diff --git a/ucb/source/ucp/tdoc/tdoc_content.cxx 
b/ucb/source/ucp/tdoc/tdoc_content.cxx
index 89335ce58493..03c80a2ad756 100644
--- a/ucb/source/ucp/tdoc/tdoc_content.cxx
+++ b/ucb/source/ucp/tdoc/tdoc_content.cxx
@@ -895,6 +895,20 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues(
                 xRow->appendObject(
                     rProp, uno::Any( rData.getCreatableContentsInfo() ) );
             }
+            else if ( rProp.Name == "DateModified" )
+            {
+                // DateModified is only supported by streams.
+                ContentType eType = rData.getType();
+                if ( eType == STREAM )
+                {
+                    xRow->appendObject(
+                        rProp,
+                        uno::Any(
+                            pProvider->queryStreamDateModified( rContentId ) ) 
);
+                }
+                else
+                    xRow->appendVoid( rProp );
+            }
             else if ( rProp.Name == "Storage" )
             {
                 // Storage is only supported by folders.
@@ -995,6 +1009,18 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues(
                 | beans::PropertyAttribute::READONLY ),
             uno::Any( rData.getCreatableContentsInfo() ) );
 
+        // DateModified is only supported by streams.
+        if ( eType == STREAM )
+        {
+            xRow->appendObject(
+                beans::Property( "DateModified",
+                          -1,
+                          cppu::UnoType<css::util::DateTime>::get(),
+                          beans::PropertyAttribute::BOUND
+                            | beans::PropertyAttribute::READONLY ),
+                uno::Any( pProvider->queryStreamDateModified( rContentId ) ) );
+        }
+
         // Storage is only supported by folders.
         if ( eType == FOLDER )
             xRow->appendObject(
diff --git a/ucb/source/ucp/tdoc/tdoc_contentcaps.cxx 
b/ucb/source/ucp/tdoc/tdoc_contentcaps.cxx
index 8b19f9ec94b8..384bac2f941f 100644
--- a/ucb/source/ucp/tdoc/tdoc_contentcaps.cxx
+++ b/ucb/source/ucp/tdoc/tdoc_contentcaps.cxx
@@ -34,6 +34,7 @@
     IsFolder            r       r       r       r       r       r
     Title               r       r       w       w       w       w
     CreatableContentsInfo r     r       r       r       r       r
+    DateModified        -       -       -       -       r       r
     Storage             -       -       r       r       -       -
     DocumentModel       -       r       -       -       -       -
 
@@ -58,6 +59,7 @@
 #include <com/sun/star/ucb/CommandInfo.hpp>
 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
 #include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/util/DateTime.hpp>
 #include <osl/diagnose.h>
 #include <sal/macros.h>
 #include "tdoc_content.hxx"
@@ -138,6 +140,13 @@ uno::Sequence< beans::Property > Content::getProperties(
                 cppu::UnoType<uno::Sequence< ucb::ContentInfo >>::get(),
                 beans::PropertyAttribute::BOUND
                     | beans::PropertyAttribute::READONLY
+            ),
+            beans::Property(
+                "DateModified",
+                -1,
+                cppu::UnoType<css::util::DateTime>::get(),
+                beans::PropertyAttribute::BOUND
+                    | beans::PropertyAttribute::READONLY
             )
 
             // New properties
diff --git a/ucb/source/ucp/tdoc/tdoc_docmgr.cxx 
b/ucb/source/ucp/tdoc/tdoc_docmgr.cxx
index 34f87ef60223..0e11f546bb1e 100644
--- a/ucb/source/ucp/tdoc/tdoc_docmgr.cxx
+++ b/ucb/source/ucp/tdoc/tdoc_docmgr.cxx
@@ -20,6 +20,8 @@
 
 #include <rtl/ref.hxx>
 #include <comphelper/diagnose_ex.hxx>
+#include <sal/log.hxx>
+#include <tools/datetime.hxx>
 
 #include <comphelper/documentinfo.hxx>
 #include <comphelper/namedvaluecollection.hxx>
@@ -529,6 +531,30 @@ OfficeDocumentsManager::queryStorageTitle( const OUString 
& rDocId )
 }
 
 
+css::util::DateTime OfficeDocumentsManager::queryStreamDateModified(OUString 
const & uri) {
+    std::scoped_lock g(m_aMtx);
+    auto const i1 = m_aDocs.find(Uri(uri).getDocumentId());
+    if (i1 != m_aDocs.end()) {
+        auto const i2 = i1->second.streamDateModified.find(uri);
+        if (i2 != i1->second.streamDateModified.end()) {
+            return i2->second;
+        }
+    }
+    return {};
+}
+
+
+void OfficeDocumentsManager::updateStreamDateModified(OUString const & uri) {
+    std::scoped_lock g(m_aMtx);
+    auto const i = m_aDocs.find(Uri(uri).getDocumentId());
+    if (i == m_aDocs.end()) {
+        SAL_WARN("ucb.ucp.tdoc", "No document info for <" << uri << ">");
+        return;
+    }
+    i->second.streamDateModified[uri] = 
DateTime(DateTime::SYSTEM).GetUNODateTime();
+}
+
+
 bool OfficeDocumentsManager::isDocumentPreview(
         const uno::Reference< frame::XModel > & xModel )
 {
diff --git a/ucb/source/ucp/tdoc/tdoc_docmgr.hxx 
b/ucb/source/ucp/tdoc/tdoc_docmgr.hxx
index fbf70c8906c7..8daf9eba60e4 100644
--- a/ucb/source/ucp/tdoc/tdoc_docmgr.hxx
+++ b/ucb/source/ucp/tdoc/tdoc_docmgr.hxx
@@ -29,10 +29,12 @@
 #include <com/sun/star/frame/XModuleManager2.hpp>
 #include <com/sun/star/frame/XGlobalEventBroadcaster.hpp>
 #include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/util/DateTime.hpp>
 #include <com/sun/star/util/XCloseListener.hpp>
 
 #include <map>
 #include <mutex>
+#include <unordered_map>
 #include <utility>
 
 namespace tdoc_ucp {
@@ -44,6 +46,7 @@ namespace tdoc_ucp {
         OUString aTitle;
         css::uno::Reference< css::embed::XStorage > xStorage;
         css::uno::Reference< css::frame::XModel >   xModel;
+        std::unordered_map<OUString, css::util::DateTime> streamDateModified;
 
         StorageInfo() {}; // needed for STL map only.
 
@@ -119,6 +122,10 @@ namespace tdoc_ucp {
         OUString
         queryStorageTitle( const OUString & rDocId );
 
+        css::util::DateTime queryStreamDateModified(OUString const & uri);
+
+        void updateStreamDateModified(OUString const & uri);
+
     private:
         void buildDocumentsList();
 
diff --git a/ucb/source/ucp/tdoc/tdoc_provider.cxx 
b/ucb/source/ucp/tdoc/tdoc_provider.cxx
index 29f0524373c6..c5d120be076f 100644
--- a/ucb/source/ucp/tdoc/tdoc_provider.cxx
+++ b/ucb/source/ucp/tdoc/tdoc_provider.cxx
@@ -602,4 +602,9 @@ ContentProvider::queryDocumentModel( const OUString & rUri 
) const
     return xModel;
 }
 
+
+css::util::DateTime ContentProvider::queryStreamDateModified(OUString const & 
uri) const {
+    return m_xDocsMgr->queryStreamDateModified(uri);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/ucb/source/ucp/tdoc/tdoc_provider.hxx 
b/ucb/source/ucp/tdoc/tdoc_provider.hxx
index 95ffa789f730..a1f93db5ecc4 100644
--- a/ucb/source/ucp/tdoc/tdoc_provider.hxx
+++ b/ucb/source/ucp/tdoc/tdoc_provider.hxx
@@ -39,6 +39,10 @@ namespace com::sun::star::frame {
     class XModel;
 }
 
+namespace com::sun::star::util {
+    struct DateTime;
+}
+
 namespace tdoc_ucp {
 
 
@@ -130,6 +134,8 @@ public:
     css::uno::Reference< css::frame::XModel >
     queryDocumentModel( const OUString & rUri ) const;
 
+    css::util::DateTime queryStreamDateModified(OUString const & uri) const;
+
     // interface OfficeDocumentsEventListener
     void notifyDocumentOpened( std::u16string_view rDocId );
     void notifyDocumentClosed( std::u16string_view rDocId );
diff --git a/ucb/source/ucp/tdoc/tdoc_stgelems.cxx 
b/ucb/source/ucp/tdoc/tdoc_stgelems.cxx
index acd2b26db5f1..9b1159fc2c41 100644
--- a/ucb/source/ucp/tdoc/tdoc_stgelems.cxx
+++ b/ucb/source/ucp/tdoc/tdoc_stgelems.cxx
@@ -32,6 +32,7 @@
 #include <com/sun/star/reflection/ProxyFactory.hpp>
 #include <utility>
 
+#include "tdoc_docmgr.hxx"
 #include "tdoc_uri.hxx"
 
 #include "tdoc_stgelems.hxx"
@@ -615,10 +616,13 @@ OutputStream::removeEventListener(
 
 Stream::Stream(
             const uno::Reference< uno::XComponentContext > & rxContext,
+            rtl::Reference<OfficeDocumentsManager> const & docsMgr,
             const OUString & rUri,
             const uno::Reference< embed::XStorage >  & xParentStorage,
             const uno::Reference< io::XStream > & xStreamToWrap )
 : ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ),
+  m_docsMgr(docsMgr),
+  m_uri(rUri),
   m_xWrappedStream( xStreamToWrap ),
   m_xWrappedOutputStream( xStreamToWrap->getOutputStream() ), // might be empty
   m_xWrappedTruncate( m_xWrappedOutputStream, uno::UNO_QUERY ), // might be 
empty
@@ -872,6 +876,7 @@ void Stream::commitChanges()
             throw io::IOException(); // @@@
         }
     }
+    m_docsMgr->updateStreamDateModified(m_uri);
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/ucb/source/ucp/tdoc/tdoc_stgelems.hxx 
b/ucb/source/ucp/tdoc/tdoc_stgelems.hxx
index a7aa306684bf..6229923f226c 100644
--- a/ucb/source/ucp/tdoc/tdoc_stgelems.hxx
+++ b/ucb/source/ucp/tdoc/tdoc_stgelems.hxx
@@ -37,6 +37,8 @@
 
 namespace tdoc_ucp {
 
+class OfficeDocumentsManager;
+
 class ParentStorageHolder
 {
 public:
@@ -246,6 +248,7 @@ class Stream : public StreamUNOBase, public 
ParentStorageHolder
 public:
     Stream(
         const css::uno::Reference< css::uno::XComponentContext > & rxContext,
+        rtl::Reference<OfficeDocumentsManager> const & docsMgr,
         const OUString & rUri,
         const css::uno::Reference< css::embed::XStorage >  & xParentStorage,
         const css::uno::Reference< css::io::XStream > & xStreamToWrap );
@@ -315,6 +318,8 @@ private:
     /// @throws css::io::IOException
     void commitChanges();
 
+    rtl::Reference<OfficeDocumentsManager> m_docsMgr;
+    OUString m_uri;
     css::uno::Reference<
         css::uno::XAggregation >     m_xAggProxy;
     css::uno::Reference<
diff --git a/ucb/source/ucp/tdoc/tdoc_storage.cxx 
b/ucb/source/ucp/tdoc/tdoc_storage.cxx
index d7633e5b1ed4..fe307a5bfa2d 100644
--- a/ucb/source/ucp/tdoc/tdoc_storage.cxx
+++ b/ucb/source/ucp/tdoc/tdoc_storage.cxx
@@ -316,7 +316,7 @@ StorageElementFactory::createStream( const OUString & rUri,
     }
 
     return uno::Reference< io::XStream >(
-        new Stream( m_xContext, rUri, xParentStorage, xStream ) );
+        new Stream( m_xContext, m_xDocsMgr, rUri, xParentStorage, xStream ) );
 }
 
 

Reply via email to