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