Line data Source code
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 : /**************************************************************************
22 : TODO
23 : **************************************************************************
24 :
25 : *************************************************************************/
26 :
27 : #include "osl/diagnose.h"
28 : #include "rtl/ref.hxx"
29 : #include "cppuhelper/weak.hxx"
30 :
31 : #include "comphelper/documentinfo.hxx"
32 : #include "comphelper/namedvaluecollection.hxx"
33 :
34 : #include "com/sun/star/awt/XTopWindow.hpp"
35 : #include "com/sun/star/beans/XPropertySet.hpp"
36 : #include "com/sun/star/document/XDocumentEventBroadcaster.hpp"
37 : #include "com/sun/star/document/XStorageBasedDocument.hpp"
38 : #include "com/sun/star/frame/theGlobalEventBroadcaster.hpp"
39 : #include "com/sun/star/frame/XStorable.hpp"
40 : #include "com/sun/star/frame/ModuleManager.hpp"
41 : #include "com/sun/star/lang/DisposedException.hpp"
42 : #include "com/sun/star/util/XCloseBroadcaster.hpp"
43 :
44 : #include "tdoc_docmgr.hxx"
45 :
46 : using namespace com::sun::star;
47 : using namespace tdoc_ucp;
48 : using ::comphelper::DocumentInfo;
49 :
50 :
51 :
52 :
53 : // OfficeDocumentsCloseListener Implementation.
54 :
55 :
56 :
57 :
58 :
59 :
60 : // util::XCloseListener
61 :
62 :
63 :
64 : // virtual
65 1409 : void SAL_CALL OfficeDocumentsManager::OfficeDocumentsCloseListener::queryClosing(
66 : const lang::EventObject& /*Source*/, sal_Bool /*GetsOwnership*/ )
67 : throw ( util::CloseVetoException,
68 : uno::RuntimeException, std::exception )
69 : {
70 1409 : }
71 :
72 :
73 1409 : void SAL_CALL OfficeDocumentsManager::OfficeDocumentsCloseListener::notifyClosing(
74 : const lang::EventObject& Source )
75 : throw ( uno::RuntimeException, std::exception )
76 : {
77 1409 : document::DocumentEvent aDocEvent;
78 1409 : aDocEvent.Source = Source.Source;
79 1409 : aDocEvent.EventName = "OfficeDocumentsListener::notifyClosing";
80 1409 : m_pManager->documentEventOccured( aDocEvent );
81 1409 : }
82 :
83 :
84 :
85 : // lang::XDocumentEventListener (base of util::XCloseListener)
86 :
87 :
88 :
89 : // virtual
90 6 : void SAL_CALL OfficeDocumentsManager::OfficeDocumentsCloseListener::disposing(
91 : const lang::EventObject& /*Source*/ )
92 : throw ( uno::RuntimeException, std::exception )
93 : {
94 6 : }
95 :
96 :
97 :
98 :
99 : // OfficeDocumentsManager Implementation.
100 :
101 :
102 :
103 :
104 96 : OfficeDocumentsManager::OfficeDocumentsManager(
105 : const uno::Reference< uno::XComponentContext > & rxContext,
106 : OfficeDocumentsEventListener * pDocEventListener )
107 : : m_xContext( rxContext ),
108 : m_xDocEvtNotifier( frame::theGlobalEventBroadcaster::get( rxContext ) ),
109 : m_pDocEventListener( pDocEventListener ),
110 96 : m_xDocCloseListener( new OfficeDocumentsCloseListener( this ) )
111 : {
112 : // Order is important (multithreaded environment)
113 : uno::Reference< document::XDocumentEventBroadcaster >(
114 96 : m_xDocEvtNotifier, uno::UNO_QUERY_THROW )->addDocumentEventListener( this );
115 96 : buildDocumentsList();
116 96 : }
117 :
118 :
119 : // virtual
120 184 : OfficeDocumentsManager::~OfficeDocumentsManager()
121 : {
122 : //OSL_ENSURE( m_aDocs.empty(), "document list not empty!" );
123 : // no need to assert this: Normal shutdown of OOo could already trigger it, since the order in which
124 : // objects are actually released/destroyed upon shutdown is not defined. And when we arrive *here*,
125 : // OOo *is* shutting down currently, since we're held by the TDOC provider, which is disposed
126 : // upon shutdown.
127 184 : }
128 :
129 :
130 92 : void OfficeDocumentsManager::destroy()
131 : {
132 : uno::Reference< document::XDocumentEventBroadcaster >(
133 92 : m_xDocEvtNotifier, uno::UNO_QUERY_THROW )->removeDocumentEventListener( this );
134 92 : }
135 :
136 :
137 : static OUString
138 4149 : getDocumentId( const uno::Reference< uno::XInterface > & xDoc )
139 : {
140 4149 : OUString aId;
141 :
142 : // Try to get the UID directly from the document.
143 8298 : uno::Reference< beans::XPropertySet > xPropSet( xDoc, uno::UNO_QUERY );
144 4149 : if ( xPropSet.is() )
145 : {
146 : try
147 : {
148 4129 : uno::Any aValue = xPropSet->getPropertyValue(
149 4129 : OUString( "RuntimeUID" ) );
150 4129 : aValue >>= aId;
151 : }
152 0 : catch ( beans::UnknownPropertyException const & )
153 : {
154 : // Not actually an error. Property is optional.
155 : }
156 0 : catch ( lang::WrappedTargetException const & )
157 : {
158 : OSL_FAIL( "Caught WrappedTargetException!" );
159 : }
160 : }
161 :
162 4149 : if ( aId.isEmpty() )
163 : {
164 : // fallback: generate UID from document's this pointer.
165 : // normalize the interface pointer first. Else, calls with different
166 : // interfaces to the same object (say, XFoo and XBar) will produce
167 : // different IDs
168 20 : uno::Reference< uno::XInterface > xNormalizedIFace( xDoc, uno::UNO_QUERY );
169 20 : sal_Int64 nId = reinterpret_cast< sal_Int64 >( xNormalizedIFace.get() );
170 20 : aId = OUString::number( nId );
171 : }
172 :
173 : OSL_ENSURE( !aId.isEmpty(), "getDocumentId - Empty id!" );
174 8298 : return aId;
175 : }
176 :
177 :
178 :
179 : // document::XDocumentEventListener
180 :
181 :
182 :
183 : // virtual
184 13118 : void SAL_CALL OfficeDocumentsManager::documentEventOccured(
185 : const document::DocumentEvent & Event )
186 : throw ( uno::RuntimeException, std::exception )
187 : {
188 : /*
189 : Events documentation: OOo Developer's Guide / Writing UNO Components / Jobs
190 : */
191 :
192 26236 : if ( Event.EventName == "OnLoadFinished" // document loaded
193 13118 : || Event.EventName == "OnCreate" ) // document created
194 : {
195 1409 : if ( isOfficeDocument( Event.Source ) )
196 : {
197 1409 : osl::MutexGuard aGuard( m_aMtx );
198 :
199 : uno::Reference< frame::XModel >
200 2818 : xModel( Event.Source, uno::UNO_QUERY );
201 : OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
202 :
203 1409 : DocumentList::const_iterator it = m_aDocs.begin();
204 3046 : while ( it != m_aDocs.end() )
205 : {
206 234 : if ( (*it).second.xModel == xModel )
207 : {
208 : // already known.
209 6 : break;
210 : }
211 228 : ++it;
212 : }
213 :
214 1409 : if ( it == m_aDocs.end() )
215 : {
216 : // new document
217 :
218 : uno::Reference< document::XStorageBasedDocument >
219 1403 : xDoc( Event.Source, uno::UNO_QUERY );
220 : OSL_ENSURE( xDoc.is(), "Got no document::XStorageBasedDocument!" );
221 :
222 : uno::Reference< embed::XStorage > xStorage
223 2806 : = xDoc->getDocumentStorage();
224 : OSL_ENSURE( xStorage.is(), "Got no document storage!" );
225 :
226 2806 : rtl:: OUString aDocId = getDocumentId( Event.Source );
227 : rtl:: OUString aTitle = DocumentInfo::getDocumentTitle(
228 2806 : uno::Reference< frame::XModel >( Event.Source, uno::UNO_QUERY ) );
229 :
230 1403 : m_aDocs[ aDocId ] = StorageInfo( aTitle, xStorage, xModel );
231 :
232 : uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster(
233 2806 : Event.Source, uno::UNO_QUERY );
234 : OSL_ENSURE( xCloseBroadcaster.is(),
235 : "OnLoadFinished/OnCreate event: got no close broadcaster!" );
236 :
237 1403 : if ( xCloseBroadcaster.is() )
238 1403 : xCloseBroadcaster->addCloseListener( m_xDocCloseListener );
239 :
240 : // Propagate document closure.
241 : OSL_ENSURE( m_pDocEventListener,
242 : "OnLoadFinished/OnCreate event: no owner for insert event propagation!" );
243 :
244 1403 : if ( m_pDocEventListener )
245 2806 : m_pDocEventListener->notifyDocumentOpened( aDocId );
246 1409 : }
247 : }
248 : }
249 11709 : else if ( Event.EventName == "OfficeDocumentsListener::notifyClosing" )
250 : {
251 1409 : if ( isOfficeDocument( Event.Source ) )
252 : {
253 : // Document has been closed (unloaded)
254 :
255 : // #163732# - Official event "OnUnload" does not work here. Event
256 : // gets fired to early. Other OnUnload listeners called after this
257 : // listener may still need TDOC access to the document. Remove the
258 : // document from TDOC docs list on XCloseListener::notifyClosing.
259 : // See OfficeDocumentsManager::OfficeDocumentsListener::notifyClosing.
260 :
261 1409 : osl::MutexGuard aGuard( m_aMtx );
262 :
263 : uno::Reference< frame::XModel >
264 2818 : xModel( Event.Source, uno::UNO_QUERY );
265 : OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
266 :
267 1409 : DocumentList::iterator it = m_aDocs.begin();
268 2961 : while ( it != m_aDocs.end() )
269 : {
270 1552 : if ( (*it).second.xModel == xModel )
271 : {
272 : // Propagate document closure.
273 : OSL_ENSURE( m_pDocEventListener,
274 : "OnUnload event: no owner for close event propagation!" );
275 :
276 1409 : if ( m_pDocEventListener )
277 : {
278 1409 : OUString aDocId( (*it).first );
279 1409 : m_pDocEventListener->notifyDocumentClosed( aDocId );
280 : }
281 1409 : break;
282 : }
283 143 : ++it;
284 : }
285 :
286 : OSL_ENSURE( it != m_aDocs.end(),
287 : "OnUnload event notified for unknown document!" );
288 :
289 1409 : if ( it != m_aDocs.end() )
290 : {
291 : uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster(
292 1409 : Event.Source, uno::UNO_QUERY );
293 : OSL_ENSURE( xCloseBroadcaster.is(),
294 : "OnUnload event: got no XCloseBroadcaster from XModel" );
295 :
296 1409 : if ( xCloseBroadcaster.is() )
297 1409 : xCloseBroadcaster->removeCloseListener( m_xDocCloseListener );
298 :
299 1409 : m_aDocs.erase( it );
300 1409 : }
301 : }
302 : }
303 10300 : else if ( Event.EventName == "OnSaveDone" )
304 : {
305 6 : if ( isOfficeDocument( Event.Source ) )
306 : {
307 6 : osl::MutexGuard aGuard( m_aMtx );
308 :
309 : uno::Reference< frame::XModel >
310 12 : xModel( Event.Source, uno::UNO_QUERY );
311 : OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
312 :
313 6 : DocumentList::iterator it = m_aDocs.begin();
314 12 : while ( it != m_aDocs.end() )
315 : {
316 6 : if ( (*it).second.xModel == xModel )
317 : {
318 : // Storage gets exchanged while saving.
319 : uno::Reference< document::XStorageBasedDocument >
320 6 : xDoc( Event.Source, uno::UNO_QUERY );
321 : OSL_ENSURE( xDoc.is(),
322 : "Got no document::XStorageBasedDocument!" );
323 :
324 : uno::Reference< embed::XStorage > xStorage
325 12 : = xDoc->getDocumentStorage();
326 : OSL_ENSURE( xStorage.is(), "Got no document storage!" );
327 :
328 6 : (*it).second.xStorage = xStorage;
329 12 : break;
330 : }
331 0 : ++it;
332 : }
333 :
334 : OSL_ENSURE( it != m_aDocs.end(),
335 6 : "OnSaveDone event notified for unknown document!" );
336 : }
337 : }
338 10294 : else if ( Event.EventName == "OnSaveAsDone" )
339 : {
340 18 : if ( isOfficeDocument( Event.Source ) )
341 : {
342 18 : osl::MutexGuard aGuard( m_aMtx );
343 :
344 : uno::Reference< frame::XModel >
345 36 : xModel( Event.Source, uno::UNO_QUERY );
346 : OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
347 :
348 18 : DocumentList::iterator it = m_aDocs.begin();
349 56 : while ( it != m_aDocs.end() )
350 : {
351 38 : if ( (*it).second.xModel == xModel )
352 : {
353 : // Storage gets exchanged while saving.
354 : uno::Reference< document::XStorageBasedDocument >
355 18 : xDoc( Event.Source, uno::UNO_QUERY );
356 : OSL_ENSURE( xDoc.is(),
357 : "Got no document::XStorageBasedDocument!" );
358 :
359 : uno::Reference< embed::XStorage > xStorage
360 36 : = xDoc->getDocumentStorage();
361 : OSL_ENSURE( xStorage.is(), "Got no document storage!" );
362 :
363 18 : (*it).second.xStorage = xStorage;
364 :
365 : // Adjust title.
366 18 : (*it).second.aTitle = DocumentInfo::getDocumentTitle( xModel );
367 36 : break;
368 : }
369 20 : ++it;
370 : }
371 :
372 : OSL_ENSURE( it != m_aDocs.end(),
373 18 : "OnSaveAsDone event notified for unknown document!" );
374 : }
375 : }
376 10276 : else if ( Event.EventName == "OnTitleChanged" )
377 : {
378 3080 : if ( isOfficeDocument( Event.Source ) )
379 : {
380 3080 : osl::MutexGuard aGuard( m_aMtx );
381 :
382 : uno::Reference< frame::XModel >
383 6160 : xModel( Event.Source, uno::UNO_QUERY );
384 : OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
385 :
386 3080 : DocumentList::iterator it = m_aDocs.begin();
387 6684 : while ( it != m_aDocs.end() )
388 : {
389 2959 : if ( (*it).second.xModel == xModel )
390 : {
391 : // Adjust title.
392 2435 : rtl:: OUString aTitle = DocumentInfo::getDocumentTitle( xModel );
393 2435 : (*it).second.aTitle = aTitle;
394 :
395 : // Adjust storage.
396 : uno::Reference< document::XStorageBasedDocument >
397 4870 : xDoc( Event.Source, uno::UNO_QUERY );
398 : OSL_ENSURE( xDoc.is(), "Got no document::XStorageBasedDocument!" );
399 :
400 : uno::Reference< embed::XStorage > xStorage
401 4870 : = xDoc->getDocumentStorage();
402 : OSL_ENSURE( xDoc.is(), "Got no document storage!" );
403 :
404 4870 : rtl:: OUString aDocId = getDocumentId( Event.Source );
405 :
406 2435 : m_aDocs[ aDocId ] = StorageInfo( aTitle, xStorage, xModel );
407 4870 : break;
408 : }
409 524 : ++it;
410 3080 : }
411 :
412 : // OSL_ENSURE( it != m_aDocs.end(),
413 : // "TitleChanged event notified for unknown document!" );
414 : // TODO: re-enable this assertion. It has been disabled for now, since it breaks the assertion-free smoketest,
415 : // and the fix is more difficult than what can be done now.
416 : // The problem is that at the moment, when you close a SFX-based document via API, it will first
417 : // fire the notifyClosing event, which will make the OfficeDocumentsManager remove the doc from its list.
418 : // Then, it will notify an OnTitleChanged, then an OnUnload. Documents closed via call the notifyClosing
419 : // *after* OnUnload and all other On* events.
420 : // In agreement with MBA, the implementation for SfxBaseModel::Close should be changed to also send notifyClosing
421 : // as last event. When this happens, the assertion here must be enabled, again.
422 : // There is no bug for this, yet - IZ is currently down due to the Kenai migration.
423 : // 2011-02-23 / frank.schoenheit@sun.com
424 : }
425 : }
426 13118 : }
427 :
428 :
429 :
430 : // lang::XDocumentEventListener (base of document::XDocumentEventListener)
431 :
432 :
433 :
434 : // virtual
435 0 : void SAL_CALL OfficeDocumentsManager::disposing(
436 : const lang::EventObject& /*Source*/ )
437 : throw ( uno::RuntimeException, std::exception )
438 : {
439 0 : }
440 :
441 :
442 :
443 : // Non-interface.
444 :
445 :
446 :
447 96 : void OfficeDocumentsManager::buildDocumentsList()
448 : {
449 : uno::Reference< container::XEnumeration > xEnum
450 96 : = m_xDocEvtNotifier->createEnumeration();
451 :
452 192 : osl::MutexGuard aGuard( m_aMtx );
453 :
454 207 : while ( xEnum->hasMoreElements() )
455 : {
456 15 : uno::Any aValue = xEnum->nextElement();
457 : // container::NoSuchElementException
458 : // lang::WrappedTargetException
459 :
460 : try
461 : {
462 15 : uno::Reference< frame::XModel > xModel;
463 15 : aValue >>= xModel;
464 :
465 15 : if ( xModel.is() )
466 : {
467 15 : if ( isOfficeDocument( xModel ) )
468 : {
469 15 : DocumentList::const_iterator it = m_aDocs.begin();
470 34 : while ( it != m_aDocs.end() )
471 : {
472 4 : if ( (*it).second.xModel == xModel )
473 : {
474 : // already known.
475 0 : break;
476 : }
477 4 : ++it;
478 : }
479 :
480 15 : if ( it == m_aDocs.end() )
481 : {
482 : // new document
483 15 : OUString aDocId = getDocumentId( xModel );
484 30 : OUString aTitle = DocumentInfo::getDocumentTitle( xModel );
485 :
486 : uno::Reference< document::XStorageBasedDocument >
487 30 : xDoc( xModel, uno::UNO_QUERY );
488 : OSL_ENSURE( xDoc.is(),
489 : "Got no document::XStorageBasedDocument!" );
490 :
491 : uno::Reference< embed::XStorage > xStorage
492 30 : = xDoc->getDocumentStorage();
493 : OSL_ENSURE( xDoc.is(), "Got no document storage!" );
494 :
495 15 : m_aDocs[ aDocId ]
496 30 : = StorageInfo( aTitle, xStorage, xModel );
497 :
498 : uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster(
499 30 : xModel, uno::UNO_QUERY );
500 : OSL_ENSURE( xCloseBroadcaster.is(),
501 : "buildDocumentsList: got no close broadcaster!" );
502 :
503 15 : if ( xCloseBroadcaster.is() )
504 30 : xCloseBroadcaster->addCloseListener( m_xDocCloseListener );
505 : }
506 : }
507 15 : }
508 : }
509 0 : catch ( lang::DisposedException const & )
510 : {
511 : // Note: Due to race conditions the XEnumeration can
512 : // contains docs that already have been closed
513 : }
514 111 : }
515 96 : }
516 :
517 :
518 : uno::Reference< embed::XStorage >
519 624 : OfficeDocumentsManager::queryStorage( const OUString & rDocId )
520 : {
521 624 : osl::MutexGuard aGuard( m_aMtx );
522 :
523 624 : DocumentList::const_iterator it = m_aDocs.find( rDocId );
524 624 : if ( it == m_aDocs.end() )
525 0 : return uno::Reference< embed::XStorage >();
526 :
527 624 : return (*it).second.xStorage;
528 : }
529 :
530 :
531 296 : OUString OfficeDocumentsManager::queryDocumentId(
532 : const uno::Reference< frame::XModel > & xModel )
533 : {
534 296 : return getDocumentId( xModel );
535 : }
536 :
537 :
538 : uno::Reference< frame::XModel >
539 328 : OfficeDocumentsManager::queryDocumentModel( const OUString & rDocId )
540 : {
541 328 : osl::MutexGuard aGuard( m_aMtx );
542 :
543 328 : DocumentList::const_iterator it = m_aDocs.find( rDocId );
544 328 : if ( it == m_aDocs.end() )
545 0 : return uno::Reference< frame::XModel >();
546 :
547 328 : return (*it).second.xModel;
548 : }
549 :
550 :
551 0 : uno::Sequence< OUString > OfficeDocumentsManager::queryDocuments()
552 : {
553 0 : osl::MutexGuard aGuard( m_aMtx );
554 :
555 0 : uno::Sequence< OUString > aRet( m_aDocs.size() );
556 0 : sal_Int32 nPos = 0;
557 :
558 0 : DocumentList::const_iterator it = m_aDocs.begin();
559 0 : while ( it != m_aDocs.end() )
560 : {
561 0 : aRet[ nPos ] = (*it).first;
562 0 : ++it;
563 0 : ++nPos;
564 : }
565 0 : return aRet;
566 : }
567 :
568 :
569 : OUString
570 624 : OfficeDocumentsManager::queryStorageTitle( const OUString & rDocId )
571 : {
572 624 : osl::MutexGuard aGuard( m_aMtx );
573 :
574 624 : DocumentList::const_iterator it = m_aDocs.find( rDocId );
575 624 : if ( it == m_aDocs.end() )
576 0 : return OUString();
577 :
578 624 : return (*it).second.aTitle;
579 : }
580 :
581 :
582 5937 : bool OfficeDocumentsManager::isDocumentPreview(
583 : const uno::Reference< frame::XModel > & xModel )
584 : {
585 5937 : if ( !xModel.is() )
586 0 : return false;
587 :
588 : ::comphelper::NamedValueCollection aArgs(
589 5937 : xModel->getArgs() );
590 5937 : bool bIsPreview = aArgs.getOrDefault( "Preview", sal_False );
591 5937 : return bIsPreview;
592 : }
593 :
594 :
595 5937 : bool OfficeDocumentsManager::isHelpDocument(
596 : const uno::Reference< frame::XModel > & xModel )
597 : {
598 5937 : if ( !xModel.is() )
599 0 : return false;
600 :
601 5937 : OUString sURL( xModel->getURL() );
602 5937 : if ( sURL.match( "vnd.sun.star.help://" ) )
603 0 : return true;
604 :
605 5937 : return false;
606 : }
607 :
608 :
609 5937 : bool OfficeDocumentsManager::isWithoutOrInTopLevelFrame(
610 : const uno::Reference< frame::XModel > & xModel )
611 : {
612 5937 : if ( !xModel.is() )
613 0 : return false;
614 :
615 : uno::Reference< frame::XController > xController
616 5937 : = xModel->getCurrentController();
617 5937 : if ( xController.is() )
618 : {
619 : uno::Reference< frame::XFrame > xFrame
620 2468 : = xController->getFrame();
621 2468 : if ( xFrame.is() )
622 : {
623 : // don't use XFrame::isTop here. This nowadays excludes
624 : // "sub documents" such as forms embedded in database documents
625 : uno::Reference< awt::XTopWindow > xFrameContainer(
626 2466 : xFrame->getContainerWindow(), uno::UNO_QUERY );
627 2466 : if ( !xFrameContainer.is() )
628 0 : return false;
629 2468 : }
630 : }
631 :
632 5937 : return true;
633 : }
634 :
635 :
636 5937 : bool OfficeDocumentsManager::isBasicIDE(
637 : const uno::Reference< frame::XModel > & xModel )
638 : {
639 5937 : if ( !m_xModuleMgr.is() )
640 : {
641 90 : osl::MutexGuard aGuard( m_aMtx );
642 90 : if ( !m_xModuleMgr.is() )
643 : {
644 : try
645 : {
646 90 : m_xModuleMgr = frame::ModuleManager::create( m_xContext );
647 : }
648 0 : catch ( uno::Exception const & )
649 : {
650 : // handled below.
651 : }
652 :
653 : OSL_ENSURE( m_xModuleMgr .is(),
654 : "Could not instanciate ModuleManager service!" );
655 90 : }
656 : }
657 :
658 5937 : if ( m_xModuleMgr.is() )
659 : {
660 5937 : OUString aModule;
661 : try
662 : {
663 5937 : aModule = m_xModuleMgr->identify( xModel );
664 : }
665 0 : catch ( lang::IllegalArgumentException const & )
666 : {
667 : OSL_FAIL( "Caught IllegalArgumentException!" );
668 : }
669 0 : catch ( frame::UnknownModuleException const & )
670 : {
671 : OSL_FAIL( "Caught UnknownModuleException!" );
672 : }
673 :
674 5937 : if ( !aModule.isEmpty() )
675 : {
676 : // Filter unwanted items, that are no real documents.
677 5937 : if ( aModule == "com.sun.star.script.BasicIDE" )
678 : {
679 0 : return true;
680 : }
681 5937 : }
682 : }
683 :
684 5937 : return false;
685 : }
686 :
687 :
688 5937 : bool OfficeDocumentsManager::isOfficeDocument(
689 : const uno::Reference< uno::XInterface > & xDoc )
690 : {
691 5937 : uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY );
692 : uno::Reference< document::XStorageBasedDocument >
693 11874 : xStorageBasedDoc( xModel, uno::UNO_QUERY );
694 5937 : if ( !xStorageBasedDoc.is() )
695 0 : return false;
696 :
697 5937 : if ( !isWithoutOrInTopLevelFrame( xModel ) )
698 0 : return false;
699 :
700 5937 : if ( isDocumentPreview( xModel ) )
701 0 : return false;
702 :
703 5937 : if ( isHelpDocument( xModel ) )
704 0 : return false;
705 :
706 5937 : if ( isBasicIDE( xModel ) )
707 0 : return false;
708 :
709 11874 : return true;
710 : }
711 :
712 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|