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