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 1 : 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 1 : if ( !xInputStream.is() )
194 0 : throw uno::RuntimeException();
195 :
196 : uno::Reference< document::XTypeDetection > xTypeDetection(
197 1 : xFactory->createInstance("com.sun.star.document.TypeDetection"),
198 1 : uno::UNO_QUERY_THROW );
199 :
200 2 : OUString aTypeName;
201 :
202 1 : if ( !aNameWithExtention.isEmpty() )
203 : {
204 0 : OUString aURLToAnalyze = "file:///" + aNameWithExtention;
205 0 : aTypeName = xTypeDetection->queryTypeByURL( aURLToAnalyze );
206 : }
207 :
208 2 : uno::Sequence< beans::PropertyValue > aArgs( aTypeName.isEmpty() ? 2 : 3 );
209 1 : aArgs[0].Name = "URL";
210 1 : aArgs[0].Value <<= OUString( "private:stream" );
211 1 : aArgs[1].Name = "InputStream";
212 1 : aArgs[1].Value <<= xInputStream;
213 1 : if ( !aTypeName.isEmpty() )
214 : {
215 0 : aArgs[2].Name = "TypeName";
216 0 : aArgs[2].Value <<= aTypeName;
217 : }
218 :
219 1 : aTypeName = xTypeDetection->queryTypeByDescriptor( aArgs, sal_True );
220 :
221 1 : OUString aFilterName;
222 5 : for ( sal_Int32 nInd = 0; nInd < aArgs.getLength(); nInd++ )
223 4 : if ( aArgs[nInd].Name == "FilterName" )
224 1 : aArgs[nInd].Value >>= aFilterName;
225 :
226 1 : if ( aFilterName.isEmpty() && !aTypeName.isEmpty() )
227 : {
228 : // get the default filter name for the type
229 0 : uno::Reference< container::XNameAccess > xNameAccess( xTypeDetection, uno::UNO_QUERY_THROW );
230 0 : uno::Sequence< beans::PropertyValue > aTypes;
231 :
232 0 : if ( xNameAccess.is() && ( xNameAccess->getByName( aTypeName ) >>= aTypes ) )
233 : {
234 0 : for ( sal_Int32 nInd = 0; nInd < aTypes.getLength(); nInd++ )
235 : {
236 0 : if ( aTypes[nInd].Name == "PreferredFilter" && ( aTypes[nInd].Value >>= aFilterName ) )
237 : {
238 0 : aTypes[nInd].Value >>= aFilterName;
239 0 : break;
240 : }
241 : }
242 0 : }
243 : }
244 :
245 2 : return aFilterName;
246 : }
247 :
248 :
249 0 : bool OwnView_Impl::ReadContentsAndGenerateTempFile( const uno::Reference< io::XInputStream >& xInStream,
250 : bool bParseHeader )
251 : {
252 0 : uno::Reference< io::XSeekable > xSeekable( xInStream, uno::UNO_QUERY_THROW );
253 0 : xSeekable->seek( 0 );
254 :
255 : // create m_aNativeTempURL
256 0 : OUString aNativeTempURL;
257 : uno::Reference < beans::XPropertySet > xNativeTempFile(
258 : io::TempFile::create(comphelper::getComponentContext(m_xFactory)),
259 0 : uno::UNO_QUERY_THROW );
260 0 : uno::Reference < io::XStream > xNativeTempStream( xNativeTempFile, uno::UNO_QUERY_THROW );
261 0 : uno::Reference < io::XOutputStream > xNativeOutTemp = xNativeTempStream->getOutputStream();
262 0 : uno::Reference < io::XInputStream > xNativeInTemp = xNativeTempStream->getInputStream();
263 0 : if ( !xNativeOutTemp.is() || !xNativeInTemp.is() )
264 0 : throw uno::RuntimeException();
265 :
266 : try {
267 0 : xNativeTempFile->setPropertyValue("RemoveFile", uno::makeAny( sal_False ) );
268 0 : uno::Any aUrl = xNativeTempFile->getPropertyValue("Uri");
269 0 : aUrl >>= aNativeTempURL;
270 : }
271 0 : catch ( uno::Exception& )
272 : {
273 : }
274 :
275 0 : bool bFailed = false;
276 0 : OUString aFileSuffix;
277 :
278 0 : if ( bParseHeader )
279 : {
280 0 : uno::Sequence< sal_Int8 > aReadSeq( 4 );
281 : // read the complete size of the Object Package
282 0 : if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
283 0 : return false;
284 : // read the first header ( have no idea what does this header mean )
285 0 : if ( xInStream->readBytes( aReadSeq, 2 ) != 2 || aReadSeq[0] != 2 || aReadSeq[1] != 0 )
286 0 : return false;
287 :
288 : // read file name
289 : // only extension is interesting so only subset of symbols is accepted
290 0 : do
291 : {
292 0 : if ( xInStream->readBytes( aReadSeq, 1 ) != 1 )
293 0 : return false;
294 :
295 0 : if (
296 0 : (aReadSeq[0] >= '0' && aReadSeq[0] <= '9') ||
297 0 : (aReadSeq[0] >= 'a' && aReadSeq[0] <= 'z') ||
298 0 : (aReadSeq[0] >= 'A' && aReadSeq[0] <= 'Z') ||
299 0 : aReadSeq[0] == '.'
300 : )
301 : {
302 0 : aFileSuffix += OUString( (sal_Unicode) aReadSeq[0] );
303 : }
304 :
305 0 : } while( aReadSeq[0] );
306 :
307 : // skip url
308 0 : do
309 : {
310 0 : if ( xInStream->readBytes( aReadSeq, 1 ) != 1 )
311 0 : return false;
312 0 : } while( aReadSeq[0] );
313 :
314 : // check the next header
315 0 : if ( xInStream->readBytes( aReadSeq, 4 ) != 4
316 0 : || aReadSeq[0] || aReadSeq[1] || aReadSeq[2] != 3 || aReadSeq[3] )
317 0 : return false;
318 :
319 : // get the size of the next entry
320 0 : if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
321 0 : return false;
322 :
323 0 : sal_uInt32 nUrlSize = (sal_uInt8)aReadSeq[0]
324 0 : + (sal_uInt8)aReadSeq[1] * 0x100
325 0 : + (sal_uInt8)aReadSeq[2] * 0x10000
326 0 : + (sal_uInt8)aReadSeq[3] * 0x1000000;
327 0 : sal_Int64 nTargetPos = xSeekable->getPosition() + nUrlSize;
328 :
329 0 : xSeekable->seek( nTargetPos );
330 :
331 : // get the size of stored data
332 0 : if ( xInStream->readBytes( aReadSeq, 4 ) != 4 )
333 0 : return false;
334 :
335 0 : sal_uInt32 nDataSize = (sal_uInt8)aReadSeq[0]
336 0 : + (sal_uInt8)aReadSeq[1] * 0x100
337 0 : + (sal_uInt8)aReadSeq[2] * 0x10000
338 0 : + (sal_uInt8)aReadSeq[3] * 0x1000000;
339 :
340 0 : aReadSeq.realloc( 32000 );
341 0 : sal_uInt32 nRead = 0;
342 0 : while ( nRead < nDataSize )
343 : {
344 0 : sal_uInt32 nToRead = ( nDataSize - nRead > 32000 ) ? 32000 : nDataSize - nRead;
345 0 : sal_uInt32 nLocalRead = xInStream->readBytes( aReadSeq, nToRead );
346 :
347 :
348 0 : if ( !nLocalRead )
349 : {
350 0 : bFailed = true;
351 0 : break;
352 : }
353 0 : else if ( nLocalRead == 32000 )
354 0 : xNativeOutTemp->writeBytes( aReadSeq );
355 : else
356 : {
357 0 : uno::Sequence< sal_Int8 > aToWrite( aReadSeq );
358 0 : aToWrite.realloc( nLocalRead );
359 0 : xNativeOutTemp->writeBytes( aToWrite );
360 : }
361 :
362 0 : nRead += nLocalRead;
363 0 : }
364 : }
365 : else
366 : {
367 0 : uno::Sequence< sal_Int8 > aData( 8 );
368 0 : if ( xInStream->readBytes( aData, 8 ) == 8
369 0 : && aData[0] == -1 && aData[1] == -1 && aData[2] == -1 && aData[3] == -1
370 0 : && ( aData[4] == 2 || aData[4] == 3 ) && aData[5] == 0 && aData[6] == 0 && aData[7] == 0 )
371 : {
372 : // the header has to be removed
373 0 : xSeekable->seek( 40 );
374 : }
375 : else
376 : {
377 : // the usual Ole10Native format
378 0 : xSeekable->seek( 4 );
379 : }
380 :
381 0 : ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xNativeOutTemp );
382 : }
383 :
384 0 : xNativeOutTemp->closeOutput();
385 :
386 : // The temporary native file is created, now the filter must be detected
387 0 : if ( !bFailed )
388 : {
389 0 : m_aFilterName = GetFilterNameFromExtentionAndInStream( m_xFactory, aFileSuffix, xNativeInTemp );
390 0 : m_aNativeTempURL = aNativeTempURL;
391 : }
392 :
393 0 : return !bFailed;
394 : }
395 :
396 :
397 0 : void OwnView_Impl::CreateNative()
398 : {
399 0 : if ( !m_aNativeTempURL.isEmpty() )
400 0 : return;
401 :
402 : try
403 : {
404 : uno::Reference < ucb::XSimpleFileAccess3 > xAccess(
405 0 : ucb::SimpleFileAccess::create( comphelper::getComponentContext(m_xFactory) ) );
406 :
407 0 : uno::Reference< io::XInputStream > xInStream = xAccess->openFileRead( m_aTempFileURL );
408 0 : if ( !xInStream.is() )
409 0 : throw uno::RuntimeException();
410 :
411 0 : uno::Sequence< uno::Any > aArgs( 1 );
412 0 : aArgs[0] <<= xInStream;
413 : uno::Reference< container::XNameAccess > xNameAccess(
414 0 : m_xFactory->createInstanceWithArguments(
415 : OUString( "com.sun.star.embed.OLESimpleStorage" ),
416 0 : aArgs ),
417 0 : uno::UNO_QUERY_THROW );
418 :
419 0 : OUString aSubStreamName = "\1Ole10Native";
420 0 : uno::Reference< embed::XClassifiedObject > xStor( xNameAccess, uno::UNO_QUERY_THROW );
421 0 : uno::Sequence< sal_Int8 > aStorClassID = xStor->getClassID();
422 :
423 0 : if ( xNameAccess->hasByName( aSubStreamName ) )
424 : {
425 : sal_uInt8 aClassID[] =
426 0 : { 0x00, 0x03, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
427 0 : uno::Sequence< sal_Int8 > aPackageClassID( reinterpret_cast<sal_Int8*>(aClassID), 16 );
428 :
429 0 : uno::Reference< io::XStream > xSubStream;
430 0 : xNameAccess->getByName( aSubStreamName ) >>= xSubStream;
431 0 : if ( xSubStream.is() )
432 : {
433 0 : bool bOk = false;
434 :
435 0 : if ( MimeConfigurationHelper::ClassIDsEqual( aPackageClassID, aStorClassID ) )
436 : {
437 : // the storage represents Object Package
438 :
439 0 : bOk = ReadContentsAndGenerateTempFile( xSubStream->getInputStream(), true );
440 :
441 0 : if ( !bOk && !m_aNativeTempURL.isEmpty() )
442 : {
443 0 : KillFile_Impl( m_aNativeTempURL, m_xFactory );
444 0 : m_aNativeTempURL.clear();
445 : }
446 : }
447 :
448 0 : if ( !bOk )
449 : {
450 0 : bOk = ReadContentsAndGenerateTempFile( xSubStream->getInputStream(), false );
451 :
452 0 : if ( !bOk && !m_aNativeTempURL.isEmpty() )
453 : {
454 0 : KillFile_Impl( m_aNativeTempURL, m_xFactory );
455 0 : m_aNativeTempURL.clear();
456 : }
457 : }
458 0 : }
459 : }
460 : else
461 : {
462 : // TODO/LATER: No native stream, needs a new solution
463 0 : }
464 : }
465 0 : catch( uno::Exception& )
466 : {}
467 : }
468 :
469 :
470 0 : bool OwnView_Impl::Open()
471 : {
472 0 : bool bResult = false;
473 :
474 0 : uno::Reference< frame::XModel > xExistingModel;
475 :
476 : {
477 0 : ::osl::MutexGuard aGuard( m_aMutex );
478 0 : xExistingModel = m_xModel;
479 0 : if ( m_bBusy )
480 0 : return false;
481 :
482 0 : m_bBusy = true;
483 : }
484 :
485 0 : if ( xExistingModel.is() )
486 : {
487 : try {
488 0 : uno::Reference< frame::XController > xController = xExistingModel->getCurrentController();
489 0 : if ( xController.is() )
490 : {
491 0 : uno::Reference< frame::XFrame > xFrame = xController->getFrame();
492 0 : if ( xFrame.is() )
493 : {
494 0 : xFrame->activate();
495 0 : uno::Reference<awt::XTopWindow> xTopWindow( xFrame->getContainerWindow(), uno::UNO_QUERY );
496 0 : if(xTopWindow.is())
497 0 : xTopWindow->toFront();
498 :
499 0 : bResult = true;
500 0 : }
501 0 : }
502 : }
503 0 : catch( uno::Exception& )
504 : {
505 : }
506 : }
507 : else
508 : {
509 0 : bResult = CreateModel( m_bUseNative );
510 :
511 0 : if ( !bResult && !m_bUseNative )
512 : {
513 : // the original storage can not be recognized
514 0 : if ( m_aNativeTempURL.isEmpty() )
515 : {
516 : // create a temporary file for the native representation if there is no
517 0 : CreateNative();
518 : }
519 :
520 0 : if ( !m_aNativeTempURL.isEmpty() )
521 : {
522 0 : bResult = CreateModel( true );
523 0 : if ( bResult )
524 0 : m_bUseNative = true;
525 : }
526 : }
527 : }
528 :
529 0 : m_bBusy = false;
530 :
531 0 : return bResult;
532 : }
533 :
534 :
535 0 : void OwnView_Impl::Close()
536 : {
537 0 : uno::Reference< frame::XModel > xModel;
538 :
539 : {
540 0 : ::osl::MutexGuard aGuard( m_aMutex );
541 0 : if ( !m_xModel.is() )
542 0 : return;
543 0 : xModel = m_xModel;
544 0 : m_xModel = uno::Reference< frame::XModel >();
545 :
546 0 : if ( m_bBusy )
547 0 : return;
548 :
549 0 : m_bBusy = true;
550 : }
551 :
552 : try {
553 0 : uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
554 0 : if ( xBroadCaster.is() )
555 0 : xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
556 : static_cast< ::cppu::OWeakObject* >( this ),
557 0 : uno::UNO_QUERY ) );
558 :
559 0 : uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
560 0 : if ( xCloseable.is() )
561 : {
562 0 : xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
563 : static_cast< ::cppu::OWeakObject* >( this ),
564 0 : uno::UNO_QUERY ) );
565 0 : xCloseable->close( sal_True );
566 0 : }
567 : }
568 0 : catch( uno::Exception& )
569 : {}
570 :
571 0 : m_bBusy = false;
572 : }
573 :
574 :
575 0 : void SAL_CALL OwnView_Impl::notifyEvent( const document::EventObject& aEvent )
576 : throw ( uno::RuntimeException, std::exception )
577 : {
578 :
579 0 : uno::Reference< frame::XModel > xModel;
580 :
581 : {
582 0 : ::osl::MutexGuard aGuard( m_aMutex );
583 0 : if ( aEvent.Source == m_xModel && aEvent.EventName == "OnSaveAsDone" )
584 : {
585 : // SaveAs operation took place, so just forget the model and deregister listeners
586 0 : xModel = m_xModel;
587 0 : m_xModel = uno::Reference< frame::XModel >();
588 0 : }
589 : }
590 :
591 0 : if ( xModel.is() )
592 : {
593 : try {
594 0 : uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY );
595 0 : if ( xBroadCaster.is() )
596 0 : xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >(
597 : static_cast< ::cppu::OWeakObject* >( this ),
598 0 : uno::UNO_QUERY ) );
599 :
600 0 : uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY );
601 0 : if ( xCloseable.is() )
602 0 : xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >(
603 : static_cast< ::cppu::OWeakObject* >( this ),
604 0 : uno::UNO_QUERY ) );
605 : }
606 0 : catch( uno::Exception& )
607 : {}
608 0 : }
609 0 : }
610 :
611 :
612 0 : void SAL_CALL OwnView_Impl::queryClosing( const lang::EventObject&, sal_Bool )
613 : throw ( util::CloseVetoException,
614 : uno::RuntimeException, std::exception )
615 : {
616 0 : }
617 :
618 :
619 0 : void SAL_CALL OwnView_Impl::notifyClosing( const lang::EventObject& Source )
620 : throw ( uno::RuntimeException, std::exception )
621 : {
622 0 : ::osl::MutexGuard aGuard( m_aMutex );
623 0 : if ( Source.Source == m_xModel )
624 0 : m_xModel = uno::Reference< frame::XModel >();
625 0 : }
626 :
627 :
628 0 : void SAL_CALL OwnView_Impl::disposing( const lang::EventObject& Source )
629 : throw (uno::RuntimeException, std::exception)
630 : {
631 0 : ::osl::MutexGuard aGuard( m_aMutex );
632 0 : if ( Source.Source == m_xModel )
633 0 : m_xModel = uno::Reference< frame::XModel >();
634 0 : };
635 :
636 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|