1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef __FRAMEWORK_HELPER_STATUSINDICATORFACTORY_HXX_
29 #define __FRAMEWORK_HELPER_STATUSINDICATORFACTORY_HXX_
30 
31 // Attention: stl headers must(!) be included at first. Otherwhise it can make trouble
32 // with solaris headers ...
33 #include <vector>
34 
35 //_______________________________________________
36 // include files of own module
37 #include <helper/wakeupthread.hxx>
38 #include <threadhelp/threadhelpbase.hxx>
39 #include <macros/xinterface.hxx>
40 #include <macros/xtypeprovider.hxx>
41 #include <macros/xserviceinfo.hxx>
42 #include <macros/debug.hxx>
43 #include <macros/generic.hxx>
44 #include <general.h>
45 
46 //_______________________________________________
47 // include uno interfaces
48 #include <com/sun/star/lang/XTypeProvider.hpp>
49 #include <com/sun/star/lang/XServiceInfo.hpp>
50 #include <com/sun/star/lang/XInitialization.hpp>
51 #include <com/sun/star/lang/XEventListener.hpp>
52 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
53 #include <com/sun/star/task/XStatusIndicator.hpp>
54 #include <com/sun/star/awt/XWindow.hpp>
55 #include <com/sun/star/awt/XWindowListener.hpp>
56 #include <com/sun/star/lang/EventObject.hpp>
57 #include <com/sun/star/awt/WindowEvent.hpp>
58 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
59 #include <com/sun/star/frame/XFrame.hpp>
60 
61 #ifndef _COM_SUN_STAR_URTIL_XUPDATABLE_HPP_
62 #include <com/sun/star/util/XUpdatable.hpp>
63 #endif
64 
65 //_______________________________________________
66 // include others
67 #include <vcl/status.hxx>
68 #include <cppuhelper/weak.hxx>
69 #include <osl/thread.hxx>
70 
71 //_______________________________________________
72 // namespace
73 
74 namespace framework{
75 
76 //_______________________________________________
77 // definitions
78 
79 //===============================================
80 /**
81     @descr  This struct hold some informations about all currently running progress proccesses.
82             Because the can be used on a stack, we must cache her states but must paint only
83             the top most one.
84  */
85 struct IndicatorInfo
86 {
87     //-------------------------------------------
88     // member
89     public:
90 
91         /** @short  points to the indicator child, where we hold its states
92                     alive here. */
93         css::uno::Reference< css::task::XStatusIndicator > m_xIndicator;
94 
95         /** @short  the last set text for this indicator */
96         ::rtl::OUString m_sText;
97 
98         /** @short  the max range for this indicator. */
99         sal_Int32 m_nRange;
100 
101         /** @short  the last set value for this indicator */
102         sal_Int32 m_nValue;
103 
104     //-------------------------------------------
105     // interface
106     public:
107 
108         //---------------------------------------
109         /** @short  initialize new instance of this class
110 
111             @param  xIndicator
112                     the new child indiactor of our factory.
113 
114             @param  sText
115                     its initial text.
116 
117             @param  nRange
118                     the max range for this indicator.
119          */
120         IndicatorInfo(const css::uno::Reference< css::task::XStatusIndicator >& xIndicator,
121                       const ::rtl::OUString&                                    sText     ,
122                             sal_Int32                                           nRange    )
123         {
124             m_xIndicator = xIndicator;
125             m_sText      = sText     ;
126             m_nRange     = nRange    ;
127             m_nValue     = 0         ;
128         }
129 
130         //---------------------------------------
131         /** @short  Don't forget to free used references!
132          */
133         ~IndicatorInfo()
134         {
135             m_xIndicator.clear();
136         }
137 
138         //---------------------------------------------------------------------------------------------------------
139         /** @short  Used to locate an info struct inside a stl structure ...
140 
141             @descr  The indicator object itself is used as key. Its values
142                     are not interesting then. Because mor then one child
143                     indicator can use the same values ...
144          */
145         sal_Bool operator==(const css::uno::Reference< css::task::XStatusIndicator >& xIndicator)
146         {
147             return (m_xIndicator == xIndicator);
148         }
149 };
150 /*
151     //---------------------------------------------------------------------------------------------------------
152     // norm nValue to fit range of 0..100%
153     sal_Int32 calcPercentage()
154     {
155     return ::std::min( (( m_nValue * 100 )/ ::std::max( m_nRange, (sal_Int32)1 ) ), (sal_Int32)100 );
156     }
157 */
158 
159 //===============================================
160 /** @descr  Define a lits of child indicator objects and her data. */
161 typedef ::std::vector< IndicatorInfo > IndicatorStack;
162 
163 //===============================================
164 /** @short          implement a factory service to create new status indicator objects
165 
166     @descr			Internaly it uses:
167                     - a vcl based
168                     - or an uno based and by the frame layouted
169                     progress implementation.
170 
171                     This factory create different indicators and control his access
172                     to a shared output device! Only the last activated component
173                     can write his state to this device. All other requests will be
174                     cached only.
175 
176     @devstatus		ready to use
177     @threadsafe     yes
178  */
179 class StatusIndicatorFactory : public  css::lang::XTypeProvider
180                              , public  css::lang::XServiceInfo
181                              , public  css::lang::XInitialization
182                              , public  css::task::XStatusIndicatorFactory
183                              , public  css::util::XUpdatable
184                              , private ThreadHelpBase
185                              , public  ::cppu::OWeakObject                   // => XInterface
186 {
187     //-------------------------------------------
188     // member
189     private:
190 
191         /** stack with all current indicator childs. */
192         IndicatorStack m_aStack;
193 
194         /** uno service manager to create own needed uno resources. */
195         css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
196 
197         /** most active indicator child, which could work with our shared indicator window only. */
198         css::uno::Reference< css::task::XStatusIndicator > m_xActiveChild;
199 
200         /** used to show the progress on the frame (layouted!) or
201             as a plugged vcl window. */
202         css::uno::Reference< css::task::XStatusIndicator > m_xProgress;
203 
204         /** points to the frame, where we show the progress (in case
205             m_xProgress points to a frame progress. */
206         css::uno::WeakReference< css::frame::XFrame > m_xFrame;
207 
208         /** points to an outside window, where we show the progress (in case
209             we are plugged into such window). */
210         css::uno::WeakReference< css::awt::XWindow > m_xPluggWindow;
211 
212         /** Notify us if a fix time is over. We use it to implement an
213             intelligent "Reschedule" ... */
214         WakeUpThread* m_pWakeUp;
215 
216         /** Our WakeUpThread calls us in our interface method "XUpdatable::update().
217             There we set this member m_bAllowReschedule to sal_True. Next time if our impl_reschedule()
218             method is called, we know, that an Application::Reschedule() should be made.
219             Because the last made Reschedule can be was taken long time ago ... may be.*/
220         sal_Bool m_bAllowReschedule;
221 
222         /** enable/disable automatic showing of our parent window. */
223         sal_Bool m_bAllowParentShow;
224 
225         /** enable/disable rescheduling. Default=enabled*/
226         sal_Bool m_bDisableReschedule;
227 
228         /** prevent recursive calling of Application::Reschedule(). */
229         static sal_Int32 m_nInReschedule;
230 
231         /** time where there last start call was made. */
232         sal_Int32 m_nStartTime;
233 
234     //-------------------------------------------
235     // interface
236 
237 	public:
238 
239         //---------------------------------------
240         // ctor
241         StatusIndicatorFactory(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
242 
243         //---------------------------------------
244         // XInterface, XTypeProvider, XServiceInfo
245         FWK_DECLARE_XINTERFACE
246         FWK_DECLARE_XTYPEPROVIDER
247         DECLARE_XSERVICEINFO
248 
249         //---------------------------------------
250         // XInitialization
251         virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
252             throw(css::uno::Exception       ,
253                   css::uno::RuntimeException);
254 
255         //---------------------------------------
256         // XStatusIndicatorFactory
257 	    virtual css::uno::Reference< css::task::XStatusIndicator > SAL_CALL createStatusIndicator()
258             throw(css::uno::RuntimeException);
259 
260         //---------------------------------------
261         // XUpdatable
262         virtual void SAL_CALL update()
263             throw(css::uno::RuntimeException);
264 
265         //---------------------------------------
266         // similar (XStatusIndicator)
267         virtual void start(const css::uno::Reference< css::task::XStatusIndicator >& xChild,
268                            const ::rtl::OUString&                                    sText ,
269                                  sal_Int32                                           nRange);
270 
271         virtual void SAL_CALL reset(const css::uno::Reference< css::task::XStatusIndicator >& xChild);
272 
273         virtual void SAL_CALL end(const css::uno::Reference< css::task::XStatusIndicator >& xChild);
274 
275         virtual void SAL_CALL setText(const css::uno::Reference< css::task::XStatusIndicator >& xChild,
276                                       const ::rtl::OUString&                                    sText );
277 
278         virtual void SAL_CALL setValue(const css::uno::Reference< css::task::XStatusIndicator >& xChild,
279                                              sal_Int32                                           nValue);
280 
281     //-------------------------------------------
282     // specials
283 
284 	protected:
285 
286         virtual ~StatusIndicatorFactory();
287 
288     //-------------------------------------------
289     // helper
290 	private:
291 
292         /** @short  show the parent window of this progress ...
293                     if it's allowed to do so.
294 
295 
296             @descr  By default we show the parent window automaticly
297                     if this progress is used.
298                     If that isn't a valid operation, the user of this
299                     progress can suppress this feature by initializaing
300                     us with a special parameter.
301 
302             @seealso    initialize()
303          */
304         void implts_makeParentVisibleIfAllowed();
305 
306         /** @short  creates a new internal used progress.
307             @descr  This factory does not paint the progress itself.
308                     It uses helper for that. They can be vcl based or
309                     layouted by the frame and provided as an uno interface.
310          */
311         void impl_createProgress();
312 
313         /** @short  shows the internal used progress.
314             @descr  This factory does not paint the progress itself.
315                     It uses helper for that. They can be vcl based or
316                     layouted by the frame and provided as an uno interface.
317          */
318         void impl_showProgress();
319 
320         /** @short  hides the internal used progress.
321             @descr  This factory does not paint the progress itself.
322                     It uses helper for that. They can be vcl based or
323                     layouted by the frame and provided as an uno interface.
324          */
325         void impl_hideProgress();
326 
327         /** @short  try to "share the current thread in an intelligent manner" :-)
328 
329             @param  Overwrites our algorithm for Reschedule and force it to be shure
330                     that our progress was painted right.
331          */
332         void impl_reschedule(sal_Bool bForceUpdate);
333 
334         void impl_startWakeUpThread();
335         void impl_stopWakeUpThread();
336 
337 }; // class StatusIndicatorFactory
338 
339 } // namespace framework
340 
341 #endif // #ifndef __FRAMEWORK_HELPER_STATUSINDICATORFACTORY_HXX_
342