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/XEventBroadcaster.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 0 : 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 0 : }
71 :
72 :
73 0 : void SAL_CALL OfficeDocumentsManager::OfficeDocumentsCloseListener::notifyClosing(
74 : const lang::EventObject& Source )
75 : throw ( uno::RuntimeException, std::exception )
76 : {
77 0 : document::EventObject aDocEvent;
78 0 : aDocEvent.Source = Source.Source;
79 0 : aDocEvent.EventName = "OfficeDocumentsListener::notifyClosing";
80 0 : m_pManager->notifyEvent( aDocEvent );
81 0 : }
82 :
83 :
84 :
85 : // lang::XEventListener (base of util::XCloseListener)
86 :
87 :
88 :
89 : // virtual
90 0 : void SAL_CALL OfficeDocumentsManager::OfficeDocumentsCloseListener::disposing(
91 : const lang::EventObject& /*Source*/ )
92 : throw ( uno::RuntimeException, std::exception )
93 : {
94 0 : }
95 :
96 :
97 :
98 :
99 : // OfficeDocumentsManager Implementation.
100 :
101 :
102 :
103 :
104 0 : 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 0 : m_xDocCloseListener( new OfficeDocumentsCloseListener( this ) )
111 : {
112 : // Order is important (multithreaded environment)
113 : uno::Reference< document::XEventBroadcaster >(
114 0 : m_xDocEvtNotifier, uno::UNO_QUERY_THROW )->addEventListener( this );
115 0 : buildDocumentsList();
116 0 : }
117 :
118 :
119 : // virtual
120 0 : 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 0 : }
128 :
129 :
130 0 : void OfficeDocumentsManager::destroy()
131 : {
132 : uno::Reference< document::XEventBroadcaster >(
133 0 : m_xDocEvtNotifier, uno::UNO_QUERY_THROW )->removeEventListener( this );
134 0 : }
135 :
136 :
137 : static OUString
138 0 : getDocumentId( const uno::Reference< uno::XInterface > & xDoc )
139 : {
140 0 : OUString aId;
141 :
142 : // Try to get the UID directly from the document.
143 0 : uno::Reference< beans::XPropertySet > xPropSet( xDoc, uno::UNO_QUERY );
144 0 : if ( xPropSet.is() )
145 : {
146 : try
147 : {
148 0 : uno::Any aValue = xPropSet->getPropertyValue(
149 0 : OUString( "RuntimeUID" ) );
150 0 : 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 0 : 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 0 : uno::Reference< uno::XInterface > xNormalizedIFace( xDoc, uno::UNO_QUERY );
169 0 : sal_Int64 nId = reinterpret_cast< sal_Int64 >( xNormalizedIFace.get() );
170 0 : aId = OUString::number( nId );
171 : }
172 :
173 : OSL_ENSURE( !aId.isEmpty(), "getDocumentId - Empty id!" );
174 0 : return aId;
175 : }
176 :
177 :
178 :
179 : // document::XEventListener
180 :
181 :
182 :
183 : // virtual
184 0 : void SAL_CALL OfficeDocumentsManager::notifyEvent(
185 : const document::EventObject & Event )
186 : throw ( uno::RuntimeException, std::exception )
187 : {
188 : /*
189 : Events documentation: OOo Developer's Guide / Writing UNO Components / Jobs
190 : */
191 :
192 0 : if ( Event.EventName == "OnLoadFinished" // document loaded
193 0 : || Event.EventName == "OnCreate" ) // document created
194 : {
195 0 : if ( isOfficeDocument( Event.Source ) )
196 : {
197 0 : osl::MutexGuard aGuard( m_aMtx );
198 :
199 : uno::Reference< frame::XModel >
200 0 : xModel( Event.Source, uno::UNO_QUERY );
201 : OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
202 :
203 0 : DocumentList::const_iterator it = m_aDocs.begin();
204 0 : while ( it != m_aDocs.end() )
205 : {
206 0 : if ( (*it).second.xModel == xModel )
207 : {
208 : // already known.
209 0 : break;
210 : }
211 0 : ++it;
212 : }
213 :
214 0 : if ( it == m_aDocs.end() )
215 : {
216 : // new document
217 :
218 : uno::Reference< document::XStorageBasedDocument >
219 0 : xDoc( Event.Source, uno::UNO_QUERY );
220 : OSL_ENSURE( xDoc.is(), "Got no document::XStorageBasedDocument!" );
221 :
222 : uno::Reference< embed::XStorage > xStorage
223 0 : = xDoc->getDocumentStorage();
224 : OSL_ENSURE( xStorage.is(), "Got no document storage!" );
225 :
226 0 : rtl:: OUString aDocId = getDocumentId( Event.Source );
227 : rtl:: OUString aTitle = DocumentInfo::getDocumentTitle(
228 0 : uno::Reference< frame::XModel >( Event.Source, uno::UNO_QUERY ) );
229 :
230 0 : m_aDocs[ aDocId ] = StorageInfo( aTitle, xStorage, xModel );
231 :
232 : uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster(
233 0 : Event.Source, uno::UNO_QUERY );
234 : OSL_ENSURE( xCloseBroadcaster.is(),
235 : "OnLoadFinished/OnCreate event: got no close broadcaster!" );
236 :
237 0 : if ( xCloseBroadcaster.is() )
238 0 : 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 0 : if ( m_pDocEventListener )
245 0 : m_pDocEventListener->notifyDocumentOpened( aDocId );
246 0 : }
247 : }
248 : }
249 0 : else if ( Event.EventName == "OfficeDocumentsListener::notifyClosing" )
250 : {
251 0 : 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 0 : osl::MutexGuard aGuard( m_aMtx );
262 :
263 : uno::Reference< frame::XModel >
264 0 : xModel( Event.Source, uno::UNO_QUERY );
265 : OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
266 :
267 0 : DocumentList::iterator it = m_aDocs.begin();
268 0 : while ( it != m_aDocs.end() )
269 : {
270 0 : 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 0 : if ( m_pDocEventListener )
277 : {
278 0 : OUString aDocId( (*it).first );
279 0 : m_pDocEventListener->notifyDocumentClosed( aDocId );
280 : }
281 0 : break;
282 : }
283 0 : ++it;
284 : }
285 :
286 : OSL_ENSURE( it != m_aDocs.end(),
287 : "OnUnload event notified for unknown document!" );
288 :
289 0 : if ( it != m_aDocs.end() )
290 : {
291 : uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster(
292 0 : Event.Source, uno::UNO_QUERY );
293 : OSL_ENSURE( xCloseBroadcaster.is(),
294 : "OnUnload event: got no XCloseBroadcaster from XModel" );
295 :
296 0 : if ( xCloseBroadcaster.is() )
297 0 : xCloseBroadcaster->removeCloseListener( m_xDocCloseListener );
298 :
299 0 : m_aDocs.erase( it );
300 0 : }
301 : }
302 : }
303 0 : else if ( Event.EventName == "OnSaveDone" )
304 : {
305 0 : if ( isOfficeDocument( Event.Source ) )
306 : {
307 0 : osl::MutexGuard aGuard( m_aMtx );
308 :
309 : uno::Reference< frame::XModel >
310 0 : xModel( Event.Source, uno::UNO_QUERY );
311 : OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
312 :
313 0 : DocumentList::iterator it = m_aDocs.begin();
314 0 : while ( it != m_aDocs.end() )
315 : {
316 0 : if ( (*it).second.xModel == xModel )
317 : {
318 : // Storage gets exchanged while saving.
319 : uno::Reference< document::XStorageBasedDocument >
320 0 : xDoc( Event.Source, uno::UNO_QUERY );
321 : OSL_ENSURE( xDoc.is(),
322 : "Got no document::XStorageBasedDocument!" );
323 :
324 : uno::Reference< embed::XStorage > xStorage
325 0 : = xDoc->getDocumentStorage();
326 : OSL_ENSURE( xStorage.is(), "Got no document storage!" );
327 :
328 0 : (*it).second.xStorage = xStorage;
329 0 : break;
330 : }
331 0 : ++it;
332 : }
333 :
334 : OSL_ENSURE( it != m_aDocs.end(),
335 0 : "OnSaveDone event notified for unknown document!" );
336 : }
337 : }
338 0 : else if ( Event.EventName == "OnSaveAsDone" )
339 : {
340 0 : if ( isOfficeDocument( Event.Source ) )
341 : {
342 0 : osl::MutexGuard aGuard( m_aMtx );
343 :
344 : uno::Reference< frame::XModel >
345 0 : xModel( Event.Source, uno::UNO_QUERY );
346 : OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
347 :
348 0 : DocumentList::iterator it = m_aDocs.begin();
349 0 : while ( it != m_aDocs.end() )
350 : {
351 0 : if ( (*it).second.xModel == xModel )
352 : {
353 : // Storage gets exchanged while saving.
354 : uno::Reference< document::XStorageBasedDocument >
355 0 : xDoc( Event.Source, uno::UNO_QUERY );
356 : OSL_ENSURE( xDoc.is(),
357 : "Got no document::XStorageBasedDocument!" );
358 :
359 : uno::Reference< embed::XStorage > xStorage
360 0 : = xDoc->getDocumentStorage();
361 : OSL_ENSURE( xStorage.is(), "Got no document storage!" );
362 :
363 0 : (*it).second.xStorage = xStorage;
364 :
365 : // Adjust title.
366 0 : (*it).second.aTitle = DocumentInfo::getDocumentTitle( xModel );
367 0 : break;
368 : }
369 0 : ++it;
370 : }
371 :
372 : OSL_ENSURE( it != m_aDocs.end(),
373 0 : "OnSaveAsDone event notified for unknown document!" );
374 : }
375 : }
376 0 : else if ( Event.EventName == "OnTitleChanged" )
377 : {
378 0 : if ( isOfficeDocument( Event.Source ) )
379 : {
380 0 : osl::MutexGuard aGuard( m_aMtx );
381 :
382 : uno::Reference< frame::XModel >
383 0 : xModel( Event.Source, uno::UNO_QUERY );
384 : OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
385 :
386 0 : DocumentList::iterator it = m_aDocs.begin();
387 0 : while ( it != m_aDocs.end() )
388 : {
389 0 : if ( (*it).second.xModel == xModel )
390 : {
391 : // Adjust title.
392 0 : rtl:: OUString aTitle = DocumentInfo::getDocumentTitle( xModel );
393 0 : (*it).second.aTitle = aTitle;
394 :
395 : // Adjust storage.
396 : uno::Reference< document::XStorageBasedDocument >
397 0 : xDoc( Event.Source, uno::UNO_QUERY );
398 : OSL_ENSURE( xDoc.is(), "Got no document::XStorageBasedDocument!" );
399 :
400 : uno::Reference< embed::XStorage > xStorage
401 0 : = xDoc->getDocumentStorage();
402 : OSL_ENSURE( xDoc.is(), "Got no document storage!" );
403 :
404 0 : rtl:: OUString aDocId = getDocumentId( Event.Source );
405 :
406 0 : m_aDocs[ aDocId ] = StorageInfo( aTitle, xStorage, xModel );
407 0 : break;
408 : }
409 0 : ++it;
410 0 : }
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 0 : }
427 :
428 :
429 :
430 : // lang::XEventListener (base of document::XEventListener)
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 0 : void OfficeDocumentsManager::buildDocumentsList()
448 : {
449 : uno::Reference< container::XEnumeration > xEnum
450 0 : = m_xDocEvtNotifier->createEnumeration();
451 :
452 0 : osl::MutexGuard aGuard( m_aMtx );
453 :
454 0 : while ( xEnum->hasMoreElements() )
455 : {
456 0 : uno::Any aValue = xEnum->nextElement();
457 : // container::NoSuchElementException
458 : // lang::WrappedTargetException
459 :
460 : try
461 : {
462 0 : uno::Reference< frame::XModel > xModel;
463 0 : aValue >>= xModel;
464 :
465 0 : if ( xModel.is() )
466 : {
467 0 : if ( isOfficeDocument( xModel ) )
468 : {
469 0 : DocumentList::const_iterator it = m_aDocs.begin();
470 0 : while ( it != m_aDocs.end() )
471 : {
472 0 : if ( (*it).second.xModel == xModel )
473 : {
474 : // already known.
475 0 : break;
476 : }
477 0 : ++it;
478 : }
479 :
480 0 : if ( it == m_aDocs.end() )
481 : {
482 : // new document
483 0 : OUString aDocId = getDocumentId( xModel );
484 0 : OUString aTitle = DocumentInfo::getDocumentTitle( xModel );
485 :
486 : uno::Reference< document::XStorageBasedDocument >
487 0 : xDoc( xModel, uno::UNO_QUERY );
488 : OSL_ENSURE( xDoc.is(),
489 : "Got no document::XStorageBasedDocument!" );
490 :
491 : uno::Reference< embed::XStorage > xStorage
492 0 : = xDoc->getDocumentStorage();
493 : OSL_ENSURE( xDoc.is(), "Got no document storage!" );
494 :
495 0 : m_aDocs[ aDocId ]
496 0 : = StorageInfo( aTitle, xStorage, xModel );
497 :
498 : uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster(
499 0 : xModel, uno::UNO_QUERY );
500 : OSL_ENSURE( xCloseBroadcaster.is(),
501 : "buildDocumentsList: got no close broadcaster!" );
502 :
503 0 : if ( xCloseBroadcaster.is() )
504 0 : xCloseBroadcaster->addCloseListener( m_xDocCloseListener );
505 : }
506 : }
507 0 : }
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 0 : }
515 0 : }
516 :
517 :
518 : uno::Reference< embed::XStorage >
519 0 : OfficeDocumentsManager::queryStorage( const OUString & rDocId )
520 : {
521 0 : osl::MutexGuard aGuard( m_aMtx );
522 :
523 0 : DocumentList::const_iterator it = m_aDocs.find( rDocId );
524 0 : if ( it == m_aDocs.end() )
525 0 : return uno::Reference< embed::XStorage >();
526 :
527 0 : return (*it).second.xStorage;
528 : }
529 :
530 :
531 0 : OUString OfficeDocumentsManager::queryDocumentId(
532 : const uno::Reference< frame::XModel > & xModel )
533 : {
534 0 : return getDocumentId( xModel );
535 : }
536 :
537 :
538 : uno::Reference< frame::XModel >
539 0 : OfficeDocumentsManager::queryDocumentModel( const OUString & rDocId )
540 : {
541 0 : osl::MutexGuard aGuard( m_aMtx );
542 :
543 0 : DocumentList::const_iterator it = m_aDocs.find( rDocId );
544 0 : if ( it == m_aDocs.end() )
545 0 : return uno::Reference< frame::XModel >();
546 :
547 0 : 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 0 : OfficeDocumentsManager::queryStorageTitle( const OUString & rDocId )
571 : {
572 0 : osl::MutexGuard aGuard( m_aMtx );
573 :
574 0 : DocumentList::const_iterator it = m_aDocs.find( rDocId );
575 0 : if ( it == m_aDocs.end() )
576 0 : return OUString();
577 :
578 0 : return (*it).second.aTitle;
579 : }
580 :
581 :
582 0 : bool OfficeDocumentsManager::isDocumentPreview(
583 : const uno::Reference< frame::XModel > & xModel )
584 : {
585 0 : if ( !xModel.is() )
586 0 : return false;
587 :
588 : ::comphelper::NamedValueCollection aArgs(
589 0 : xModel->getArgs() );
590 0 : sal_Bool bIsPreview = aArgs.getOrDefault( "Preview", sal_False );
591 0 : return bIsPreview;
592 : }
593 :
594 :
595 0 : bool OfficeDocumentsManager::isHelpDocument(
596 : const uno::Reference< frame::XModel > & xModel )
597 : {
598 0 : if ( !xModel.is() )
599 0 : return false;
600 :
601 0 : OUString sURL( xModel->getURL() );
602 0 : if ( sURL.match( "vnd.sun.star.help://" ) )
603 0 : return true;
604 :
605 0 : return false;
606 : }
607 :
608 :
609 0 : bool OfficeDocumentsManager::isWithoutOrInTopLevelFrame(
610 : const uno::Reference< frame::XModel > & xModel )
611 : {
612 0 : if ( !xModel.is() )
613 0 : return false;
614 :
615 : uno::Reference< frame::XController > xController
616 0 : = xModel->getCurrentController();
617 0 : if ( xController.is() )
618 : {
619 : uno::Reference< frame::XFrame > xFrame
620 0 : = xController->getFrame();
621 0 : 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 0 : xFrame->getContainerWindow(), uno::UNO_QUERY );
627 0 : if ( !xFrameContainer.is() )
628 0 : return false;
629 0 : }
630 : }
631 :
632 0 : return true;
633 : }
634 :
635 :
636 0 : bool OfficeDocumentsManager::isBasicIDE(
637 : const uno::Reference< frame::XModel > & xModel )
638 : {
639 0 : if ( !m_xModuleMgr.is() )
640 : {
641 0 : osl::MutexGuard aGuard( m_aMtx );
642 0 : if ( !m_xModuleMgr.is() )
643 : {
644 : try
645 : {
646 0 : 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 0 : }
656 : }
657 :
658 0 : if ( m_xModuleMgr.is() )
659 : {
660 0 : OUString aModule;
661 : try
662 : {
663 0 : 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 0 : if ( !aModule.isEmpty() )
675 : {
676 : // Filter unwanted items, that are no real documents.
677 0 : if ( aModule == "com.sun.star.script.BasicIDE" )
678 : {
679 0 : return true;
680 : }
681 0 : }
682 : }
683 :
684 0 : return false;
685 : }
686 :
687 :
688 0 : bool OfficeDocumentsManager::isOfficeDocument(
689 : const uno::Reference< uno::XInterface > & xDoc )
690 : {
691 0 : uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY );
692 : uno::Reference< document::XStorageBasedDocument >
693 0 : xStorageBasedDoc( xModel, uno::UNO_QUERY );
694 0 : if ( !xStorageBasedDoc.is() )
695 0 : return false;
696 :
697 0 : if ( !isWithoutOrInTopLevelFrame( xModel ) )
698 0 : return false;
699 :
700 0 : if ( isDocumentPreview( xModel ) )
701 0 : return false;
702 :
703 0 : if ( isHelpDocument( xModel ) )
704 0 : return false;
705 :
706 0 : if ( isBasicIDE( xModel ) )
707 0 : return false;
708 :
709 0 : return true;
710 : }
711 :
712 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|