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:
@@ -433,6 +433,7 @@ certain functionality.
|
|||||||
@li @c ucb.ucp.file
|
@li @c ucb.ucp.file
|
||||||
@li @c ucb.ucp.ftp
|
@li @c ucb.ucp.ftp
|
||||||
@li @c ucb.ucp.gio
|
@li @c ucb.ucp.gio
|
||||||
|
@li @c ucb.ucp.tdoc
|
||||||
@li @c ucb.ucp.webdav
|
@li @c ucb.ucp.webdav
|
||||||
@li @c ucb.ucp.webdav.curl
|
@li @c ucb.ucp.webdav.curl
|
||||||
|
|
||||||
|
@@ -895,6 +895,20 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues(
|
|||||||
xRow->appendObject(
|
xRow->appendObject(
|
||||||
rProp, uno::Any( rData.getCreatableContentsInfo() ) );
|
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" )
|
else if ( rProp.Name == "Storage" )
|
||||||
{
|
{
|
||||||
// Storage is only supported by folders.
|
// Storage is only supported by folders.
|
||||||
@@ -995,6 +1009,18 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues(
|
|||||||
| beans::PropertyAttribute::READONLY ),
|
| beans::PropertyAttribute::READONLY ),
|
||||||
uno::Any( rData.getCreatableContentsInfo() ) );
|
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.
|
// Storage is only supported by folders.
|
||||||
if ( eType == FOLDER )
|
if ( eType == FOLDER )
|
||||||
xRow->appendObject(
|
xRow->appendObject(
|
||||||
|
@@ -34,6 +34,7 @@
|
|||||||
IsFolder r r r r r r
|
IsFolder r r r r r r
|
||||||
Title r r w w w w
|
Title r r w w w w
|
||||||
CreatableContentsInfo r r r r r r
|
CreatableContentsInfo r r r r r r
|
||||||
|
DateModified - - - - r r
|
||||||
Storage - - r r - -
|
Storage - - r r - -
|
||||||
DocumentModel - r - - - -
|
DocumentModel - r - - - -
|
||||||
|
|
||||||
@@ -58,6 +59,7 @@
|
|||||||
#include <com/sun/star/ucb/CommandInfo.hpp>
|
#include <com/sun/star/ucb/CommandInfo.hpp>
|
||||||
#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
|
#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
|
||||||
#include <com/sun/star/ucb/TransferInfo.hpp>
|
#include <com/sun/star/ucb/TransferInfo.hpp>
|
||||||
|
#include <com/sun/star/util/DateTime.hpp>
|
||||||
#include <osl/diagnose.h>
|
#include <osl/diagnose.h>
|
||||||
#include <sal/macros.h>
|
#include <sal/macros.h>
|
||||||
#include "tdoc_content.hxx"
|
#include "tdoc_content.hxx"
|
||||||
@@ -138,6 +140,13 @@ uno::Sequence< beans::Property > Content::getProperties(
|
|||||||
cppu::UnoType<uno::Sequence< ucb::ContentInfo >>::get(),
|
cppu::UnoType<uno::Sequence< ucb::ContentInfo >>::get(),
|
||||||
beans::PropertyAttribute::BOUND
|
beans::PropertyAttribute::BOUND
|
||||||
| beans::PropertyAttribute::READONLY
|
| beans::PropertyAttribute::READONLY
|
||||||
|
),
|
||||||
|
beans::Property(
|
||||||
|
"DateModified",
|
||||||
|
-1,
|
||||||
|
cppu::UnoType<css::util::DateTime>::get(),
|
||||||
|
beans::PropertyAttribute::BOUND
|
||||||
|
| beans::PropertyAttribute::READONLY
|
||||||
)
|
)
|
||||||
|
|
||||||
// New properties
|
// New properties
|
||||||
|
@@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include <rtl/ref.hxx>
|
#include <rtl/ref.hxx>
|
||||||
#include <comphelper/diagnose_ex.hxx>
|
#include <comphelper/diagnose_ex.hxx>
|
||||||
|
#include <sal/log.hxx>
|
||||||
|
#include <tools/datetime.hxx>
|
||||||
|
|
||||||
#include <comphelper/documentinfo.hxx>
|
#include <comphelper/documentinfo.hxx>
|
||||||
#include <comphelper/namedvaluecollection.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(
|
bool OfficeDocumentsManager::isDocumentPreview(
|
||||||
const uno::Reference< frame::XModel > & xModel )
|
const uno::Reference< frame::XModel > & xModel )
|
||||||
{
|
{
|
||||||
|
@@ -29,10 +29,12 @@
|
|||||||
#include <com/sun/star/frame/XModuleManager2.hpp>
|
#include <com/sun/star/frame/XModuleManager2.hpp>
|
||||||
#include <com/sun/star/frame/XGlobalEventBroadcaster.hpp>
|
#include <com/sun/star/frame/XGlobalEventBroadcaster.hpp>
|
||||||
#include <com/sun/star/uno/XComponentContext.hpp>
|
#include <com/sun/star/uno/XComponentContext.hpp>
|
||||||
|
#include <com/sun/star/util/DateTime.hpp>
|
||||||
#include <com/sun/star/util/XCloseListener.hpp>
|
#include <com/sun/star/util/XCloseListener.hpp>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace tdoc_ucp {
|
namespace tdoc_ucp {
|
||||||
@@ -44,6 +46,7 @@ namespace tdoc_ucp {
|
|||||||
OUString aTitle;
|
OUString aTitle;
|
||||||
css::uno::Reference< css::embed::XStorage > xStorage;
|
css::uno::Reference< css::embed::XStorage > xStorage;
|
||||||
css::uno::Reference< css::frame::XModel > xModel;
|
css::uno::Reference< css::frame::XModel > xModel;
|
||||||
|
std::unordered_map<OUString, css::util::DateTime> streamDateModified;
|
||||||
|
|
||||||
StorageInfo() {}; // needed for STL map only.
|
StorageInfo() {}; // needed for STL map only.
|
||||||
|
|
||||||
@@ -119,6 +122,10 @@ namespace tdoc_ucp {
|
|||||||
OUString
|
OUString
|
||||||
queryStorageTitle( const OUString & rDocId );
|
queryStorageTitle( const OUString & rDocId );
|
||||||
|
|
||||||
|
css::util::DateTime queryStreamDateModified(OUString const & uri);
|
||||||
|
|
||||||
|
void updateStreamDateModified(OUString const & uri);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void buildDocumentsList();
|
void buildDocumentsList();
|
||||||
|
|
||||||
|
@@ -602,4 +602,9 @@ ContentProvider::queryDocumentModel( const OUString & rUri ) const
|
|||||||
return xModel;
|
return xModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
css::util::DateTime ContentProvider::queryStreamDateModified(OUString const & uri) const {
|
||||||
|
return m_xDocsMgr->queryStreamDateModified(uri);
|
||||||
|
}
|
||||||
|
|
||||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||||
|
@@ -39,6 +39,10 @@ namespace com::sun::star::frame {
|
|||||||
class XModel;
|
class XModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace com::sun::star::util {
|
||||||
|
struct DateTime;
|
||||||
|
}
|
||||||
|
|
||||||
namespace tdoc_ucp {
|
namespace tdoc_ucp {
|
||||||
|
|
||||||
|
|
||||||
@@ -130,6 +134,8 @@ public:
|
|||||||
css::uno::Reference< css::frame::XModel >
|
css::uno::Reference< css::frame::XModel >
|
||||||
queryDocumentModel( const OUString & rUri ) const;
|
queryDocumentModel( const OUString & rUri ) const;
|
||||||
|
|
||||||
|
css::util::DateTime queryStreamDateModified(OUString const & uri) const;
|
||||||
|
|
||||||
// interface OfficeDocumentsEventListener
|
// interface OfficeDocumentsEventListener
|
||||||
void notifyDocumentOpened( std::u16string_view rDocId );
|
void notifyDocumentOpened( std::u16string_view rDocId );
|
||||||
void notifyDocumentClosed( std::u16string_view rDocId );
|
void notifyDocumentClosed( std::u16string_view rDocId );
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
#include <com/sun/star/reflection/ProxyFactory.hpp>
|
#include <com/sun/star/reflection/ProxyFactory.hpp>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "tdoc_docmgr.hxx"
|
||||||
#include "tdoc_uri.hxx"
|
#include "tdoc_uri.hxx"
|
||||||
|
|
||||||
#include "tdoc_stgelems.hxx"
|
#include "tdoc_stgelems.hxx"
|
||||||
@@ -615,10 +616,13 @@ OutputStream::removeEventListener(
|
|||||||
|
|
||||||
Stream::Stream(
|
Stream::Stream(
|
||||||
const uno::Reference< uno::XComponentContext > & rxContext,
|
const uno::Reference< uno::XComponentContext > & rxContext,
|
||||||
|
rtl::Reference<OfficeDocumentsManager> const & docsMgr,
|
||||||
const OUString & rUri,
|
const OUString & rUri,
|
||||||
const uno::Reference< embed::XStorage > & xParentStorage,
|
const uno::Reference< embed::XStorage > & xParentStorage,
|
||||||
const uno::Reference< io::XStream > & xStreamToWrap )
|
const uno::Reference< io::XStream > & xStreamToWrap )
|
||||||
: ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ),
|
: ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ),
|
||||||
|
m_docsMgr(docsMgr),
|
||||||
|
m_uri(rUri),
|
||||||
m_xWrappedStream( xStreamToWrap ),
|
m_xWrappedStream( xStreamToWrap ),
|
||||||
m_xWrappedOutputStream( xStreamToWrap->getOutputStream() ), // might be empty
|
m_xWrappedOutputStream( xStreamToWrap->getOutputStream() ), // might be empty
|
||||||
m_xWrappedTruncate( m_xWrappedOutputStream, uno::UNO_QUERY ), // might be empty
|
m_xWrappedTruncate( m_xWrappedOutputStream, uno::UNO_QUERY ), // might be empty
|
||||||
@@ -872,6 +876,7 @@ void Stream::commitChanges()
|
|||||||
throw io::IOException(); // @@@
|
throw io::IOException(); // @@@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_docsMgr->updateStreamDateModified(m_uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||||
|
@@ -37,6 +37,8 @@
|
|||||||
|
|
||||||
namespace tdoc_ucp {
|
namespace tdoc_ucp {
|
||||||
|
|
||||||
|
class OfficeDocumentsManager;
|
||||||
|
|
||||||
class ParentStorageHolder
|
class ParentStorageHolder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -246,6 +248,7 @@ class Stream : public StreamUNOBase, public ParentStorageHolder
|
|||||||
public:
|
public:
|
||||||
Stream(
|
Stream(
|
||||||
const css::uno::Reference< css::uno::XComponentContext > & rxContext,
|
const css::uno::Reference< css::uno::XComponentContext > & rxContext,
|
||||||
|
rtl::Reference<OfficeDocumentsManager> const & docsMgr,
|
||||||
const OUString & rUri,
|
const OUString & rUri,
|
||||||
const css::uno::Reference< css::embed::XStorage > & xParentStorage,
|
const css::uno::Reference< css::embed::XStorage > & xParentStorage,
|
||||||
const css::uno::Reference< css::io::XStream > & xStreamToWrap );
|
const css::uno::Reference< css::io::XStream > & xStreamToWrap );
|
||||||
@@ -315,6 +318,8 @@ private:
|
|||||||
/// @throws css::io::IOException
|
/// @throws css::io::IOException
|
||||||
void commitChanges();
|
void commitChanges();
|
||||||
|
|
||||||
|
rtl::Reference<OfficeDocumentsManager> m_docsMgr;
|
||||||
|
OUString m_uri;
|
||||||
css::uno::Reference<
|
css::uno::Reference<
|
||||||
css::uno::XAggregation > m_xAggProxy;
|
css::uno::XAggregation > m_xAggProxy;
|
||||||
css::uno::Reference<
|
css::uno::Reference<
|
||||||
|
@@ -316,7 +316,7 @@ StorageElementFactory::createStream( const OUString & rUri,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return uno::Reference< io::XStream >(
|
return uno::Reference< io::XStream >(
|
||||||
new Stream( m_xContext, rUri, xParentStorage, xStream ) );
|
new Stream( m_xContext, m_xDocsMgr, rUri, xParentStorage, xStream ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user