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 throw(css::uno::Exception ,
130 css::uno::RuntimeException)
131 {
132 ::comphelper::SequenceAsHashMap lArgs(lArguments);
133
134 // SAFE -> ----------------------------------
135 WriteGuard aWriteLock(m_aLock);
136
137 m_xFrame = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_FRAME , css::uno::Reference< css::frame::XFrame >());
138 m_xPluggWindow = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_WINDOW , css::uno::Reference< css::awt::XWindow >() );
139 m_bAllowParentShow = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_ALLOWPARENTSHOW , (sal_Bool)sal_False );
140 m_bDisableReschedule = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_DISABLERESCHEDULE, (sal_Bool)sal_False );
141
142 aWriteLock.unlock();
143 // <- SAFE ----------------------------------
144
145 impl_createProgress();
146 }
147
148 //-----------------------------------------------
createStatusIndicator()149 css::uno::Reference< css::task::XStatusIndicator > SAL_CALL StatusIndicatorFactory::createStatusIndicator()
150 throw(css::uno::RuntimeException)
151 {
152 StatusIndicator* pIndicator = new StatusIndicator(this);
153 css::uno::Reference< css::task::XStatusIndicator > xIndicator(static_cast< ::cppu::OWeakObject* >(pIndicator), css::uno::UNO_QUERY_THROW);
154
155 return xIndicator;
156 }
157
158 //-----------------------------------------------
update()159 void SAL_CALL StatusIndicatorFactory::update()
160 throw(css::uno::RuntimeException)
161 {
162 // SAFE -> ----------------------------------
163 WriteGuard aWriteLock(m_aLock);
164 m_bAllowReschedule = sal_True;
165 aWriteLock.unlock();
166 // <- SAFE ----------------------------------
167 }
168
169 //-----------------------------------------------
start(const css::uno::Reference<css::task::XStatusIndicator> & xChild,const::rtl::OUString & sText,sal_Int32 nRange)170 void StatusIndicatorFactory::start(const css::uno::Reference< css::task::XStatusIndicator >& xChild,
171 const ::rtl::OUString& sText ,
172 sal_Int32 nRange)
173 {
174 // SAFE -> ----------------------------------
175 WriteGuard aWriteLock(m_aLock);
176
177 // create new info structure for this child or move it to the front of our stack
178 IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
179 if (pItem != m_aStack.end())
180 m_aStack.erase(pItem);
181 IndicatorInfo aInfo(xChild, sText, nRange);
182 m_aStack.push_back (aInfo );
183
184 m_xActiveChild = xChild;
185 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress;
186
187 aWriteLock.unlock();
188 // <- SAFE ----------------------------------
189
190 implts_makeParentVisibleIfAllowed();
191
192 if (xProgress.is())
193 xProgress->start(sText, nRange);
194
195 impl_startWakeUpThread();
196 impl_reschedule(sal_True);
197 }
198
199 //-----------------------------------------------
reset(const css::uno::Reference<css::task::XStatusIndicator> & xChild)200 void StatusIndicatorFactory::reset(const css::uno::Reference< css::task::XStatusIndicator >& xChild)
201 {
202 // SAFE -> ----------------------------------
203 ReadGuard aReadLock(m_aLock);
204
205 // reset the internal info structure related to this child
206 IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
207 if (pItem != m_aStack.end())
208 {
209 pItem->m_nValue = 0;
210 pItem->m_sText = ::rtl::OUString();
211 }
212
213 css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild;
214 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress;
215
216 aReadLock.unlock();
217 // <- SAFE ----------------------------------
218
219 // not the top most child => dont change UI
220 // But dont forget Reschedule!
221 if (
222 (xChild == xActive) &&
223 (xProgress.is() )
224 )
225 xProgress->reset();
226
227 impl_reschedule(sal_True);
228 }
229
230 //-----------------------------------------------
end(const css::uno::Reference<css::task::XStatusIndicator> & xChild)231 void StatusIndicatorFactory::end(const css::uno::Reference< css::task::XStatusIndicator >& xChild)
232 {
233 // SAFE -> ----------------------------------
234 WriteGuard aWriteLock(m_aLock);
235
236 // remove this child from our stack
237 IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
238 if (pItem != m_aStack.end())
239 m_aStack.erase(pItem);
240
241 // activate next child ... or finish the progress if there is no further one.
242 m_xActiveChild.clear();
243 ::rtl::OUString sText;
244 sal_Int32 nValue = 0;
245 IndicatorStack::reverse_iterator pNext = m_aStack.rbegin();
246 if (pNext != m_aStack.rend())
247 {
248 m_xActiveChild = pNext->m_xIndicator;
249 sText = pNext->m_sText;
250 nValue = pNext->m_nValue;
251 }
252
253 css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild;
254 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress;
255
256 aWriteLock.unlock();
257 // <- SAFE ----------------------------------
258
259 if (xActive.is())
260 {
261 // There is at least one further child indicator.
262 // Actualize our progress, so it shows these values from now.
263 if (xProgress.is())
264 {
265 xProgress->setText (sText );
266 xProgress->setValue(nValue);
267 }
268 }
269 else
270 {
271 // Our stack is empty. No further child exists.
272 // Se we must "end" our progress really
273 if (xProgress.is())
274 xProgress->end();
275 // Now hide the progress bar again.
276 impl_hideProgress();
277
278 impl_stopWakeUpThread();
279 }
280
281 impl_reschedule(sal_True);
282 }
283
284 //-----------------------------------------------
setText(const css::uno::Reference<css::task::XStatusIndicator> & xChild,const::rtl::OUString & sText)285 void StatusIndicatorFactory::setText(const css::uno::Reference< css::task::XStatusIndicator >& xChild,
286 const ::rtl::OUString& sText )
287 {
288 // SAFE -> ----------------------------------
289 WriteGuard aWriteLock(m_aLock);
290
291 IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
292 if (pItem != m_aStack.end())
293 pItem->m_sText = sText;
294
295 css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild;
296 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress;
297
298 aWriteLock.unlock();
299 // SAFE -> ----------------------------------
300
301 // paint only the top most indicator
302 // but dont forget to Reschedule!
303 if (
304 (xChild == xActive) &&
305 (xProgress.is() )
306 )
307 {
308 xProgress->setText(sText);
309 }
310
311 impl_reschedule(sal_True);
312 }
313
314 //-----------------------------------------------
setValue(const css::uno::Reference<css::task::XStatusIndicator> & xChild,sal_Int32 nValue)315 void StatusIndicatorFactory::setValue( const css::uno::Reference< css::task::XStatusIndicator >& xChild ,
316 sal_Int32 nValue )
317 {
318 // SAFE -> ----------------------------------
319 WriteGuard aWriteLock(m_aLock);
320
321 sal_Int32 nOldValue = 0;
322 IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
323 if (pItem != m_aStack.end())
324 {
325 nOldValue = pItem->m_nValue;
326 pItem->m_nValue = nValue;
327 }
328
329 css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild;
330 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress;
331
332 aWriteLock.unlock();
333 // SAFE -> ----------------------------------
334
335 if (
336 (xChild == xActive) &&
337 (nOldValue != nValue ) &&
338 (xProgress.is() )
339 )
340 {
341 xProgress->setValue(nValue);
342 }
343
344 impl_reschedule(sal_False);
345 }
346
347 //-----------------------------------------------
implts_makeParentVisibleIfAllowed()348 void StatusIndicatorFactory::implts_makeParentVisibleIfAllowed()
349 {
350 // SAFE -> ----------------------------------
351 ReadGuard aReadLock(m_aLock);
352
353 if (!m_bAllowParentShow)
354 return;
355
356 css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY);
357 css::uno::Reference< css::awt::XWindow > xPluggWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY);
358 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xSMGR.get(), css::uno::UNO_QUERY);
359
360 aReadLock.unlock();
361 // <- SAFE ----------------------------------
362
363 css::uno::Reference< css::awt::XWindow > xParentWindow;
364 if (xFrame.is())
365 xParentWindow = xFrame->getContainerWindow();
366 else
367 xParentWindow = xPluggWindow;
368
369 // dont disturb user in case he put the loading document into the background!
370 // Suppress any setVisible() or toFront() call in case the initial show was
371 // already made.
372 css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(xParentWindow, css::uno::UNO_QUERY);
373 sal_Bool bIsVisible = sal_False;
374 if (xVisibleCheck.is())
375 bIsVisible = xVisibleCheck->isVisible();
376
377 if (bIsVisible)
378 {
379 impl_showProgress();
380 return;
381 }
382
383 // Check if the layout manager has been set to invisible state. It this case we are also
384 // not allowed to set the frame visible!
385 css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
386 if (xPropSet.is())
387 {
388 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
389 xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
390 if (xLayoutManager.is())
391 {
392 if ( !xLayoutManager->isVisible() )
393 return;
394 }
395 }
396
397 // Ok the window should be made visible ... because it isn't currently visible.
398 // BUT ..!
399 // We need a Hack for our applications: They get her progress from the frame directly
400 // on saving documents. Because there is no progress set on the MediaDescriptor.
401 // But that's wrong. In case the document was opened hidden, they shouldn't use any progress .-(
402 // They only possible workaround: dont show the parent window here, if the document was opened hidden.
403 sal_Bool bHiddenDoc = sal_False;
404 if (xFrame.is())
405 {
406 css::uno::Reference< css::frame::XController > xController;
407 css::uno::Reference< css::frame::XModel > xModel ;
408 xController = xFrame->getController();
409 if (xController.is())
410 xModel = xController->getModel();
411 if (xModel.is())
412 {
413 ::comphelper::MediaDescriptor lDocArgs(xModel->getArgs());
414 bHiddenDoc = lDocArgs.getUnpackedValueOrDefault(
415 ::comphelper::MediaDescriptor::PROP_HIDDEN(),
416 (sal_Bool)sal_False);
417 }
418 }
419
420 if (bHiddenDoc)
421 return;
422
423 // OK: The document was not opened in hidden mode ...
424 // and the window isn't already visible.
425 // Show it and bring it to front.
426 // But before we have to be sure, that our internal used helper progress
427 // is visible too.
428 impl_showProgress();
429
430 ::vos::OClearableGuard aSolarGuard(Application::GetSolarMutex());
431 Window* pWindow = VCLUnoHelper::GetWindow(xParentWindow);
432 if ( pWindow )
433 {
434 bool bForceFrontAndFocus(false);
435 ::comphelper::ConfigurationHelper::readDirectKey(
436 xSMGR,
437 ::rtl::OUString::createFromAscii("org.openoffice.Office.Common/View"),
438 ::rtl::OUString::createFromAscii("NewDocumentHandling"),
439 ::rtl::OUString::createFromAscii("ForceFocusAndToFront"),
440 ::comphelper::ConfigurationHelper::E_READONLY) >>= bForceFrontAndFocus;
441
442 pWindow->Show(sal_True, bForceFrontAndFocus ? SHOW_FOREGROUNDTASK : 0 );
443 }
444
445 /*
446 #i75167# dont disturb window manager handling .-)
447 css::uno::Reference< css::awt::XTopWindow > xParentWindowTop(xParentWindow, css::uno::UNO_QUERY);
448 if (xParentWindowTop.is())
449 xParentWindowTop->toFront();
450 */
451 }
452
453 //-----------------------------------------------
impl_createProgress()454 void StatusIndicatorFactory::impl_createProgress()
455 {
456 // SAFE -> ----------------------------------
457 ReadGuard aReadLock(m_aLock);
458
459 css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY);
460 css::uno::Reference< css::awt::XWindow > xWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY);
461 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
462
463 aReadLock.lock();
464 // <- SAFE ----------------------------------
465
466 css::uno::Reference< css::task::XStatusIndicator > xProgress;
467
468 if (xWindow.is())
469 {
470 // use vcl based progress implementation in plugged mode
471 VCLStatusIndicator* pVCLProgress = new VCLStatusIndicator(xSMGR, xWindow);
472 xProgress = css::uno::Reference< css::task::XStatusIndicator >(static_cast< css::task::XStatusIndicator* >(pVCLProgress), css::uno::UNO_QUERY);
473 }
474 else
475 if (xFrame.is())
476 {
477 // use frame layouted progress implementation
478 css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
479 if (xPropSet.is())
480 {
481 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
482 xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
483 if (xLayoutManager.is())
484 {
485 xLayoutManager->lock();
486 xLayoutManager->createElement( PROGRESS_RESOURCE );
487 xLayoutManager->hideElement( PROGRESS_RESOURCE );
488
489 css::uno::Reference< css::ui::XUIElement > xProgressBar = xLayoutManager->getElement(PROGRESS_RESOURCE);
490 if (xProgressBar.is())
491 xProgress = css::uno::Reference< css::task::XStatusIndicator >(xProgressBar->getRealInterface(), css::uno::UNO_QUERY);
492 xLayoutManager->unlock();
493 }
494 }
495 }
496
497 // SAFE -> ----------------------------------
498 WriteGuard aWriteLock(m_aLock);
499 m_xProgress = xProgress;
500 aWriteLock.lock();
501 // <- SAFE ----------------------------------
502 }
503
504 //-----------------------------------------------
impl_showProgress()505 void StatusIndicatorFactory::impl_showProgress()
506 {
507 // SAFE -> ----------------------------------
508 ReadGuard aReadLock(m_aLock);
509
510 css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY);
511 css::uno::Reference< css::awt::XWindow > xWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY);
512 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
513
514 aReadLock.lock();
515 // <- SAFE ----------------------------------
516
517 css::uno::Reference< css::task::XStatusIndicator > xProgress;
518
519 if (xFrame.is())
520 {
521 // use frame layouted progress implementation
522 css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
523 if (xPropSet.is())
524 {
525 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
526 xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
527 if (xLayoutManager.is())
528 {
529 // Be sure that we have always a progress. It can be that our frame
530 // was recycled and therefore the progress was destroyed!
531 // CreateElement does nothing if there is already a valid progress.
532 xLayoutManager->createElement( PROGRESS_RESOURCE );
533 xLayoutManager->showElement( PROGRESS_RESOURCE );
534
535 css::uno::Reference< css::ui::XUIElement > xProgressBar = xLayoutManager->getElement(PROGRESS_RESOURCE);
536 if (xProgressBar.is())
537 xProgress = css::uno::Reference< css::task::XStatusIndicator >(xProgressBar->getRealInterface(), css::uno::UNO_QUERY);
538 }
539 }
540
541 // SAFE -> ----------------------------------
542 WriteGuard aWriteLock(m_aLock);
543 m_xProgress = xProgress;
544 aWriteLock.lock();
545 // <- SAFE ----------------------------------
546 }
547 }
548
549 //-----------------------------------------------
impl_hideProgress()550 void StatusIndicatorFactory::impl_hideProgress()
551 {
552 // SAFE -> ----------------------------------
553 ReadGuard aReadLock(m_aLock);
554
555 css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY);
556 css::uno::Reference< css::awt::XWindow > xWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY);
557 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
558
559 aReadLock.lock();
560 // <- SAFE ----------------------------------
561
562 if (xFrame.is())
563 {
564 // use frame layouted progress implementation
565 css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
566 if (xPropSet.is())
567 {
568 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
569 xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
570 if (xLayoutManager.is())
571 xLayoutManager->hideElement( PROGRESS_RESOURCE );
572 }
573 }
574 }
575
576 //-----------------------------------------------
impl_reschedule(sal_Bool bForce)577 void StatusIndicatorFactory::impl_reschedule(sal_Bool bForce)
578 {
579 // SAFE ->
580 ReadGuard aReadLock(m_aLock);
581 if (m_bDisableReschedule)
582 return;
583 aReadLock.unlock();
584 // <- SAFE
585
586 sal_Bool bReschedule = bForce;
587 if (!bReschedule)
588 {
589 // SAFE ->
590 WriteGuard aWriteLock(m_aLock);
591 bReschedule = m_bAllowReschedule;
592 m_bAllowReschedule = sal_False;
593 aWriteLock.unlock();
594 // <- SAFE
595 }
596
597 if (!bReschedule)
598 return;
599
600 // SAFE ->
601 WriteGuard aGlobalLock(LockHelper::getGlobalLock());
602
603 if (m_nInReschedule == 0)
604 {
605 ++m_nInReschedule;
606 aGlobalLock.unlock();
607 // <- SAFE
608
609 Application::Reschedule(true);
610
611 // SAFE ->
612 aGlobalLock.lock();
613 --m_nInReschedule;
614 }
615 }
616
617 //-----------------------------------------------
impl_startWakeUpThread()618 void StatusIndicatorFactory::impl_startWakeUpThread()
619 {
620 // SAFE ->
621 WriteGuard aWriteLock(m_aLock);
622
623 if (m_bDisableReschedule)
624 return;
625
626 if (!m_pWakeUp)
627 {
628 m_pWakeUp = new WakeUpThread(this);
629 m_pWakeUp->create();
630 }
631 aWriteLock.unlock();
632 // <- SAFE
633 }
634
635 //-----------------------------------------------
impl_stopWakeUpThread()636 void StatusIndicatorFactory::impl_stopWakeUpThread()
637 {
638 // SAFE ->
639 WriteGuard aWriteLock(m_aLock);
640 if (m_pWakeUp)
641 {
642 // Thread kill itself after terminate()!
643 m_pWakeUp->terminate();
644 m_pWakeUp = 0;
645 }
646 aWriteLock.unlock();
647 // <- SAFE
648 }
649
650 } // namespace framework
651