1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_framework.hxx"
26
27 //-----------------------------------------------
28 // my own includes
29
30 #include <algorithm>
31 #include <helper/statusindicatorfactory.hxx>
32 #include <helper/statusindicator.hxx>
33 #include <helper/vclstatusindicator.hxx>
34 #include <threadhelp/writeguard.hxx>
35 #include <threadhelp/readguard.hxx>
36 #include <services.h>
37 #include <properties.h>
38
39 //-----------------------------------------------
40 // interface includes
41 #include <com/sun/star/awt/Rectangle.hpp>
42
43 #ifndef _COM_SUN_STAR_AWT_XCONTROLS_HPP_
44 #include <com/sun/star/awt/XControl.hpp>
45 #endif
46 #include <com/sun/star/awt/XLayoutConstrains.hpp>
47 #include <com/sun/star/awt/DeviceInfo.hpp>
48 #include <com/sun/star/awt/PosSize.hpp>
49 #include <com/sun/star/awt/WindowAttribute.hpp>
50 #include <com/sun/star/awt/XTopWindow.hpp>
51 #include <com/sun/star/awt/XWindow2.hpp>
52 #include <com/sun/star/beans/XPropertySet.hpp>
53 #include <com/sun/star/frame/XLayoutManager.hpp>
54
55 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
56 #include <toolkit/helper/vclunohelper.hxx>
57 #endif
58
59 //-----------------------------------------------
60 // includes of other projects
61 #include <comphelper/sequenceashashmap.hxx>
62 #include <comphelper/mediadescriptor.hxx>
63 #include <comphelper/configurationhelper.hxx>
64 #include <vcl/svapp.hxx>
65 #include <vos/mutex.hxx>
66
67 //-----------------------------------------------
68 // namespace
69
70 namespace framework{
71
72 //-----------------------------------------------
73 // definitions
74
75 sal_Int32 StatusIndicatorFactory::m_nInReschedule = 0; /// static counter for rescheduling
76 static ::rtl::OUString PROGRESS_RESOURCE = ::rtl::OUString::createFromAscii("private:resource/progressbar/progressbar");
77
78 //-----------------------------------------------
DEFINE_XINTERFACE_5(StatusIndicatorFactory,OWeakObject,DIRECT_INTERFACE (css::lang::XTypeProvider),DIRECT_INTERFACE (css::lang::XServiceInfo),DIRECT_INTERFACE (css::lang::XInitialization),DIRECT_INTERFACE (css::task::XStatusIndicatorFactory),DIRECT_INTERFACE (css::util::XUpdatable))79 DEFINE_XINTERFACE_5(StatusIndicatorFactory ,
80 OWeakObject ,
81 DIRECT_INTERFACE(css::lang::XTypeProvider ),
82 DIRECT_INTERFACE(css::lang::XServiceInfo ),
83 DIRECT_INTERFACE(css::lang::XInitialization ),
84 DIRECT_INTERFACE(css::task::XStatusIndicatorFactory),
85 DIRECT_INTERFACE(css::util::XUpdatable ))
86
87 DEFINE_XTYPEPROVIDER_5(StatusIndicatorFactory ,
88 css::lang::XTypeProvider ,
89 css::lang::XServiceInfo ,
90 css::lang::XInitialization ,
91 css::task::XStatusIndicatorFactory,
92 css::util::XUpdatable )
93
94 DEFINE_XSERVICEINFO_MULTISERVICE(StatusIndicatorFactory ,
95 ::cppu::OWeakObject ,
96 SERVICENAME_STATUSINDICATORFACTORY ,
97 IMPLEMENTATIONNAME_STATUSINDICATORFACTORY)
98
99 DEFINE_INIT_SERVICE(StatusIndicatorFactory,
100 {
101 /*Attention
102 I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
103 to create a new instance of this class by our own supported service factory.
104 see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
105 */
106 }
107 )
108
109 //-----------------------------------------------
110 StatusIndicatorFactory::StatusIndicatorFactory(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
111 : ThreadHelpBase ( )
112 , ::cppu::OWeakObject ( )
113 , m_xSMGR (xSMGR )
114 , m_pWakeUp (0 )
115 , m_bAllowReschedule (sal_False)
116 , m_bAllowParentShow (sal_False)
117 , m_bDisableReschedule(sal_False)
118 {
119 }
120
121 //-----------------------------------------------
~StatusIndicatorFactory()122 StatusIndicatorFactory::~StatusIndicatorFactory()
123 {
124 impl_stopWakeUpThread();
125 }
126
127 //-----------------------------------------------
initialize(const css::uno::Sequence<css::uno::Any> & lArguments)128 void SAL_CALL StatusIndicatorFactory::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
129 {
130 ::comphelper::SequenceAsHashMap lArgs(lArguments);
131
132 // SAFE -> ----------------------------------
133 WriteGuard aWriteLock(m_aLock);
134
135 m_xFrame = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_FRAME , css::uno::Reference< css::frame::XFrame >());
136 m_xPluggWindow = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_WINDOW , css::uno::Reference< css::awt::XWindow >() );
137 m_bAllowParentShow = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_ALLOWPARENTSHOW , (sal_Bool)sal_False );
138 m_bDisableReschedule = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_DISABLERESCHEDULE, (sal_Bool)sal_False );
139
140 aWriteLock.unlock();
141 // <- SAFE ----------------------------------
142
143 impl_createProgress();
144 }
145
146 //-----------------------------------------------
createStatusIndicator()147 css::uno::Reference< css::task::XStatusIndicator > SAL_CALL StatusIndicatorFactory::createStatusIndicator()
148 {
149 StatusIndicator* pIndicator = new StatusIndicator(this);
150 css::uno::Reference< css::task::XStatusIndicator > xIndicator(static_cast< ::cppu::OWeakObject* >(pIndicator), css::uno::UNO_QUERY_THROW);
151
152 return xIndicator;
153 }
154
155 //-----------------------------------------------
update()156 void SAL_CALL StatusIndicatorFactory::update()
157 {
158 // SAFE -> ----------------------------------
159 WriteGuard aWriteLock(m_aLock);
160 m_bAllowReschedule = sal_True;
161 aWriteLock.unlock();
162 // <- SAFE ----------------------------------
163 }
164
165 //-----------------------------------------------
start(const css::uno::Reference<css::task::XStatusIndicator> & xChild,const::rtl::OUString & sText,sal_Int32 nRange)166 void StatusIndicatorFactory::start(const css::uno::Reference< css::task::XStatusIndicator >& xChild,
167 const ::rtl::OUString& sText ,
168 sal_Int32 nRange)
169 {
170 // SAFE -> ----------------------------------
171 WriteGuard aWriteLock(m_aLock);
172
173 // create new info structure for this child or move it to the front of our stack
174 IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
175 if (pItem != m_aStack.end())
176 m_aStack.erase(pItem);
177 IndicatorInfo aInfo(xChild, sText, nRange);
178 m_aStack.push_back (aInfo );
179
180 m_xActiveChild = xChild;
181 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress;
182
183 aWriteLock.unlock();
184 // <- SAFE ----------------------------------
185
186 implts_makeParentVisibleIfAllowed();
187
188 if (xProgress.is())
189 xProgress->start(sText, nRange);
190
191 impl_startWakeUpThread();
192 impl_reschedule(sal_True);
193 }
194
195 //-----------------------------------------------
reset(const css::uno::Reference<css::task::XStatusIndicator> & xChild)196 void StatusIndicatorFactory::reset(const css::uno::Reference< css::task::XStatusIndicator >& xChild)
197 {
198 // SAFE -> ----------------------------------
199 ReadGuard aReadLock(m_aLock);
200
201 // reset the internal info structure related to this child
202 IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
203 if (pItem != m_aStack.end())
204 {
205 pItem->m_nValue = 0;
206 pItem->m_sText = ::rtl::OUString();
207 }
208
209 css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild;
210 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress;
211
212 aReadLock.unlock();
213 // <- SAFE ----------------------------------
214
215 // not the top most child => dont change UI
216 // But dont forget Reschedule!
217 if (
218 (xChild == xActive) &&
219 (xProgress.is() )
220 )
221 xProgress->reset();
222
223 impl_reschedule(sal_True);
224 }
225
226 //-----------------------------------------------
end(const css::uno::Reference<css::task::XStatusIndicator> & xChild)227 void StatusIndicatorFactory::end(const css::uno::Reference< css::task::XStatusIndicator >& xChild)
228 {
229 // SAFE -> ----------------------------------
230 WriteGuard aWriteLock(m_aLock);
231
232 // remove this child from our stack
233 IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
234 if (pItem != m_aStack.end())
235 m_aStack.erase(pItem);
236
237 // activate next child ... or finish the progress if there is no further one.
238 m_xActiveChild.clear();
239 ::rtl::OUString sText;
240 sal_Int32 nValue = 0;
241 IndicatorStack::reverse_iterator pNext = m_aStack.rbegin();
242 if (pNext != m_aStack.rend())
243 {
244 m_xActiveChild = pNext->m_xIndicator;
245 sText = pNext->m_sText;
246 nValue = pNext->m_nValue;
247 }
248
249 css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild;
250 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress;
251
252 aWriteLock.unlock();
253 // <- SAFE ----------------------------------
254
255 if (xActive.is())
256 {
257 // There is at least one further child indicator.
258 // Actualize our progress, so it shows these values from now.
259 if (xProgress.is())
260 {
261 xProgress->setText (sText );
262 xProgress->setValue(nValue);
263 }
264 }
265 else
266 {
267 // Our stack is empty. No further child exists.
268 // Se we must "end" our progress really
269 if (xProgress.is())
270 xProgress->end();
271 // Now hide the progress bar again.
272 impl_hideProgress();
273
274 impl_stopWakeUpThread();
275 }
276
277 impl_reschedule(sal_True);
278 }
279
280 //-----------------------------------------------
setText(const css::uno::Reference<css::task::XStatusIndicator> & xChild,const::rtl::OUString & sText)281 void StatusIndicatorFactory::setText(const css::uno::Reference< css::task::XStatusIndicator >& xChild,
282 const ::rtl::OUString& sText )
283 {
284 // SAFE -> ----------------------------------
285 WriteGuard aWriteLock(m_aLock);
286
287 IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
288 if (pItem != m_aStack.end())
289 pItem->m_sText = sText;
290
291 css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild;
292 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress;
293
294 aWriteLock.unlock();
295 // SAFE -> ----------------------------------
296
297 // paint only the top most indicator
298 // but dont forget to Reschedule!
299 if (
300 (xChild == xActive) &&
301 (xProgress.is() )
302 )
303 {
304 xProgress->setText(sText);
305 }
306
307 impl_reschedule(sal_True);
308 }
309
310 //-----------------------------------------------
setValue(const css::uno::Reference<css::task::XStatusIndicator> & xChild,sal_Int32 nValue)311 void StatusIndicatorFactory::setValue( const css::uno::Reference< css::task::XStatusIndicator >& xChild ,
312 sal_Int32 nValue )
313 {
314 // SAFE -> ----------------------------------
315 WriteGuard aWriteLock(m_aLock);
316
317 sal_Int32 nOldValue = 0;
318 IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
319 if (pItem != m_aStack.end())
320 {
321 nOldValue = pItem->m_nValue;
322 pItem->m_nValue = nValue;
323 }
324
325 css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild;
326 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress;
327
328 aWriteLock.unlock();
329 // SAFE -> ----------------------------------
330
331 if (
332 (xChild == xActive) &&
333 (nOldValue != nValue ) &&
334 (xProgress.is() )
335 )
336 {
337 xProgress->setValue(nValue);
338 }
339
340 impl_reschedule(sal_False);
341 }
342
343 //-----------------------------------------------
implts_makeParentVisibleIfAllowed()344 void StatusIndicatorFactory::implts_makeParentVisibleIfAllowed()
345 {
346 // SAFE -> ----------------------------------
347 ReadGuard aReadLock(m_aLock);
348
349 if (!m_bAllowParentShow)
350 return;
351
352 css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY);
353 css::uno::Reference< css::awt::XWindow > xPluggWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY);
354 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xSMGR.get(), css::uno::UNO_QUERY);
355
356 aReadLock.unlock();
357 // <- SAFE ----------------------------------
358
359 css::uno::Reference< css::awt::XWindow > xParentWindow;
360 if (xFrame.is())
361 xParentWindow = xFrame->getContainerWindow();
362 else
363 xParentWindow = xPluggWindow;
364
365 // dont disturb user in case he put the loading document into the background!
366 // Suppress any setVisible() or toFront() call in case the initial show was
367 // already made.
368 css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(xParentWindow, css::uno::UNO_QUERY);
369 sal_Bool bIsVisible = sal_False;
370 if (xVisibleCheck.is())
371 bIsVisible = xVisibleCheck->isVisible();
372
373 if (bIsVisible)
374 {
375 impl_showProgress();
376 return;
377 }
378
379 // Check if the layout manager has been set to invisible state. It this case we are also
380 // not allowed to set the frame visible!
381 css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
382 if (xPropSet.is())
383 {
384 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
385 xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
386 if (xLayoutManager.is())
387 {
388 if ( !xLayoutManager->isVisible() )
389 return;
390 }
391 }
392
393 // Ok the window should be made visible ... because it isn't currently visible.
394 // BUT ..!
395 // We need a Hack for our applications: They get her progress from the frame directly
396 // on saving documents. Because there is no progress set on the MediaDescriptor.
397 // But that's wrong. In case the document was opened hidden, they shouldn't use any progress .-(
398 // They only possible workaround: dont show the parent window here, if the document was opened hidden.
399 sal_Bool bHiddenDoc = sal_False;
400 if (xFrame.is())
401 {
402 css::uno::Reference< css::frame::XController > xController;
403 css::uno::Reference< css::frame::XModel > xModel ;
404 xController = xFrame->getController();
405 if (xController.is())
406 xModel = xController->getModel();
407 if (xModel.is())
408 {
409 ::comphelper::MediaDescriptor lDocArgs(xModel->getArgs());
410 bHiddenDoc = lDocArgs.getUnpackedValueOrDefault(
411 ::comphelper::MediaDescriptor::PROP_HIDDEN(),
412 (sal_Bool)sal_False);
413 }
414 }
415
416 if (bHiddenDoc)
417 return;
418
419 // OK: The document was not opened in hidden mode ...
420 // and the window isn't already visible.
421 // Show it and bring it to front.
422 // But before we have to be sure, that our internal used helper progress
423 // is visible too.
424 impl_showProgress();
425
426 ::vos::OClearableGuard aSolarGuard(Application::GetSolarMutex());
427 Window* pWindow = VCLUnoHelper::GetWindow(xParentWindow);
428 if ( pWindow )
429 {
430 bool bForceFrontAndFocus(false);
431 ::comphelper::ConfigurationHelper::readDirectKey(
432 xSMGR,
433 ::rtl::OUString::createFromAscii("org.openoffice.Office.Common/View"),
434 ::rtl::OUString::createFromAscii("NewDocumentHandling"),
435 ::rtl::OUString::createFromAscii("ForceFocusAndToFront"),
436 ::comphelper::ConfigurationHelper::E_READONLY) >>= bForceFrontAndFocus;
437
438 pWindow->Show(sal_True, bForceFrontAndFocus ? SHOW_FOREGROUNDTASK : 0 );
439 }
440
441 /*
442 #i75167# dont disturb window manager handling .-)
443 css::uno::Reference< css::awt::XTopWindow > xParentWindowTop(xParentWindow, css::uno::UNO_QUERY);
444 if (xParentWindowTop.is())
445 xParentWindowTop->toFront();
446 */
447 }
448
449 //-----------------------------------------------
impl_createProgress()450 void StatusIndicatorFactory::impl_createProgress()
451 {
452 // SAFE -> ----------------------------------
453 ReadGuard aReadLock(m_aLock);
454
455 css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY);
456 css::uno::Reference< css::awt::XWindow > xWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY);
457 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
458
459 aReadLock.lock();
460 // <- SAFE ----------------------------------
461
462 css::uno::Reference< css::task::XStatusIndicator > xProgress;
463
464 if (xWindow.is())
465 {
466 // use vcl based progress implementation in plugged mode
467 VCLStatusIndicator* pVCLProgress = new VCLStatusIndicator(xSMGR, xWindow);
468 xProgress = css::uno::Reference< css::task::XStatusIndicator >(static_cast< css::task::XStatusIndicator* >(pVCLProgress), css::uno::UNO_QUERY);
469 }
470 else
471 if (xFrame.is())
472 {
473 // use frame layouted progress implementation
474 css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
475 if (xPropSet.is())
476 {
477 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
478 xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
479 if (xLayoutManager.is())
480 {
481 xLayoutManager->lock();
482 xLayoutManager->createElement( PROGRESS_RESOURCE );
483 xLayoutManager->hideElement( PROGRESS_RESOURCE );
484
485 css::uno::Reference< css::ui::XUIElement > xProgressBar = xLayoutManager->getElement(PROGRESS_RESOURCE);
486 if (xProgressBar.is())
487 xProgress = css::uno::Reference< css::task::XStatusIndicator >(xProgressBar->getRealInterface(), css::uno::UNO_QUERY);
488 xLayoutManager->unlock();
489 }
490 }
491 }
492
493 // SAFE -> ----------------------------------
494 WriteGuard aWriteLock(m_aLock);
495 m_xProgress = xProgress;
496 aWriteLock.lock();
497 // <- SAFE ----------------------------------
498 }
499
500 //-----------------------------------------------
impl_showProgress()501 void StatusIndicatorFactory::impl_showProgress()
502 {
503 // SAFE -> ----------------------------------
504 ReadGuard aReadLock(m_aLock);
505
506 css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY);
507 css::uno::Reference< css::awt::XWindow > xWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY);
508 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
509
510 aReadLock.lock();
511 // <- SAFE ----------------------------------
512
513 css::uno::Reference< css::task::XStatusIndicator > xProgress;
514
515 if (xFrame.is())
516 {
517 // use frame layouted progress implementation
518 css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
519 if (xPropSet.is())
520 {
521 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
522 xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
523 if (xLayoutManager.is())
524 {
525 // Be sure that we have always a progress. It can be that our frame
526 // was recycled and therefore the progress was destroyed!
527 // CreateElement does nothing if there is already a valid progress.
528 xLayoutManager->createElement( PROGRESS_RESOURCE );
529 xLayoutManager->showElement( PROGRESS_RESOURCE );
530
531 css::uno::Reference< css::ui::XUIElement > xProgressBar = xLayoutManager->getElement(PROGRESS_RESOURCE);
532 if (xProgressBar.is())
533 xProgress = css::uno::Reference< css::task::XStatusIndicator >(xProgressBar->getRealInterface(), css::uno::UNO_QUERY);
534 }
535 }
536
537 // SAFE -> ----------------------------------
538 WriteGuard aWriteLock(m_aLock);
539 m_xProgress = xProgress;
540 aWriteLock.lock();
541 // <- SAFE ----------------------------------
542 }
543 }
544
545 //-----------------------------------------------
impl_hideProgress()546 void StatusIndicatorFactory::impl_hideProgress()
547 {
548 // SAFE -> ----------------------------------
549 ReadGuard aReadLock(m_aLock);
550
551 css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY);
552 css::uno::Reference< css::awt::XWindow > xWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY);
553 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
554
555 aReadLock.lock();
556 // <- SAFE ----------------------------------
557
558 if (xFrame.is())
559 {
560 // use frame layouted progress implementation
561 css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
562 if (xPropSet.is())
563 {
564 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
565 xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
566 if (xLayoutManager.is())
567 xLayoutManager->hideElement( PROGRESS_RESOURCE );
568 }
569 }
570 }
571
572 //-----------------------------------------------
impl_reschedule(sal_Bool bForce)573 void StatusIndicatorFactory::impl_reschedule(sal_Bool bForce)
574 {
575 // SAFE ->
576 ReadGuard aReadLock(m_aLock);
577 if (m_bDisableReschedule)
578 return;
579 aReadLock.unlock();
580 // <- SAFE
581
582 sal_Bool bReschedule = bForce;
583 if (!bReschedule)
584 {
585 // SAFE ->
586 WriteGuard aWriteLock(m_aLock);
587 bReschedule = m_bAllowReschedule;
588 m_bAllowReschedule = sal_False;
589 aWriteLock.unlock();
590 // <- SAFE
591 }
592
593 if (!bReschedule)
594 return;
595
596 // SAFE ->
597 WriteGuard aGlobalLock(LockHelper::getGlobalLock());
598
599 if (m_nInReschedule == 0)
600 {
601 ++m_nInReschedule;
602 aGlobalLock.unlock();
603 // <- SAFE
604
605 Application::Reschedule(true);
606
607 // SAFE ->
608 aGlobalLock.lock();
609 --m_nInReschedule;
610 }
611 }
612
613 //-----------------------------------------------
impl_startWakeUpThread()614 void StatusIndicatorFactory::impl_startWakeUpThread()
615 {
616 // SAFE ->
617 WriteGuard aWriteLock(m_aLock);
618
619 if (m_bDisableReschedule)
620 return;
621
622 if (!m_pWakeUp)
623 {
624 m_pWakeUp = new WakeUpThread(this);
625 m_pWakeUp->create();
626 }
627 aWriteLock.unlock();
628 // <- SAFE
629 }
630
631 //-----------------------------------------------
impl_stopWakeUpThread()632 void StatusIndicatorFactory::impl_stopWakeUpThread()
633 {
634 // SAFE ->
635 WriteGuard aWriteLock(m_aLock);
636 if (m_pWakeUp)
637 {
638 // Thread kill itself after terminate()!
639 m_pWakeUp->terminate();
640 m_pWakeUp = 0;
641 }
642 aWriteLock.unlock();
643 // <- SAFE
644 }
645
646 } // namespace framework
647