OfficeDocumentsManager::OfficeDocumentsManager( const uno::Reference< uno::XComponentContext > & rxContext,
ContentProvider * pDocEventListener )
: m_xContext( rxContext ),
m_xDocEvtNotifier( frame::theGlobalEventBroadcaster::get( rxContext ) ),
m_pDocEventListener( pDocEventListener ),
m_xDocCloseListener( new OfficeDocumentsCloseListener( this ) )
{ // Order is important (multithreaded environment)
uno::Reference< document::XDocumentEventBroadcaster >(
m_xDocEvtNotifier, uno::UNO_QUERY_THROW )->addDocumentEventListener( this );
buildDocumentsList();
}
// virtual
OfficeDocumentsManager::~OfficeDocumentsManager()
{ //OSL_ENSURE( m_aDocs.empty(), "document list not empty!" ); // no need to assert this: Normal shutdown of LibreOffice could already trigger it, since the order // in which objects are actually released/destroyed upon shutdown is not defined. And when we // arrive *here*, LibreOffice *is* shutting down currently, since we're held by the TDOC provider, // which is disposed upon shutdown.
m_xDocCloseListener->Dispose();
}
// Try to get the UID directly from the document.
uno::Reference< beans::XPropertySet > xPropSet( xDoc, uno::UNO_QUERY ); if ( xPropSet.is() )
{ try
{
uno::Any aValue = xPropSet->getPropertyValue(u"RuntimeUID"_ustr);
aValue >>= aId;
} catch ( beans::UnknownPropertyException const & )
{ // Not actually an error. Property is optional.
} catch ( lang::WrappedTargetException const & )
{
TOOLS_WARN_EXCEPTION("ucb.ucp", "Caught WrappedTargetException!");
}
}
if ( aId.isEmpty() )
{ // fallback: generate UID from document's this pointer. // normalize the interface pointer first. Else, calls with different // interfaces to the same object (say, XFoo and XBar) will produce // different IDs
uno::Reference< uno::XInterface > xNormalizedIFace( xDoc, uno::UNO_QUERY );
sal_Int64 nId = reinterpret_cast< sal_Int64 >( xNormalizedIFace.get() );
aId = OUString::number( nId );
}
uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster(
Event.Source, uno::UNO_QUERY );
OSL_ENSURE( xCloseBroadcaster.is(), "OnLoadFinished/OnCreate event: got no close broadcaster!" );
if ( xCloseBroadcaster.is() )
xCloseBroadcaster->addCloseListener(m_xDocCloseListener);
// Propagate document closure.
OSL_ENSURE( m_pDocEventListener, "OnLoadFinished/OnCreate event: no owner for insert event propagation!" );
if ( m_pDocEventListener )
m_pDocEventListener->notifyDocumentOpened( aDocId );
}
}
} elseif ( Event.EventName == "OfficeDocumentsListener::notifyClosing" )
{ if ( isOfficeDocument( Event.Source ) )
{ // Document has been closed (unloaded)
// Official event "OnUnload" does not work here. Event // gets fired too early. Other OnUnload listeners called after this // listener may still need TDOC access to the document. Remove the // document from TDOC docs list on XCloseListener::notifyClosing. // See OfficeDocumentsManager::OfficeDocumentsListener::notifyClosing.
// OSL_ENSURE( it != m_aDocs.end(), // "TitleChanged event notified for unknown document!" ); // TODO: re-enable this assertion. It has been disabled for now, since it breaks the assertion-free smoketest, // and the fix is more difficult than what can be done now. // The problem is that at the moment, when you close a SFX-based document via API, it will first // fire the notifyClosing event, which will make the OfficeDocumentsManager remove the doc from its list. // Then, it will notify an OnTitleChanged, then an OnUnload. Documents closed via call the notifyClosing // *after* OnUnload and all other On* events. // In agreement with MBA, the implementation for SfxBaseModel::Close should be changed to also send notifyClosing // as last event. When this happens, the assertion here must be enabled, again.
}
}
}
// lang::XDocumentEventListener (base of document::XDocumentEventListener)
uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster(
xModel, uno::UNO_QUERY );
OSL_ENSURE( xCloseBroadcaster.is(), "buildDocumentsList: got no close broadcaster!" );
if ( xCloseBroadcaster.is() )
xCloseBroadcaster->addCloseListener(m_xDocCloseListener);
}
}
}
} catch ( lang::DisposedException const & )
{ // Note: Due to race conditions the XEnumeration can // contain docs that have already been closed
} catch ( lang::NotInitializedException const & )
{ // Note: Due to race conditions the XEnumeration can // contain docs that are still uninitialized
}
}
}
void OfficeDocumentsManager::updateStreamDateModified(OUString const & uri) {
std::scoped_lock g(m_aMtx); autoconst 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();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.