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 : #include <com/sun/star/frame/Desktop.hpp>
21 : #include <com/sun/star/frame/XFrame.hpp>
22 : #include <com/sun/star/frame/XController.hpp>
23 : #include <com/sun/star/frame/XComponentLoader.hpp>
24 : #include <com/sun/star/awt/XTopWindow.hpp>
25 : #include <com/sun/star/embed/XClassifiedObject.hpp>
26 : #include <com/sun/star/io/TempFile.hpp>
27 : #include <com/sun/star/io/XStream.hpp>
28 : #include <com/sun/star/io/XInputStream.hpp>
29 : #include <com/sun/star/io/XOutputStream.hpp>
30 : #include <com/sun/star/io/XSeekable.hpp>
31 : #include <com/sun/star/task/XInteractionHandler.hpp>
32 : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
33 : #include <com/sun/star/util/XCloseable.hpp>
34 : #include <com/sun/star/beans/XPropertySet.hpp>
35 :
36 : #include <com/sun/star/document/XEventBroadcaster.hpp>
37 : #include <com/sun/star/document/XEventListener.hpp>
38 : #include <com/sun/star/document/XTypeDetection.hpp>
39 : #include <com/sun/star/container/XNameAccess.hpp>
40 : #include <cppuhelper/implbase1.hxx>
41 : #include <comphelper/processfactory.hxx>
42 : #include <comphelper/storagehelper.hxx>
43 : #include <comphelper/mimeconfighelper.hxx>
44 :
45 : #include "olepersist.hxx"
46 : #include "ownview.hxx"
47 :
48 :
49 : using namespace ::com::sun::star;
50 : using namespace ::comphelper;
51 :
52 : class DummyHandler_Impl : public ::cppu::WeakImplHelper1< task::XInteractionHandler >
53 : {
54 : public:
55 0 : DummyHandler_Impl() {}
56 : virtual ~DummyHandler_Impl();
57 :
58 : virtual void SAL_CALL handle( const uno::Reference< task::XInteractionRequest >& xRequest )
59 : throw( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
60 : };
61 :
62 :
63 0 : DummyHandler_Impl::~DummyHandler_Impl()
64 : {
65 0 : }
66 :
67 :
68 0 : void SAL_CALL DummyHandler_Impl::handle( const uno::Reference< task::XInteractionRequest >& )
69 : throw( uno::RuntimeException, std::exception )
70 : {
71 0 : return;
72 : }
73 :
74 :
75 : // Object viewer
76 :
77 :
78 0 : OwnView_Impl::OwnView_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory,
79 : const uno::Reference< io::XInputStream >& xInputStream )
80 : : m_xFactory( xFactory )
81 : , m_bBusy( false )
82 0 : , m_bUseNative( false )
83 : {
84 0 : if ( !xFactory.is() || !xInputStream.is() )
85 0 : throw uno::RuntimeException();
86 :
87 0 : m_aTempFileURL = GetNewFilledTempFile_Impl( xInputStream, m_xFactory );
88 0 : }
89 :
90 :
91 0 : OwnView_Impl::~OwnView_Impl()
92 : {
93 : try {
94 0 : KillFile_Impl( m_aTempFileURL, m_xFactory );
95 0 : } catch( uno::Exception& ) {}
96 :
97 : try {
98 0 : if ( !m_aNativeTempURL.isEmpty() )
99 0 : KillFile_Impl( m_aNativeTempURL, m_xFactory );
100 0 : } catch( uno::Exception& ) {}
101 0 : }
102 :
103 :
104 0 : bool OwnView_Impl::CreateModelFromURL( const OUString& aFileURL )
105 : {
106 0 : bool bResult = false;
107 :
108 0 : if ( !aFileURL.isEmpty() )
109 : {
110 : try {
111 0 : uno::Reference < frame::XDesktop2 > xDocumentLoader = frame::Desktop::create(comphelper::getComponentContext(m_xFactory));
112 :
113 0 : uno::Sequence< beans::PropertyValue > aArgs( m_aFilterName.isEmpty() ? 4 : 5 );
114 :
115 0 : aArgs[0].Name = "URL";
116 0 : aArgs[0].Value <<= aFileURL;
117 :
118 0 : aArgs[1].Name = "ReadOnly";
119 0 : aArgs[1].Value <<= sal_True;
120 :
121 0 : aArgs[2].Name = "InteractionHandler";
122 0 : aArgs[2].Value <<= uno::Reference< task::XInteractionHandler >(
123 0 : static_cast< ::cppu::OWeakObject* >( new DummyHandler_Impl() ), uno::UNO_QUERY );
124 :
125 0 : aArgs[3].Name = "DontEdit";
126 0 : aArgs[3].Value <<= sal_True;
127 :
128 0 : if ( !m_aFilterName.isEmpty() )
129 : {
130 0 : aArgs[4].Name = "FilterName";
131 0 : aArgs[4].Value <<= m_aFilterName;
132 : }
133 :
134 0 : uno::Reference< frame::XModel > xModel( xDocumentLoader->loadComponentFromURL(
135 : aFileURL,
136 : OUString( "_blank" ),
137 : 0,
138 0 : aArgs ),
139 0 : uno::UNO_QUERY );
140 :
141 0 : if ( xModel.is() )
142 : {
143 0 : uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
144 0 : if ( xBroadCaster.is() )
145 0 : xBroadCaster->addEventListener( uno::Reference< document::XEventListener >(
146 : static_cast< ::cppu::OWeakObject* >( this ),
147 0 : uno::UNO_QUERY ) );
148 :
149 0 : uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
150 0 : if ( xCloseable.is() )
151 : {
152 0 : xCloseable->addCloseListener( uno::Reference< util::XCloseListener >(
153 : static_cast< ::cppu::OWeakObject* >( this ),
154 0 : uno::UNO_QUERY ) );
155 :
156 0 : ::osl::MutexGuard aGuard( m_aMutex );
157 0 : m_xModel = xModel;
158 0 : bResult = true;
159 0 : }
160 0 : }
161 : }
162 0 : catch (uno::Exception const& e)
163 : {
164 : SAL_WARN("embeddedobj.ole", "OwnView_Impl::CreateModelFromURL:"
165 : " exception caught: " << e.Message);
166 : }
167 : }
168 :
169 0 : return bResult;
170 : }
171 :
172 :
173 0 : bool OwnView_Impl::CreateModel( bool bUseNative )
174 : {
175 0 : bool bResult = false;
176 :
177 : try {
178 0 : bResult = CreateModelFromURL( bUseNative ? m_aNativeTempURL : m_aTempFileURL );
179 : }
180 0 : catch( uno::Exception& )
181 : {
182 : }
183 :
184 0 : return bResult;
185 : }
186 :
187 :
188 0 : OUString OwnView_Impl::GetFilterNameFromExtentionAndInStream(
189 : const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
190 : const OUString& aNameWithExtention,
191 : const uno::Reference< io::XInputStream >& xInputStream )
192 : {
193 0 : if ( !xInputStream.is() )
194 0 : throw uno::RuntimeException();
195 :
196 : uno::Reference< document::XTypeDetection > xTypeDetection(
197 0 : xFactory->createInstance("com.sun.star.document.TypeDetection"),
198 0 : uno::UNO_QUERY_THROW );
199 :
200 0 : OUString aTypeName;
201 :
202 0 : if ( !aNameWithExtention.isEmpty() )
203 : {
204 : OUString aURLToAnalyze =
205 0 : ( OUString( "file:///" ) + aNameWithExtention );
206 0 : aTypeName = xTypeDetection->queryTypeByURL( aURLToAnalyze );
207 : }
208 :
209 0 : uno::Sequence< beans::PropertyValue > aArgs( aTypeName.isEmpty() ? 2 : 3 );
210 0 : aArgs[0].Name = "URL";
211 0 : aArgs[0].Value <<= OUString( "private:stream" );
212 0 : aArgs[1].Name = "InputStream";
213 0 : aArgs[1].Value <<= xInputStream;
214 0 : if ( !aTypeName.isEmpty() )
215 : {
216 0 : aArgs[2].Name = "TypeName";
217 0 : aArgs[2].Value <<= aTypeName;
218 : }
219 :
220 0 : aTypeName = xTypeDetection->queryTypeByDescriptor( aArgs, sal_True );
221 :
222 0 : OUString aFilterName;
223 0 : for ( sal_Int32 nInd = 0; nInd < aArgs.getLength(); nInd++ )
224 0 : if ( aArgs[nInd].Name == "FilterName" )
225 0 : aArgs[nInd].Value >>= aFilterName;
226 :
227 0 : if ( aFilterName.isEmpty() && !aTypeName.isEmpty() )
228 : {
229 : // get the default filter name for the type
230 0 : uno::Reference< container::XNameAccess > xNameAccess( xTypeDetection, uno::UNO_QUERY_THROW );
231 0 : uno::Sequence< beans::PropertyValue > aTypes;
232 :
233 0 : if ( xNameAccess.is() && ( xNameAccess->getByName( aTypeName ) >>= aTypes ) )
234 : {
235 0 : for ( sal_Int32 nInd = 0; nInd < aTypes.getLength(); nInd++ )
236 : {
237 0 : if ( aTypes[nInd].Name == "PreferredFilter" && ( aTypes[nInd].Value >>= aFilterName ) )
238 : {
239 0 : aTypes[nInd].Value >>= aFilterName;
240 0 : break;
241 : }
242 : }
243 0 : }
244 : }
245 :
246 0 : return aFilterName;
247 : }
248 :
249 :
250 0 : bool OwnView_Impl::ReadContentsAndGenerateTempFile( const uno::Reference< io::XInputStream >& xInStream,
251 : bool bParseHeader )
252 : {
253 0 : uno::Reference< io::XSeekable > xSeekable( xInStream, uno::UNO_QUERY_THROW );
254 0 : xSeekable->seek( 0 );
255 :
256 : // create m_aNativeTempURL
257 0 : OUString aNativeTempURL;
258 : uno::Reference < beans::XPropertySet > xNativeTempFile(
259 : io::TempFile::create(comphelper::getComponentContext(m_xFactory)),
260 0 : uno::UNO_QUERY_THROW );
261 0 : uno::Reference < io::XStream > xNativeTempStream( xNativeTempFile, uno::UNO_QUERY_THROW );
262 0 : uno::Reference < io::XOutputStream > xNativeOutTemp = xNativeTempStream->getOutputStream();
263 0 : uno::Reference < io::XInputStream > xNativeInTemp = xNativeTempStream->getInputStream();
264 0 : if ( !xNativeOutTemp.is() || !xNativeInTemp.is() )
265 0 : throw uno::RuntimeException();
266 :
267 : try {
268 0 : xNativeTempFile->setPropertyValue("RemoveFile", uno::makeAny( sal_False ) );
269 0 : uno::Any aUrl = xNativeTempFile->getPropertyValue("Uri");
270 0 : aUrl >>= aNativeTempURL;
271 : }
272 0 : catch ( uno::Exception& )
273 : {
274 : }
275 :
276 0 : bool bFailed = false;
277 0 : OUString aFileSuffix;
278 :
279 0 : if ( bParseHeader )
280 : {
281 0 : uno::Sequence< sal_Int8 > aReadSeq( 4 );
282 : // read the complete size of the Object Package
283 0 : if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
284 0 : return false;
285 : // read the first header ( have no idea what does this header mean )
286 0 : if ( xInStream->readBytes( aReadSeq, 2 ) != 2 || aReadSeq[0] != 2 || aReadSeq[1] != 0 )
287 0 : return false;
288 :
289 : // read file name
290 : // only extension is interesting so only subset of symbols is accepted
291 0 : do
292 : {
293 0 : if ( xInStream->readBytes( aReadSeq, 1 ) != 1 )
294 0 : return false;
295 :
296 0 : if (
297 0 : (aReadSeq[0] >= '0' && aReadSeq[0] <= '9') ||
298 0 : (aReadSeq[0] >= 'a' && aReadSeq[0] <= 'z') ||
299 0 : (aReadSeq[0] >= 'A' && aReadSeq[0] <= 'Z') ||
300 0 : aReadSeq[0] == '.'
301 : )
302 : {
303 0 : aFileSuffix += OUString( (sal_Unicode) aReadSeq[0] );
304 : }
305 :
306 0 : } while( aReadSeq[0] );
307 :
308 : // skip url
309 0 : do
310 : {
311 0 : if ( xInStream->readBytes( aReadSeq, 1 ) != 1 )
312 0 : return false;
313 0 : } while( aReadSeq[0] );
314 :
315 : // check the next header
316 0 : if ( xInStream->readBytes( aReadSeq, 4 ) != 4
317 0 : || aReadSeq[0] || aReadSeq[1] || aReadSeq[2] != 3 || aReadSeq[3] )
318 0 : return false;
319 :
320 : // get the size of the next entry
321 0 : if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
322 0 : return false;
323 :
324 0 : sal_uInt32 nUrlSize = (sal_uInt8)aReadSeq[0]
325 0 : + (sal_uInt8)aReadSeq[1] * 0x100
326 0 : + (sal_uInt8)aReadSeq[2] * 0x10000
327 0 : + (sal_uInt8)aReadSeq[3] * 0x1000000;
328 0 : sal_Int64 nTargetPos = xSeekable->getPosition() + nUrlSize;
329 :
330 0 : xSeekable->seek( nTargetPos );
331 :
332 : // get the size of stored data
333 0 : if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
334 0 : return false;
335 :
336 0 : sal_uInt32 nDataSize = (sal_uInt8)aReadSeq[0]
337 0 : + (sal_uInt8)aReadSeq[1] * 0x100
338 0 : + (sal_uInt8)aReadSeq[2] * 0x10000
339 0 : + (sal_uInt8)aReadSeq[3] * 0x1000000;
340 :
341 0 : aReadSeq.realloc( 32000 );
342 0 : sal_uInt32 nRead = 0;
343 0 : while ( nRead < nDataSize )
344 : {
345 0 : sal_uInt32 nToRead = ( nDataSize - nRead > 32000 ) ? 32000 : nDataSize - nRead;
346 0 : sal_uInt32 nLocalRead = xInStream->readBytes( aReadSeq, nToRead );
347 :
348 :
349 0 : if ( !nLocalRead )
350 : {
351 0 : bFailed = true;
352 0 : break;
353 : }
354 0 : else if ( nLocalRead == 32000 )
355 0 : xNativeOutTemp->writeBytes( aReadSeq );
356 : else
357 : {
358 0 : uno::Sequence< sal_Int8 > aToWrite( aReadSeq );
359 0 : aToWrite.realloc( nLocalRead );
360 0 : xNativeOutTemp->writeBytes( aToWrite );
361 : }
362 :
363 0 : nRead += nLocalRead;
364 0 : }
365 : }
366 : else
367 : {
368 0 : uno::Sequence< sal_Int8 > aData( 8 );
369 0 : if ( xInStream->readBytes( aData, 8 ) == 8
370 0 : && aData[0] == -1 && aData[1] == -1 && aData[2] == -1 && aData[3] == -1
371 0 : && ( aData[4] == 2 || aData[4] == 3 ) && aData[5] == 0 && aData[6] == 0 && aData[7] == 0 )
372 : {
373 : // the header has to be removed
374 0 : xSeekable->seek( 40 );
375 : }
376 : else
377 : {
378 : // the usual Ole10Native format
379 0 : xSeekable->seek( 4 );
380 : }
381 :
382 0 : ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xNativeOutTemp );
383 : }
384 :
385 0 : xNativeOutTemp->closeOutput();
386 :
387 : // The temporary native file is created, now the filter must be detected
388 0 : if ( !bFailed )
389 : {
390 0 : m_aFilterName = GetFilterNameFromExtentionAndInStream( m_xFactory, aFileSuffix, xNativeInTemp );
391 0 : m_aNativeTempURL = aNativeTempURL;
392 : }
393 :
394 0 : return !bFailed;
395 : }
396 :
397 :
398 0 : void OwnView_Impl::CreateNative()
399 : {
400 0 : if ( !m_aNativeTempURL.isEmpty() )
401 0 : return;
402 :
403 : try
404 : {
405 : uno::Reference < ucb::XSimpleFileAccess3 > xAccess(
406 0 : ucb::SimpleFileAccess::create( comphelper::getComponentContext(m_xFactory) ) );
407 :
408 0 : uno::Reference< io::XInputStream > xInStream = xAccess->openFileRead( m_aTempFileURL );
409 0 : if ( !xInStream.is() )
410 0 : throw uno::RuntimeException();
411 :
412 0 : uno::Sequence< uno::Any > aArgs( 1 );
413 0 : aArgs[0] <<= xInStream;
414 : uno::Reference< container::XNameAccess > xNameAccess(
415 0 : m_xFactory->createInstanceWithArguments(
416 : OUString( "com.sun.star.embed.OLESimpleStorage" ),
417 0 : aArgs ),
418 0 : uno::UNO_QUERY_THROW );
419 :
420 0 : OUString aSubStreamName = "\1Ole10Native";
421 0 : uno::Reference< embed::XClassifiedObject > xStor( xNameAccess, uno::UNO_QUERY_THROW );
422 0 : uno::Sequence< sal_Int8 > aStorClassID = xStor->getClassID();
423 :
424 0 : if ( xNameAccess->hasByName( aSubStreamName ) )
425 : {
426 : sal_uInt8 aClassID[] =
427 0 : { 0x00, 0x03, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
428 0 : uno::Sequence< sal_Int8 > aPackageClassID( (sal_Int8*)aClassID, 16 );
429 :
430 0 : uno::Reference< io::XStream > xSubStream;
431 0 : xNameAccess->getByName( aSubStreamName ) >>= xSubStream;
432 0 : if ( xSubStream.is() )
433 : {
434 0 : bool bOk = false;
435 :
436 0 : if ( MimeConfigurationHelper::ClassIDsEqual( aPackageClassID, aStorClassID ) )
437 : {
438 : // the storage represents Object Package
439 :
440 0 : bOk = ReadContentsAndGenerateTempFile( xSubStream->getInputStream(), true );
441 :
442 0 : if ( !bOk && !m_aNativeTempURL.isEmpty() )
443 : {
444 0 : KillFile_Impl( m_aNativeTempURL, m_xFactory );
445 0 : m_aNativeTempURL = OUString();
446 : }
447 : }
448 :
449 0 : if ( !bOk )
450 : {
451 0 : bOk = ReadContentsAndGenerateTempFile( xSubStream->getInputStream(), false );
452 :
453 0 : if ( !bOk && !m_aNativeTempURL.isEmpty() )
454 : {
455 0 : KillFile_Impl( m_aNativeTempURL, m_xFactory );
456 0 : m_aNativeTempURL = OUString();
457 : }
458 : }
459 0 : }
460 : }
461 : else
462 : {
463 : // TODO/LATER: No native stream, needs a new solution
464 0 : }
465 : }
466 0 : catch( uno::Exception& )
467 : {}
468 : }
469 :
470 :
471 0 : bool OwnView_Impl::Open()
472 : {
473 0 : bool bResult = false;
474 :
475 0 : uno::Reference< frame::XModel > xExistingModel;
476 :
477 : {
478 0 : ::osl::MutexGuard aGuard( m_aMutex );
479 0 : xExistingModel = m_xModel;
480 0 : if ( m_bBusy )
481 0 : return false;
482 :
483 0 : m_bBusy = true;
484 : }
485 :
486 0 : if ( xExistingModel.is() )
487 : {
488 : try {
489 0 : uno::Reference< frame::XController > xController = xExistingModel->getCurrentController();
490 0 : if ( xController.is() )
491 : {
492 0 : uno::Reference< frame::XFrame > xFrame = xController->getFrame();
493 0 : if ( xFrame.is() )
494 : {
495 0 : xFrame->activate();
496 0 : uno::Reference<awt::XTopWindow> xTopWindow( xFrame->getContainerWindow(), uno::UNO_QUERY );
497 0 : if(xTopWindow.is())
498 0 : xTopWindow->toFront();
499 :
500 0 : bResult = true;
501 0 : }
502 0 : }
503 : }
504 0 : catch( uno::Exception& )
505 : {
506 : }
507 : }
508 : else
509 : {
510 0 : bResult = CreateModel( m_bUseNative );
511 :
512 0 : if ( !bResult && !m_bUseNative )
513 : {
514 : // the original storage can not be recognized
515 0 : if ( m_aNativeTempURL.isEmpty() )
516 : {
517 : // create a temporary file for the native representation if there is no
518 0 : CreateNative();
519 : }
520 :
521 0 : if ( !m_aNativeTempURL.isEmpty() )
522 : {
523 0 : bResult = CreateModel( true );
524 0 : if ( bResult )
525 0 : m_bUseNative = true;
526 : }
527 : }
528 : }
529 :
530 0 : m_bBusy = false;
531 :
532 0 : return bResult;
533 : }
534 :
535 :
536 0 : void OwnView_Impl::Close()
537 : {
538 0 : uno::Reference< frame::XModel > xModel;
539 :
540 : {
541 0 : ::osl::MutexGuard aGuard( m_aMutex );
542 0 : if ( !m_xModel.is() )
543 0 : return;
544 0 : xModel = m_xModel;
545 0 : m_xModel = uno::Reference< frame::XModel >();
546 :
547 0 : if ( m_bBusy )
548 0 : return;
549 :
550 0 : m_bBusy = true;
551 : }
552 :
553 : try {
554 0 : uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
555 0 : if ( xBroadCaster.is() )
556 0 : xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
557 : static_cast< ::cppu::OWeakObject* >( this ),
558 0 : uno::UNO_QUERY ) );
559 :
560 0 : uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
561 0 : if ( xCloseable.is() )
562 : {
563 0 : xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
564 : static_cast< ::cppu::OWeakObject* >( this ),
565 0 : uno::UNO_QUERY ) );
566 0 : xCloseable->close( sal_True );
567 0 : }
568 : }
569 0 : catch( uno::Exception& )
570 : {}
571 :
572 0 : m_bBusy = false;
573 : }
574 :
575 :
576 0 : void SAL_CALL OwnView_Impl::notifyEvent( const document::EventObject& aEvent )
577 : throw ( uno::RuntimeException, std::exception )
578 : {
579 :
580 0 : uno::Reference< frame::XModel > xModel;
581 :
582 : {
583 0 : ::osl::MutexGuard aGuard( m_aMutex );
584 0 : if ( aEvent.Source == m_xModel && aEvent.EventName == "OnSaveAsDone" )
585 : {
586 : // SaveAs operation took place, so just forget the model and deregister listeners
587 0 : xModel = m_xModel;
588 0 : m_xModel = uno::Reference< frame::XModel >();
589 0 : }
590 : }
591 :
592 0 : if ( xModel.is() )
593 : {
594 : try {
595 0 : uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
596 0 : if ( xBroadCaster.is() )
597 0 : xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
598 : static_cast< ::cppu::OWeakObject* >( this ),
599 0 : uno::UNO_QUERY ) );
600 :
601 0 : uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
602 0 : if ( xCloseable.is() )
603 0 : xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
604 : static_cast< ::cppu::OWeakObject* >( this ),
605 0 : uno::UNO_QUERY ) );
606 : }
607 0 : catch( uno::Exception& )
608 : {}
609 0 : }
610 0 : }
611 :
612 :
613 0 : void SAL_CALL OwnView_Impl::queryClosing( const lang::EventObject&, sal_Bool )
614 : throw ( util::CloseVetoException,
615 : uno::RuntimeException, std::exception )
616 : {
617 0 : }
618 :
619 :
620 0 : void SAL_CALL OwnView_Impl::notifyClosing( const lang::EventObject& Source )
621 : throw ( uno::RuntimeException, std::exception )
622 : {
623 0 : ::osl::MutexGuard aGuard( m_aMutex );
624 0 : if ( Source.Source == m_xModel )
625 0 : m_xModel = uno::Reference< frame::XModel >();
626 0 : }
627 :
628 :
629 0 : void SAL_CALL OwnView_Impl::disposing( const lang::EventObject& Source )
630 : throw (uno::RuntimeException, std::exception)
631 : {
632 0 : ::osl::MutexGuard aGuard( m_aMutex );
633 0 : if ( Source.Source == m_xModel )
634 0 : m_xModel = uno::Reference< frame::XModel >();
635 0 : };
636 :
637 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|