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 <sbergman@redhat.com>
This commit is contained in:
Stephan Bergmann
2022-10-18 11:15:46 +02:00
parent 8ad39b6f2a
commit d4512d391b
10 changed files with 91 additions and 1 deletions

View File

@@ -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

View File

@@ -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(

View File

@@ -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

View File

@@ -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 )
{

View File

@@ -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();

View File

@@ -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: */

View File

@@ -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 );

View File

@@ -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: */

View File

@@ -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<

View File

@@ -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 ) );
}