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