1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <jobs/job.hxx>
24 #include <com/sun/star/frame/Desktop.hpp>
25 #include <com/sun/star/task/XJob.hpp>
26 #include <com/sun/star/task/XAsyncJob.hpp>
27 #include <com/sun/star/util/XCloseBroadcaster.hpp>
28 #include <com/sun/star/util/XCloseable.hpp>
29 #include <com/sun/star/lang/DisposedException.hpp>
31 #include <comphelper/processfactory.hxx>
32 #include <rtl/ustrbuf.hxx>
33 #include <vcl/svapp.hxx>
39 @descr It initialize this new instance. But it set some generic parameters here only.
40 Specialized information (e.g. the alias or service name ofthis job) will be set
41 later using the method setJobData().
44 reference to the uno service manager
47 reference to the frame, in which environment we run
50 Job::Job( /*IN*/ const css::uno::Reference
< css::uno::XComponentContext
>& xContext
,
51 /*IN*/ const css::uno::Reference
< css::frame::XFrame
>& xFrame
)
52 : m_aJobCfg (xContext
)
53 , m_xContext (xContext
)
55 , m_bListenOnDesktop (false )
56 , m_bListenOnFrame (false )
57 , m_bListenOnModel (false )
58 , m_bPendingCloseFrame (false )
59 , m_bPendingCloseModel (false )
60 , m_eRunState (E_NEW
)
66 @descr It initialize this new instance. But it set some generic parameters here only.
67 Specialized information (e.g. the alias or service name ofthis job) will be set
68 later using the method setJobData().
71 reference to the uno service manager
74 reference to the model, in which environment we run
77 Job::Job( /*IN*/ const css::uno::Reference
< css::uno::XComponentContext
>& xContext
,
78 /*IN*/ const css::uno::Reference
< css::frame::XModel
>& xModel
)
79 : m_aJobCfg (xContext
)
80 , m_xContext (xContext
)
82 , m_bListenOnDesktop (false )
83 , m_bListenOnFrame (false )
84 , m_bListenOnModel (false )
85 , m_bPendingCloseFrame (false )
86 , m_bPendingCloseModel (false )
87 , m_eRunState (E_NEW
)
93 @descr Releasing of memory and reference must be done inside die() call.
94 Otherwhise it's a bug.
101 @short set (or delete) a listener for sending dispatch result events
102 @descr Because this object is used in a wrapped mode ... the original listener
103 for such events can't be registered here directly. Because the
104 listener expect to get the original object given as source of the event.
105 That's why we get this source here too, to fake(!) it at sending time!
108 the original listener for dispatch result events
111 our user, which got the registration request for this listener
113 void Job::setDispatchResultFake( /*IN*/ const css::uno::Reference
< css::frame::XDispatchResultListener
>& xListener
,
114 /*IN*/ const css::uno::Reference
< css::uno::XInterface
>& xSourceFake
)
118 // reject dangerous calls
119 if (m_eRunState
!= E_NEW
)
121 SAL_INFO("fwk", "Job::setJobData(): job may still running or already finished");
125 m_xResultListener
= xListener
;
126 m_xResultSourceFake
= xSourceFake
;
129 void Job::setJobData( const JobData
& aData
)
133 // reject dangerous calls
134 if (m_eRunState
!= E_NEW
)
136 SAL_INFO("fwk", "Job::setJobData(): job may still running or already finished");
145 @descr It doesn't matter, if the job is an asynchronous or
146 synchronous one. This method returns only if it was finished
150 optional arguments for job execution
151 In case the represented job is a configured one (which uses static
152 arguments too) all information will be merged!
154 void Job::execute( /*IN*/ const css::uno::Sequence
< css::beans::NamedValue
>& lDynamicArgs
)
157 SolarMutexResettableGuard aWriteLock
;
159 // reject dangerous calls
160 if (m_eRunState
!= E_NEW
)
162 SAL_INFO("fwk", "Job::execute(): job may still running or already finished");
166 // create the environment and mark this job as running ...
167 m_eRunState
= E_RUNNING
;
168 impl_startListening();
170 css::uno::Reference
< css::task::XAsyncJob
> xAJob
;
171 css::uno::Reference
< css::task::XJob
> xSJob
;
172 css::uno::Sequence
< css::beans::NamedValue
> lJobArgs
= impl_generateJobArgs(lDynamicArgs
);
174 // It's necessary to hold us self alive!
175 // Otherwhise we might die by ref count ...
176 css::uno::Reference
< css::task::XJobListener
> xThis(static_cast< ::cppu::OWeakObject
* >(this), css::uno::UNO_QUERY
);
181 // We must check for the supported interface on demand!
182 // But we preferr the synchronous one ...
183 m_xJob
= m_xContext
->getServiceManager()->createInstanceWithContext(m_aJobCfg
.getService(), m_xContext
);
184 xSJob
= css::uno::Reference
< css::task::XJob
>(m_xJob
, css::uno::UNO_QUERY
);
186 xAJob
= css::uno::Reference
< css::task::XAsyncJob
>(m_xJob
, css::uno::UNO_QUERY
);
188 // execute it asynchron
191 m_aAsyncWait
.reset();
194 xAJob
->executeAsync(lJobArgs
, xThis
);
195 // wait for finishing this job - so this method
196 // does the same for synchronous and asynchronous jobs!
200 // Note: Result handling was already done inside the callback!
202 // execute it synchron
207 css::uno::Any aResult
= xSJob
->execute(lJobArgs
);
210 impl_reactForJobResult(aResult
);
213 #if OSL_DEBUG_LEVEL > 0
214 catch(const css::uno::Exception
& ex
)
216 SAL_INFO("fwk", "Job::execute(): Got exception during job execution. Original Message was: \"" << ex
.Message
<< "\"");
219 catch(const css::uno::Exception
&)
223 // deinitialize the environment and mark this job as finished ...
224 // but don't overwrite any information about STOPPED or might DISPOSED jobs!
225 impl_stopListening();
226 if (m_eRunState
== E_RUNNING
)
227 m_eRunState
= E_STOPPED_OR_FINISHED
;
229 // If we got a close request from our frame or model ...
230 // but we disagreed wit that by throwing a veto exception...
231 // and got the ownership ...
232 // we have to close the resource frame or model now -
233 // and to disable ourself!
234 if (m_bPendingCloseFrame
)
236 m_bPendingCloseFrame
= false;
237 css::uno::Reference
< css::util::XCloseable
> xClose(m_xFrame
, css::uno::UNO_QUERY
);
242 xClose
->close(sal_True
);
244 catch(const css::util::CloseVetoException
&) {}
248 if (m_bPendingCloseModel
)
250 m_bPendingCloseModel
= false;
251 css::uno::Reference
< css::util::XCloseable
> xClose(m_xModel
, css::uno::UNO_QUERY
);
256 xClose
->close(sal_True
);
258 catch(const css::util::CloseVetoException
&) {}
265 // release this instance ...
271 @descr It doesn't matter if this request is called from inside or
272 from outside. We release our internal structures and stop
273 avary activity. After doing so - this instance will not be
274 useable any longer! Of course we try to handle further requests
275 carefully. Maybe someone else holds a reference to us ...
281 impl_stopListening();
283 if (m_eRunState
!= E_DISPOSED
)
287 css::uno::Reference
< css::lang::XComponent
> xDispose(m_xJob
, css::uno::UNO_QUERY
);
291 m_eRunState
= E_DISPOSED
;
294 catch(const css::lang::DisposedException
&)
296 m_eRunState
= E_DISPOSED
;
300 m_xJob
= css::uno::Reference
< css::uno::XInterface
>();
301 m_xFrame
= css::uno::Reference
< css::frame::XFrame
>();
302 m_xModel
= css::uno::Reference
< css::frame::XModel
>();
303 m_xDesktop
= css::uno::Reference
< css::frame::XDesktop2
>();
304 m_xResultListener
= css::uno::Reference
< css::frame::XDispatchResultListener
>();
305 m_xResultSourceFake
= css::uno::Reference
< css::uno::XInterface
>();
306 m_bPendingCloseFrame
= false;
307 m_bPendingCloseModel
= false;
311 @short generates list of arguments for job execute
312 @descr There exist a set of information, which can be needed by a job.
313 a) it's static configuration data (Equals for all jobs. )
314 b) it's specific configuration data (Different for every job.)
315 c) some environment values (e.g. the frame, for which this job was started)
316 d) any other dynamic data (e.g. parameters of a dispatch() request)
317 We collect all these information and generate one list which include all others.
320 list of dynamic arguments (given by a corresponding dispatch() call)
323 @return A list which includes all mentioned sub lists.
325 css::uno::Sequence
< css::beans::NamedValue
> Job::impl_generateJobArgs( /*IN*/ const css::uno::Sequence
< css::beans::NamedValue
>& lDynamicArgs
)
327 css::uno::Sequence
< css::beans::NamedValue
> lAllArgs
;
330 SolarMutexClearableGuard aReadLock
;
332 // the real structure of the returned list depends from the environment of this job!
333 JobData::EMode eMode
= m_aJobCfg
.getMode();
335 // Create list of environment variables. This list must be part of the
336 // returned structure every time... but some of its members are opetional!
337 css::uno::Sequence
< css::beans::NamedValue
> lEnvArgs(1);
338 lEnvArgs
[0].Name
= "EnvType";
339 lEnvArgs
[0].Value
<<= m_aJobCfg
.getEnvironmentDescriptor();
343 sal_Int32 c
= lEnvArgs
.getLength();
344 lEnvArgs
.realloc(c
+1);
345 lEnvArgs
[c
].Name
= "Frame";
346 lEnvArgs
[c
].Value
<<= m_xFrame
;
350 sal_Int32 c
= lEnvArgs
.getLength();
351 lEnvArgs
.realloc(c
+1);
352 lEnvArgs
[c
].Name
= "Model";
353 lEnvArgs
[c
].Value
<<= m_xModel
;
355 if (eMode
==JobData::E_EVENT
)
357 sal_Int32 c
= lEnvArgs
.getLength();
358 lEnvArgs
.realloc(c
+1);
359 lEnvArgs
[c
].Name
= "EventName";
360 lEnvArgs
[c
].Value
<<= m_aJobCfg
.getEvent();
363 // get the configuration data from the job data container ... if possible
364 // Means: if this job has any configuration data. Note: only really
365 // filled lists will be set to the return structure at the end of this method.
366 css::uno::Sequence
< css::beans::NamedValue
> lConfigArgs
;
367 css::uno::Sequence
< css::beans::NamedValue
> lJobConfigArgs
;
368 if (eMode
==JobData::E_ALIAS
|| eMode
==JobData::E_EVENT
)
370 lConfigArgs
= m_aJobCfg
.getConfig();
371 lJobConfigArgs
= m_aJobCfg
.getJobConfig();
377 // Add all valid (not empty) lists to the return list
378 if (lConfigArgs
.getLength()>0)
380 sal_Int32 nLength
= lAllArgs
.getLength();
381 lAllArgs
.realloc(nLength
+1);
382 lAllArgs
[nLength
].Name
= "Config";
383 lAllArgs
[nLength
].Value
<<= lConfigArgs
;
385 if (lJobConfigArgs
.getLength()>0)
387 sal_Int32 nLength
= lAllArgs
.getLength();
388 lAllArgs
.realloc(nLength
+1);
389 lAllArgs
[nLength
].Name
= "JobConfig";
390 lAllArgs
[nLength
].Value
<<= lJobConfigArgs
;
392 if (lEnvArgs
.getLength()>0)
394 sal_Int32 nLength
= lAllArgs
.getLength();
395 lAllArgs
.realloc(nLength
+1);
396 lAllArgs
[nLength
].Name
= "Environment";
397 lAllArgs
[nLength
].Value
<<= lEnvArgs
;
399 if (lDynamicArgs
.getLength()>0)
401 sal_Int32 nLength
= lAllArgs
.getLength();
402 lAllArgs
.realloc(nLength
+1);
403 lAllArgs
[nLength
].Name
= "DynamicData";
404 lAllArgs
[nLength
].Value
<<= lDynamicArgs
;
411 @short analyze the given job result and change the job configuration
412 @descr Note: Some results can be handled only, if this job has a valid configuration!
413 For "not configured jobs" (means pure services) they can be ignored.
414 But these cases are handled by our JobData member. We can call it every time.
415 It does the right things automatically. E.g. if the job has no configuration ...
416 it does nothing during setJobConfig()!
419 the job result for analyzing
421 void Job::impl_reactForJobResult( /*IN*/ const css::uno::Any
& aResult
)
425 // analyze the result set ...
426 JobResult
aAnalyzedResult(aResult
);
428 // some of the following operations will be supported for different environments
429 // or different type of jobs only.
430 JobData::EEnvironment eEnvironment
= m_aJobCfg
.getEnvironment();
432 // write back the job specific configuration data ...
433 // If the environment allow it and if this job has a configuration!
435 (m_aJobCfg
.hasConfig() ) &&
436 (aAnalyzedResult
.existPart(JobResult::E_ARGUMENTS
))
439 m_aJobCfg
.setJobConfig(aAnalyzedResult
.getArguments());
442 // disable a job for further executions.
443 // Note: this option is available inside the environment EXECUTOR only
445 // (eEnvironment == JobData::E_EXECUTION ) &&
446 (m_aJobCfg
.hasConfig() ) &&
447 (aAnalyzedResult
.existPart(JobResult::E_DEACTIVATE
))
450 m_aJobCfg
.disableJob();
453 // notify any interested listener with the may given result state.
454 // Note: this option is available inside the environment DISPATCH only
456 (eEnvironment
== JobData::E_DISPATCH
) &&
457 (m_xResultListener
.is() ) &&
458 (aAnalyzedResult
.existPart(JobResult::E_DISPATCHRESULT
))
461 m_aJobCfg
.setResult(aAnalyzedResult
);
462 // Attention: Because the listener expect that the original object send this event ...
463 // and we nor the job are the right ones ...
464 // our user has set itself before. So we can fake this source address!
465 css::frame::DispatchResultEvent aEvent
= aAnalyzedResult
.getDispatchResult();
466 aEvent
.Source
= m_xResultSourceFake
;
467 m_xResultListener
->dispatchFinished(aEvent
);
472 @short starts listening for office shutdown and closing of our
473 given target frame (if it's a valid reference)
474 @descr We will reghister ourself as terminate listener
475 at the global desktop instance. That will hold us
476 alive and additional we get the information, if the
477 office wish to shutdown. If then an internal job
478 is running we will have the chance to suppress that
479 by throwing a veto exception. If our internal wrapped
480 job finished his work, we can release this listener
483 Further we are listener for closing of the (possible valid)
484 given frame. We must be sure, that this resource won't be gone
485 if our internal job is still running.
487 void Job::impl_startListening()
491 // listening for office shutdown
492 if (!m_xDesktop
.is() && !m_bListenOnDesktop
)
496 m_xDesktop
= css::frame::Desktop::create( m_xContext
);
497 css::uno::Reference
< css::frame::XTerminateListener
> xThis(static_cast< ::cppu::OWeakObject
* >(this), css::uno::UNO_QUERY
);
498 m_xDesktop
->addTerminateListener(xThis
);
499 m_bListenOnDesktop
= true;
501 catch(const css::uno::Exception
&)
507 // listening for frame closing
508 if (m_xFrame
.is() && !m_bListenOnFrame
)
512 css::uno::Reference
< css::util::XCloseBroadcaster
> xCloseable(m_xFrame
, css::uno::UNO_QUERY
);
513 css::uno::Reference
< css::util::XCloseListener
> xThis (static_cast< ::cppu::OWeakObject
* >(this), css::uno::UNO_QUERY
);
516 xCloseable
->addCloseListener(xThis
);
517 m_bListenOnFrame
= true;
520 catch(const css::uno::Exception
&)
522 m_bListenOnFrame
= false;
526 // listening for model closing
527 if (m_xModel
.is() && !m_bListenOnModel
)
531 css::uno::Reference
< css::util::XCloseBroadcaster
> xCloseable(m_xModel
, css::uno::UNO_QUERY
);
532 css::uno::Reference
< css::util::XCloseListener
> xThis (static_cast< ::cppu::OWeakObject
* >(this), css::uno::UNO_QUERY
);
535 xCloseable
->addCloseListener(xThis
);
536 m_bListenOnModel
= true;
539 catch(const css::uno::Exception
&)
541 m_bListenOnModel
= false;
547 @short release listener connection for office shutdown
548 @descr see description of impl_startListening()
550 void Job::impl_stopListening()
554 // stop listening for office shutdown
555 if (m_xDesktop
.is() && m_bListenOnDesktop
)
559 css::uno::Reference
< css::frame::XTerminateListener
> xThis(static_cast< ::cppu::OWeakObject
* >(this) , css::uno::UNO_QUERY
);
560 m_xDesktop
->removeTerminateListener(xThis
);
562 m_bListenOnDesktop
= false;
564 catch(const css::uno::Exception
&)
569 // stop listening for frame closing
570 if (m_xFrame
.is() && m_bListenOnFrame
)
574 css::uno::Reference
< css::util::XCloseBroadcaster
> xCloseable(m_xFrame
, css::uno::UNO_QUERY
);
575 css::uno::Reference
< css::util::XCloseListener
> xThis (static_cast< ::cppu::OWeakObject
* >(this), css::uno::UNO_QUERY
);
578 xCloseable
->removeCloseListener(xThis
);
579 m_bListenOnFrame
= false;
582 catch(const css::uno::Exception
&)
587 // stop listening for model closing
588 if (m_xModel
.is() && m_bListenOnModel
)
592 css::uno::Reference
< css::util::XCloseBroadcaster
> xCloseable(m_xModel
, css::uno::UNO_QUERY
);
593 css::uno::Reference
< css::util::XCloseListener
> xThis (static_cast< ::cppu::OWeakObject
* >(this), css::uno::UNO_QUERY
);
596 xCloseable
->removeCloseListener(xThis
);
597 m_bListenOnModel
= false;
600 catch(const css::uno::Exception
&)
607 @short callback from any asynchronous executed job
609 @descr Our execute() method waits for this callback.
610 We have to react for the possible results here,
611 to kill the running job and disable the blocked condition
612 so execute() can be finished too.
615 the job, which was running and inform us now
620 void SAL_CALL
Job::jobFinished( /*IN*/ const css::uno::Reference
< css::task::XAsyncJob
>& xJob
,
621 /*IN*/ const css::uno::Any
& aResult
) throw(css::uno::RuntimeException
, std::exception
)
625 // It's necessary to check this.
626 // May this job was cancelled by any other reason
627 // some milliseconds before. :-)
628 if (m_xJob
.is() && m_xJob
==xJob
)
630 // react for his results
631 // (means enable/disable it for further requests
632 // or save arguments or notify listener ...)
633 impl_reactForJobResult(aResult
);
636 m_xJob
= css::uno::Reference
< css::uno::XInterface
>();
639 // And let the start method "execute()" finishing it's job.
640 // But do it every time. So any outside blocking code can finish
646 @short prevent internal wrapped job against office termination
647 @descr This event is broadcasted by the desktop instance and ask for an office termination.
648 If the internal wrapped job is still in progress, we disagree with that by throwing the
649 right veto exception. If not - we agree. But then we must be aware, that another event
650 notifyTermination() can follow. Then we have no chance to do the same. Then we have to
651 accept that and stop our work instandly.
654 describes the broadcaster and must be the desktop instance
656 @throw TerminateVetoException
657 if our internal wrapped job is still running.
659 void SAL_CALL
Job::queryTermination( /*IN*/ const css::lang::EventObject
& ) throw(css::frame::TerminationVetoException
,
660 css::uno::RuntimeException
, std::exception
)
664 // Otherwhise try to close() it
665 css::uno::Reference
< css::util::XCloseable
> xClose(m_xJob
, css::uno::UNO_QUERY
);
670 xClose
->close(sal_False
);
671 m_eRunState
= E_STOPPED_OR_FINISHED
;
673 catch(const css::util::CloseVetoException
&) {}
676 if (m_eRunState
!= E_STOPPED_OR_FINISHED
)
678 css::uno::Reference
< css::uno::XInterface
> xThis(static_cast< ::cppu::OWeakObject
* >(this), css::uno::UNO_QUERY
);
679 throw css::frame::TerminationVetoException("job still in progress", xThis
);
684 @short inform us about office termination
685 @descr Instead of the method queryTermination(), here is no chance to disagree with that.
686 We have to accept it and cancel all current processes inside.
687 It can occur only, if job was not already started if queryTermination() was called here ..
688 Then we had not throwed a veto exception. But now we must agree with this situation and break
689 all our internal processes. Its not a good idea to mark this instance as non startable any longer
690 inside queryTermination() if no job was unning too. Because that would disable this job and may
691 the office does not really shutdownm, because another listener has thrown the suitable exception.
694 describes the broadcaster and must be the desktop instance
696 void SAL_CALL
Job::notifyTermination( /*IN*/ const css::lang::EventObject
& ) throw(css::uno::RuntimeException
, std::exception
)
699 // Do nothing else here. Our internal resources was released ...
703 @short prevent internal wrapped job against frame closing
704 @descr This event is broadcasted by the frame instance and ask for closing.
705 If the internal wrapped job is still in progress, we disagree with that by throwing the
706 right veto exception. If not - we agree. But then we must be aware, that another event
707 notifyClosing() can follow. Then we have no chance to do the same. Then we have to
708 accept that and stop our work instandly.
711 describes the broadcaster and must be the frame instance
713 @param bGetsOwnership
714 If it's set to <sal_True> and we throw the right veto excepion, we have to close this frame later
715 if our internal processes will be finished. If it's set to <FALSE/> we can ignore it.
717 @throw CloseVetoException
718 if our internal wrapped job is still running.
720 void SAL_CALL
Job::queryClosing( const css::lang::EventObject
& aEvent
,
721 sal_Bool bGetsOwnership
) throw(css::util::CloseVetoException
,
722 css::uno::RuntimeException
, std::exception
)
726 // do nothing, if no internal job is still running ...
727 // The frame or model can be closed then successfully.
728 if (m_eRunState
!= E_RUNNING
)
731 // try close() first at the job.
732 // The job can agree or disagree with this request.
733 css::uno::Reference
< css::util::XCloseable
> xClose(m_xJob
, css::uno::UNO_QUERY
);
736 xClose
->close(bGetsOwnership
);
737 // Here we can say: "this job was stopped successfully". Because
738 // no veto exception was thrown!
739 m_eRunState
= E_STOPPED_OR_FINISHED
;
743 // try dispose() then
744 // Here the job has no chance for a veto.
745 // But we must be aware of an "already disposed exception"...
748 css::uno::Reference
< css::lang::XComponent
> xDispose(m_xJob
, css::uno::UNO_QUERY
);
752 m_eRunState
= E_DISPOSED
;
755 catch(const css::lang::DisposedException
&)
757 // the job was already disposed by any other mechanism !?
758 // But it's not interesting for us. For us this job is stopped now.
759 m_eRunState
= E_DISPOSED
;
762 if (m_eRunState
!= E_DISPOSED
)
764 // analyze event source - to find out, which resource called queryClosing() at this
765 // job wrapper. We must bind a "pending close" request to this resource.
766 // Closing of the corresponding resource will be done if our internal job finish it's work.
767 m_bPendingCloseFrame
= (m_xFrame
.is() && aEvent
.Source
== m_xFrame
);
768 m_bPendingCloseModel
= (m_xModel
.is() && aEvent
.Source
== m_xModel
);
770 // throw suitable veto exception - because the internal job could not be cancelled.
771 css::uno::Reference
< css::uno::XInterface
> xThis(static_cast< ::cppu::OWeakObject
* >(this), css::uno::UNO_QUERY
);
772 throw css::util::CloseVetoException("job still in progress", xThis
);
776 // But don't call die() here or free our internal member.
777 // This must be done inside notifyClosing() only. Otherwhise the
778 // might stopped job has no chance to return its results or
779 // call us back. We must give him the chance to finish it's work successfully.
783 @short inform us about frame closing
784 @descr Instead of the method queryClosing(), here is no chance to disagree with that.
785 We have to accept it and cancel all current processes inside.
788 describes the broadcaster and must be the frame or model instance we know
790 void SAL_CALL
Job::notifyClosing( const css::lang::EventObject
& ) throw(css::uno::RuntimeException
, std::exception
)
793 // Do nothing else here. Our internal resources was released ...
797 @short shouldn't be called normally
798 @descr But it doesn't matter, who called it. We have to kill our internal
799 running processes hardly.
802 describe the broadcaster
804 void SAL_CALL
Job::disposing( const css::lang::EventObject
& aEvent
) throw(css::uno::RuntimeException
, std::exception
)
807 SolarMutexClearableGuard aWriteLock
;
809 if (m_xDesktop
.is() && aEvent
.Source
== m_xDesktop
)
812 m_bListenOnDesktop
= false;
814 else if (m_xFrame
.is() && aEvent
.Source
== m_xFrame
)
816 m_xFrame
= css::uno::Reference
< css::frame::XFrame
>();
817 m_bListenOnFrame
= false;
819 else if (m_xModel
.is() && aEvent
.Source
== m_xModel
)
821 m_xModel
= css::uno::Reference
< css::frame::XModel
>();
822 m_bListenOnModel
= false;
829 // Do nothing else here. Our internal resources was released ...
832 } // namespace framework
834 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */