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