LibreOffice Module ucb (master) 1
tdoc_docmgr.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21#include <rtl/ref.hxx>
23#include <sal/log.hxx>
24#include <tools/datetime.hxx>
25
29
30#include <com/sun/star/awt/XTopWindow.hpp>
31#include <com/sun/star/beans/XPropertySet.hpp>
32#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
33#include <com/sun/star/document/XStorageBasedDocument.hpp>
34#include <com/sun/star/frame/UnknownModuleException.hpp>
35#include <com/sun/star/frame/theGlobalEventBroadcaster.hpp>
36#include <com/sun/star/frame/ModuleManager.hpp>
37#include <com/sun/star/lang/DisposedException.hpp>
38#include <com/sun/star/lang/NotInitializedException.hpp>
39#include <com/sun/star/util/XCloseBroadcaster.hpp>
40
41#include "tdoc_docmgr.hxx"
42#include "tdoc_provider.hxx"
43
44using namespace com::sun::star;
45using namespace tdoc_ucp;
46
47// OfficeDocumentsCloseListener Implementation.
48
49
50// util::XCloseListener
51
52
53// virtual
54void SAL_CALL OfficeDocumentsManager::OfficeDocumentsCloseListener::queryClosing(
55 const lang::EventObject& /*Source*/, sal_Bool /*GetsOwnership*/ )
56{
57}
58
59
61 const lang::EventObject& Source )
62{
63 if (!m_pManager) return; // disposed?
64
65 document::DocumentEvent aDocEvent;
66 aDocEvent.Source = Source.Source;
67 aDocEvent.EventName = "OfficeDocumentsListener::notifyClosing";
68 m_pManager->documentEventOccured( aDocEvent );
69}
70
71
72// lang::XDocumentEventListener (base of util::XCloseListener)
73
74
75// virtual
77 const lang::EventObject& /*Source*/ )
78{
79}
80
81
82// OfficeDocumentsManager Implementation.
83
84
86 const uno::Reference< uno::XComponentContext > & rxContext,
87 ContentProvider * pDocEventListener )
88: m_xContext( rxContext ),
89 m_xDocEvtNotifier( frame::theGlobalEventBroadcaster::get( rxContext ) ),
90 m_pDocEventListener( pDocEventListener ),
92{
93 // Order is important (multithreaded environment)
94 uno::Reference< document::XDocumentEventBroadcaster >(
95 m_xDocEvtNotifier, uno::UNO_QUERY_THROW )->addDocumentEventListener( this );
97}
98
99
100// virtual
102{
103 //OSL_ENSURE( m_aDocs.empty(), "document list not empty!" );
104 // no need to assert this: Normal shutdown of LibreOffice could already trigger it, since the order
105 // in which objects are actually released/destroyed upon shutdown is not defined. And when we
106 // arrive *here*, LibreOffice *is* shutting down currently, since we're held by the TDOC provider,
107 // which is disposed upon shutdown.
108 m_xDocCloseListener->Dispose();
109}
110
111
113{
114 uno::Reference< document::XDocumentEventBroadcaster >(
115 m_xDocEvtNotifier, uno::UNO_QUERY_THROW )->removeDocumentEventListener( this );
116}
117
118
119static OUString
120getDocumentId( const uno::Reference< uno::XInterface > & xDoc )
121{
122 OUString aId;
123
124 // Try to get the UID directly from the document.
125 uno::Reference< beans::XPropertySet > xPropSet( xDoc, uno::UNO_QUERY );
126 if ( xPropSet.is() )
127 {
128 try
129 {
130 uno::Any aValue = xPropSet->getPropertyValue("RuntimeUID");
131 aValue >>= aId;
132 }
133 catch ( beans::UnknownPropertyException const & )
134 {
135 // Not actually an error. Property is optional.
136 }
137 catch ( lang::WrappedTargetException const & )
138 {
139 TOOLS_WARN_EXCEPTION("ucb.ucp", "Caught WrappedTargetException!");
140 }
141 }
142
143 if ( aId.isEmpty() )
144 {
145 // fallback: generate UID from document's this pointer.
146 // normalize the interface pointer first. Else, calls with different
147 // interfaces to the same object (say, XFoo and XBar) will produce
148 // different IDs
149 uno::Reference< uno::XInterface > xNormalizedIFace( xDoc, uno::UNO_QUERY );
150 sal_Int64 nId = reinterpret_cast< sal_Int64 >( xNormalizedIFace.get() );
151 aId = OUString::number( nId );
152 }
153
154 OSL_ENSURE( !aId.isEmpty(), "getDocumentId - Empty id!" );
155 return aId;
156}
157
158
159// document::XDocumentEventListener
160
161
162// virtual
164 const document::DocumentEvent & Event )
165{
166/*
167 Events documentation: OOo Developer's Guide / Writing UNO Components /
168 Integrating Components into OpenOffice.org / Jobs
169*/
170
171 if ( Event.EventName == "OnLoadFinished" // document loaded
172 || Event.EventName == "OnCreate" ) // document created
173 {
174 if ( isOfficeDocument( Event.Source ) )
175 {
176 uno::Reference<frame::XModel> const xModel(
177 Event.Source, uno::UNO_QUERY );
178 OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
179
180 bool found(false);
181
182 {
183 std::scoped_lock aGuard( m_aMtx );
184
185 found = std::any_of(m_aDocs.begin(), m_aDocs.end(),
186 [&xModel](const DocumentList::value_type& rEntry) { return rEntry.second.xModel == xModel; });
187 }
188
189 if (!found)
190 {
191 // no mutex to avoid deadlocks!
192 // need no lock to access const members, ContentProvider is safe
193
194 // new document
195
196 uno::Reference< document::XStorageBasedDocument >
197 xDoc( Event.Source, uno::UNO_QUERY );
198 OSL_ENSURE( xDoc.is(), "Got no document::XStorageBasedDocument!" );
199
200 uno::Reference< embed::XStorage > xStorage
201 = xDoc->getDocumentStorage();
202 OSL_ENSURE( xStorage.is(), "Got no document storage!" );
203
204 rtl:: OUString aDocId = getDocumentId( Event.Source );
205 rtl:: OUString aTitle = comphelper::DocumentInfo::getDocumentTitle(
206 uno::Reference< frame::XModel >( Event.Source, uno::UNO_QUERY ) );
207
208 {
209 std::scoped_lock g(m_aMtx);
210 m_aDocs[ aDocId ] = StorageInfo( aTitle, xStorage, xModel );
211 }
212
213 uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster(
214 Event.Source, uno::UNO_QUERY );
215 OSL_ENSURE( xCloseBroadcaster.is(),
216 "OnLoadFinished/OnCreate event: got no close broadcaster!" );
217
218 if ( xCloseBroadcaster.is() )
219 xCloseBroadcaster->addCloseListener(m_xDocCloseListener);
220
221 // Propagate document closure.
222 OSL_ENSURE( m_pDocEventListener,
223 "OnLoadFinished/OnCreate event: no owner for insert event propagation!" );
224
227 }
228 }
229 }
230 else if ( Event.EventName == "OfficeDocumentsListener::notifyClosing" )
231 {
232 if ( isOfficeDocument( Event.Source ) )
233 {
234 // Document has been closed (unloaded)
235
236 // Official event "OnUnload" does not work here. Event
237 // gets fired too early. Other OnUnload listeners called after this
238 // listener may still need TDOC access to the document. Remove the
239 // document from TDOC docs list on XCloseListener::notifyClosing.
240 // See OfficeDocumentsManager::OfficeDocumentsListener::notifyClosing.
241
242 uno::Reference< frame::XModel >
243 xModel( Event.Source, uno::UNO_QUERY );
244 OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
245
246 bool found(false);
247 OUString aDocId;
248
249 {
250 std::scoped_lock aGuard( m_aMtx );
251
252 auto it = std::find_if(m_aDocs.begin(), m_aDocs.end(),
253 [&xModel](const DocumentList::value_type& rEntry) { return rEntry.second.xModel == xModel; });
254 if ( it != m_aDocs.end() )
255 {
256 aDocId = (*it).first;
257 found = true;
258 m_aDocs.erase( it );
259 }
260 }
261
262 OSL_ENSURE( found,
263 "OnUnload event notified for unknown document!" );
264
265 if (found)
266 {
267 // Propagate document closure.
268 OSL_ENSURE( m_pDocEventListener,
269 "OnUnload event: no owner for close event propagation!" );
271 {
273 }
274 uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster(
275 Event.Source, uno::UNO_QUERY );
276 OSL_ENSURE( xCloseBroadcaster.is(),
277 "OnUnload event: got no XCloseBroadcaster from XModel" );
278 if ( xCloseBroadcaster.is() )
279 xCloseBroadcaster->removeCloseListener(m_xDocCloseListener);
280 }
281 }
282 }
283 else if ( Event.EventName == "OnSaveDone" )
284 {
285 if ( isOfficeDocument( Event.Source ) )
286 {
287 // Storage gets exchanged while saving.
288 uno::Reference<document::XStorageBasedDocument> const xDoc(
289 Event.Source, uno::UNO_QUERY );
290 OSL_ENSURE( xDoc.is(),
291 "Got no document::XStorageBasedDocument!" );
292 uno::Reference<embed::XStorage> const xStorage(
293 xDoc->getDocumentStorage());
294 OSL_ENSURE( xStorage.is(), "Got no document storage!" );
295
296 uno::Reference< frame::XModel >
297 xModel( Event.Source, uno::UNO_QUERY );
298 OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
299
300 std::scoped_lock aGuard( m_aMtx );
301
302 DocumentList::iterator it = std::find_if(m_aDocs.begin(), m_aDocs.end(),
303 [&xModel](const DocumentList::value_type& rEntry) { return rEntry.second.xModel == xModel; });
304
305 OSL_ENSURE( it != m_aDocs.end(),
306 "OnSaveDone event notified for unknown document!" );
307 if ( it != m_aDocs.end() )
308 {
309 (*it).second.xStorage = xStorage;
310 }
311 }
312 }
313 else if ( Event.EventName == "OnSaveAsDone" )
314 {
315 if ( isOfficeDocument( Event.Source ) )
316 {
317 // Storage gets exchanged while saving.
318 uno::Reference<document::XStorageBasedDocument> const xDoc(
319 Event.Source, uno::UNO_QUERY );
320 OSL_ENSURE( xDoc.is(),
321 "Got no document::XStorageBasedDocument!" );
322 uno::Reference<embed::XStorage> const xStorage(
323 xDoc->getDocumentStorage());
324 OSL_ENSURE( xStorage.is(), "Got no document storage!" );
325
326 uno::Reference< frame::XModel >
327 xModel( Event.Source, uno::UNO_QUERY );
328 OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
329
331
332 std::scoped_lock aGuard( m_aMtx );
333
334 DocumentList::iterator it = std::find_if(m_aDocs.begin(), m_aDocs.end(),
335 [&xModel](const DocumentList::value_type& rEntry) { return rEntry.second.xModel == xModel; });
336
337 OSL_ENSURE( it != m_aDocs.end(),
338 "OnSaveAsDone event notified for unknown document!" );
339 if ( it != m_aDocs.end() )
340 {
341 (*it).second.xStorage = xStorage;
342
343 // Adjust title.
344 (*it).second.aTitle = title;
345 }
346 }
347 }
348 else if ( Event.EventName == "OnTitleChanged"
349 || Event.EventName == "OnStorageChanged" )
350 {
351 if ( isOfficeDocument( Event.Source ) )
352 {
353 // Storage gets exchanged while saving.
354 uno::Reference<document::XStorageBasedDocument> const xDoc(
355 Event.Source, uno::UNO_QUERY );
356 OSL_ENSURE( xDoc.is(),
357 "Got no document::XStorageBasedDocument!" );
358 uno::Reference<embed::XStorage> const xStorage(
359 xDoc->getDocumentStorage());
360 OSL_ENSURE( xStorage.is(), "Got no document storage!" );
361
362 uno::Reference< frame::XModel >
363 xModel( Event.Source, uno::UNO_QUERY );
364 OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
365
367
368 OUString const aDocId(getDocumentId(Event.Source));
369
370 std::scoped_lock aGuard( m_aMtx );
371
372 DocumentList::iterator it = std::find_if(m_aDocs.begin(), m_aDocs.end(),
373 [&xModel](const DocumentList::value_type& rEntry) { return rEntry.second.xModel == xModel; });
374 if ( it != m_aDocs.end() )
375 {
376 // Adjust title.
377 (*it).second.aTitle = aTitle;
378
379 m_aDocs[ aDocId ] = StorageInfo( aTitle, xStorage, xModel );
380 }
381
382// OSL_ENSURE( it != m_aDocs.end(),
383// "TitleChanged event notified for unknown document!" );
384 // TODO: re-enable this assertion. It has been disabled for now, since it breaks the assertion-free smoketest,
385 // and the fix is more difficult than what can be done now.
386 // The problem is that at the moment, when you close a SFX-based document via API, it will first
387 // fire the notifyClosing event, which will make the OfficeDocumentsManager remove the doc from its list.
388 // Then, it will notify an OnTitleChanged, then an OnUnload. Documents closed via call the notifyClosing
389 // *after* OnUnload and all other On* events.
390 // In agreement with MBA, the implementation for SfxBaseModel::Close should be changed to also send notifyClosing
391 // as last event. When this happens, the assertion here must be enabled, again.
392 }
393 }
394}
395
396// lang::XDocumentEventListener (base of document::XDocumentEventListener)
397
398// virtual
400 const lang::EventObject& /*Source*/ )
401{
402}
403
404// Non-interface.
405
407{
408 uno::Reference< container::XEnumeration > xEnum
409 = m_xDocEvtNotifier->createEnumeration();
410
411 while ( xEnum->hasMoreElements() )
412 {
413 uno::Any aValue = xEnum->nextElement();
414 // container::NoSuchElementException
415 // lang::WrappedTargetException
416
417 try
418 {
419 uno::Reference< frame::XModel > xModel;
420 aValue >>= xModel;
421
422 if ( xModel.is() )
423 {
424 if ( isOfficeDocument( xModel ) )
425 {
426 bool found(false);
427
428 {
429 std::scoped_lock aGuard( m_aMtx );
430
431 found = std::any_of(m_aDocs.begin(), m_aDocs.end(),
432 [&xModel](const DocumentList::value_type& rEntry) { return rEntry.second.xModel == xModel; });
433 }
434
435 if (!found)
436 {
437 // new document
438 OUString aDocId = getDocumentId( xModel );
440
441 uno::Reference< document::XStorageBasedDocument >
442 xDoc( xModel, uno::UNO_QUERY );
443 OSL_ENSURE( xDoc.is(),
444 "Got no document::XStorageBasedDocument!" );
445
446 uno::Reference< embed::XStorage > xStorage
447 = xDoc->getDocumentStorage();
448 OSL_ENSURE( xStorage.is(), "Got no document storage!" );
449
450 {
451 std::scoped_lock aGuard( m_aMtx );
452 m_aDocs[ aDocId ]
453 = StorageInfo( aTitle, xStorage, xModel );
454 }
455
456 uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster(
457 xModel, uno::UNO_QUERY );
458 OSL_ENSURE( xCloseBroadcaster.is(),
459 "buildDocumentsList: got no close broadcaster!" );
460
461 if ( xCloseBroadcaster.is() )
462 xCloseBroadcaster->addCloseListener(m_xDocCloseListener);
463 }
464 }
465 }
466 }
467 catch ( lang::DisposedException const & )
468 {
469 // Note: Due to race conditions the XEnumeration can
470 // contain docs that have already been closed
471 }
472 catch ( lang::NotInitializedException const & )
473 {
474 // Note: Due to race conditions the XEnumeration can
475 // contain docs that are still uninitialized
476 }
477 }
478}
479
480uno::Reference< embed::XStorage >
481OfficeDocumentsManager::queryStorage( const OUString & rDocId )
482{
483 std::scoped_lock aGuard( m_aMtx );
484
485 DocumentList::const_iterator it = m_aDocs.find( rDocId );
486 if ( it == m_aDocs.end() )
487 return uno::Reference< embed::XStorage >();
488
489 return (*it).second.xStorage;
490}
491
492
494 const uno::Reference< frame::XModel > & xModel )
495{
496 return getDocumentId( xModel );
497}
498
499
500uno::Reference< frame::XModel >
502{
503 std::scoped_lock aGuard( m_aMtx );
504
505 DocumentList::const_iterator it = m_aDocs.find( rDocId );
506 if ( it == m_aDocs.end() )
507 return uno::Reference< frame::XModel >();
508
509 return (*it).second.xModel;
510}
511
512
513uno::Sequence< OUString > OfficeDocumentsManager::queryDocuments()
514{
515 std::scoped_lock aGuard( m_aMtx );
516
518}
519
520
521OUString
523{
524 std::scoped_lock aGuard( m_aMtx );
525
526 DocumentList::const_iterator it = m_aDocs.find( rDocId );
527 if ( it == m_aDocs.end() )
528 return OUString();
529
530 return (*it).second.aTitle;
531}
532
533
534css::util::DateTime OfficeDocumentsManager::queryStreamDateModified(OUString const & uri) {
535 std::scoped_lock g(m_aMtx);
536 auto const i1 = m_aDocs.find(Uri(uri).getDocumentId());
537 if (i1 != m_aDocs.end()) {
538 auto const i2 = i1->second.streamDateModified.find(uri);
539 if (i2 != i1->second.streamDateModified.end()) {
540 return i2->second;
541 }
542 }
543 return {};
544}
545
546
548 std::scoped_lock g(m_aMtx);
549 auto const i = m_aDocs.find(Uri(uri).getDocumentId());
550 if (i == m_aDocs.end()) {
551 SAL_WARN("ucb.ucp.tdoc", "No document info for <" << uri << ">");
552 return;
553 }
554 i->second.streamDateModified[uri] = DateTime(DateTime::SYSTEM).GetUNODateTime();
555}
556
557
559 const uno::Reference< frame::XModel > & xModel )
560{
561 if ( !xModel.is() )
562 return false;
563
564 bool bIsPreview = ::comphelper::NamedValueCollection::getOrDefault( xModel->getArgs(), u"Preview", false );
565 return bIsPreview;
566}
567
568
570 const uno::Reference< frame::XModel > & xModel )
571{
572 if ( !xModel.is() )
573 return false;
574
575 OUString sURL( xModel->getURL() );
576 return sURL.match( "vnd.sun.star.help://" );
577}
578
579
581 const uno::Reference< frame::XModel > & xModel )
582{
583 if ( !xModel.is() )
584 return false;
585
586 uno::Reference< frame::XController > xController
587 = xModel->getCurrentController();
588 if ( xController.is() )
589 {
590 uno::Reference< frame::XFrame > xFrame
591 = xController->getFrame();
592 if ( xFrame.is() )
593 {
594 // don't use XFrame::isTop here. This nowadays excludes
595 // "sub documents" such as forms embedded in database documents
596 uno::Reference< awt::XTopWindow > xFrameContainer(
597 xFrame->getContainerWindow(), uno::UNO_QUERY );
598 if ( !xFrameContainer.is() )
599 return false;
600 }
601 }
602
603 return true;
604}
605
606
608 const uno::Reference< frame::XModel > & xModel )
609{
610 if ( !m_xModuleMgr.is() )
611 {
612 std::scoped_lock aGuard( m_aMtx );
613 if ( !m_xModuleMgr.is() )
614 {
615 try
616 {
617 m_xModuleMgr = frame::ModuleManager::create( m_xContext );
618 }
619 catch ( uno::Exception const & )
620 {
621 // handled below.
622 }
623
624 OSL_ENSURE( m_xModuleMgr .is(),
625 "Could not instantiate ModuleManager service!" );
626 }
627 }
628
629 if ( m_xModuleMgr.is() )
630 {
631 OUString aModule;
632 try
633 {
634 aModule = m_xModuleMgr->identify( xModel );
635 }
636 catch ( lang::IllegalArgumentException const & )
637 {
638 TOOLS_WARN_EXCEPTION("ucb.ucp", "");
639 }
640 catch ( frame::UnknownModuleException const & )
641 {
642 TOOLS_WARN_EXCEPTION("ucb.ucp", "");
643 }
644
645 if ( !aModule.isEmpty() )
646 {
647 // Filter unwanted items, that are no real documents.
648 if ( aModule == "com.sun.star.script.BasicIDE" )
649 {
650 return true;
651 }
652 }
653 }
654
655 return false;
656}
657
658
660 const uno::Reference< uno::XInterface > & xDoc )
661{
662 uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY );
663 uno::Reference< document::XStorageBasedDocument >
664 xStorageBasedDoc( xModel, uno::UNO_QUERY );
665 if ( !xStorageBasedDoc.is() )
666 return false;
667
669 return false;
670
671 if ( isDocumentPreview( xModel ) )
672 return false;
673
674 if ( isHelpDocument( xModel ) )
675 return false;
676
677 if ( isBasicIDE( xModel ) )
678 return false;
679
680 return true;
681}
682
683/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::util::DateTime GetUNODateTime() const
VALUE_TYPE getOrDefault(const OUString &_rValueName, const VALUE_TYPE &_rDefault) const
void notifyDocumentOpened(std::u16string_view rDocId)
void notifyDocumentClosed(std::u16string_view rDocId)
virtual void SAL_CALL notifyClosing(const css::lang::EventObject &Source) override
Definition: tdoc_docmgr.cxx:60
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
Definition: tdoc_docmgr.cxx:76
css::uno::Sequence< OUString > queryDocuments()
static bool isDocumentPreview(const css::uno::Reference< css::frame::XModel > &xModel)
virtual void SAL_CALL documentEventOccured(const css::document::DocumentEvent &Event) override
bool isBasicIDE(const css::uno::Reference< css::frame::XModel > &xModel)
ContentProvider *const m_pDocEventListener
OUString queryStorageTitle(const OUString &rDocId)
OfficeDocumentsManager(const css::uno::Reference< css::uno::XComponentContext > &rxContext, ContentProvider *pDocEventListener)
Definition: tdoc_docmgr.cxx:85
css::uno::Reference< css::frame::XModuleManager2 > m_xModuleMgr
css::uno::Reference< css::frame::XModel > queryDocumentModel(const OUString &rDocId)
static OUString queryDocumentId(const css::uno::Reference< css::frame::XModel > &xModel)
virtual ~OfficeDocumentsManager() override
css::uno::Reference< css::frame::XGlobalEventBroadcaster > m_xDocEvtNotifier
void updateStreamDateModified(OUString const &uri)
bool isOfficeDocument(const css::uno::Reference< css::uno::XInterface > &xDoc)
css::util::DateTime queryStreamDateModified(OUString const &uri)
css::uno::Reference< css::embed::XStorage > queryStorage(const OUString &rDocId)
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
static bool isHelpDocument(const css::uno::Reference< css::frame::XModel > &xModel)
css::uno::Reference< css::uno::XComponentContext > m_xContext
::rtl::Reference< OfficeDocumentsCloseListener > const m_xDocCloseListener
static bool isWithoutOrInTopLevelFrame(const css::uno::Reference< css::frame::XModel > &xModel)
#define TOOLS_WARN_EXCEPTION(area, stream)
float u
#define SAL_WARN(area, stream)
COMPHELPER_DLLPUBLIC OUString getDocumentTitle(const css::uno::Reference< css::frame::XModel > &_rxDocument)
css::uno::Sequence< typename M::key_type > mapKeysToSequence(M const &map)
int i
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
sal_Int16 nId
Reference< XController > xController
Reference< XFrame > xFrame
Reference< XModel > xModel
static OUString getDocumentId(const uno::Reference< uno::XInterface > &xDoc)
ToolBarManager * m_pManager
unsigned char sal_Bool