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           */
IndicatorInfoframework::IndicatorInfo116          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           */
~IndicatorInfoframework::IndicatorInfo129          ~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           */
operator ==framework::IndicatorInfo141          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 automaticly
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 shure
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