1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #ifndef INCLUDED_FRAMEWORK_INC_HELPER_STATUSINDICATORFACTORY_HXX
21 #define INCLUDED_FRAMEWORK_INC_HELPER_STATUSINDICATORFACTORY_HXX
22 
23 // Attention: stl headers must(!) be included at first. Otherwise it can make trouble
24 // with solaris headers ...
25 #include <vector>
26 
27 // include files of own module
28 #include <helper/wakeupthread.hxx>
29 
30 // include uno interfaces
31 #include <com/sun/star/lang/XServiceInfo.hpp>
32 #include <com/sun/star/lang/XInitialization.hpp>
33 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
34 #include <com/sun/star/task/XStatusIndicator.hpp>
35 #include <com/sun/star/awt/XWindow.hpp>
36 #include <com/sun/star/frame/XFrame.hpp>
37 #include <com/sun/star/util/XUpdatable.hpp>
38 #include <com/sun/star/uno/XComponentContext.hpp>
39 
40 #include <cppuhelper/supportsservice.hxx>
41 #include <cppuhelper/implbase.hxx>
42 #include <rtl/ref.hxx>
43 
44 namespace framework{
45 
46 /**
47     @descr  This struct hold some information about all currently running progress processes.
48             Because the can be used on a stack, we must cache her states but must paint only
49             the top most one.
50  */
51 struct IndicatorInfo
52 {
53 
54     // member
55     public:
56 
57         /** @short  points to the indicator child, where we hold its states
58                     alive here. */
59         css::uno::Reference< css::task::XStatusIndicator > m_xIndicator;
60 
61         /** @short  the last set text for this indicator */
62         OUString m_sText;
63 
64         /** @short  the last set value for this indicator */
65         sal_Int32 m_nValue;
66 
67     // interface
68     public:
69 
70         /** @short  initialize new instance of this class
71 
72             @param  xIndicator
73                     the new child indicator of our factory.
74 
75             @param  sText
76                     its initial text.
77 
78             @param  nRange
79                     the max range for this indicator.
80          */
IndicatorInfoframework::IndicatorInfo81         IndicatorInfo(const css::uno::Reference< css::task::XStatusIndicator >& xIndicator,
82                       const OUString&                                    sText    )
83         {
84             m_xIndicator = xIndicator;
85             m_sText      = sText;
86             m_nValue     = 0;
87         }
88 
89         /** @short  Don't forget to free used references!
90          */
~IndicatorInfoframework::IndicatorInfo91         ~IndicatorInfo()
92         {
93             m_xIndicator.clear();
94         }
95 
96         /** @short  Used to locate an info struct inside a stl structure...
97 
98             @descr  The indicator object itself is used as key. Its values
99                     are not interesting then. Because more than one child
100                     indicator can use the same values...
101          */
operator ==framework::IndicatorInfo102         bool operator==(const css::uno::Reference< css::task::XStatusIndicator >& xIndicator)
103         {
104             return (m_xIndicator == xIndicator);
105         }
106 };
107 
108 /** @descr  Define a list of child indicator objects and its data. */
109 typedef ::std::vector< IndicatorInfo > IndicatorStack;
110 
111 /** @short          implement a factory service to create new status indicator objects
112 
113     @descr          Internally it uses:
114                     - a vcl based
115                     - or a uno based and by the frame layouted
116                     progress implementation.
117 
118                     This factory create different indicators and control his access
119                     to a shared output device! Only the last activated component
120                     can write its state to this device. All other requests will be
121                     cached only.
122 
123     @devstatus      ready to use
124     @threadsafe     yes
125  */
126 class StatusIndicatorFactory : public  ::cppu::WeakImplHelper<
127                                              css::lang::XServiceInfo
128                                            , css::lang::XInitialization
129                                            , css::task::XStatusIndicatorFactory
130                                            , css::util::XUpdatable >
131 {
132 
133     // member
134     private:
135         osl::Mutex m_mutex;
136 
137         /** stack with all current indicator children. */
138         IndicatorStack m_aStack;
139 
140         /** uno service manager to create own needed uno resources. */
141         css::uno::Reference< css::uno::XComponentContext > m_xContext;
142 
143         /** most active indicator child, which could work with our shared indicator window only. */
144         css::uno::Reference< css::task::XStatusIndicator > m_xActiveChild;
145 
146         /** used to show the progress on the frame (layouted!) or
147             as a plugged vcl window. */
148         css::uno::Reference< css::task::XStatusIndicator > m_xProgress;
149 
150         /** points to the frame, where we show the progress (in case
151             m_xProgress points to a frame progress. */
152         css::uno::WeakReference< css::frame::XFrame > m_xFrame;
153 
154         /** points to an outside window, where we show the progress (in case
155             we are plugged into such window). */
156         css::uno::WeakReference< css::awt::XWindow > m_xPluggWindow;
157 
158         /** Notify us if a fix time is over. We use it to implement an
159             intelligent "Reschedule" ... */
160         rtl::Reference<WakeUpThread> m_pWakeUp;
161 
162         /** Our WakeUpThread calls us in our interface method "XUpdatable::update().
163             There we set this member m_bAllowReschedule to sal_True. Next time if our impl_reschedule()
164             method is called, we know, that an Application::Reschedule() should be made.
165             Because the last made Reschedule can be was taken long time ago ... may be.*/
166         bool m_bAllowReschedule;
167 
168         /** enable/disable automatic showing of our parent window. */
169         bool m_bAllowParentShow;
170 
171         /** enable/disable rescheduling. Default=enabled*/
172         bool m_bDisableReschedule;
173 
174         /** prevent recursive calling of Application::Reschedule(). */
175         static sal_Int32 m_nInReschedule;
176 
177     // interface
178 
179     public:
180         StatusIndicatorFactory(const css::uno::Reference< css::uno::XComponentContext >& xContext);
181 
getImplementationName()182         virtual OUString SAL_CALL getImplementationName() override
183         {
184             return "com.sun.star.comp.framework.StatusIndicatorFactory";
185         }
186 
supportsService(OUString const & ServiceName)187         virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
188         {
189             return cppu::supportsService(this, ServiceName);
190         }
191 
getSupportedServiceNames()192         virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
193         {
194             css::uno::Sequence< OUString > aSeq { "com.sun.star.task.StatusIndicatorFactory" };
195             return aSeq;
196         }
197 
198         // XInitialization
199         virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any >& lArguments) override;
200 
201         // XStatusIndicatorFactory
202         virtual css::uno::Reference< css::task::XStatusIndicator > SAL_CALL createStatusIndicator() override;
203 
204         // XUpdatable
205         virtual void SAL_CALL update() override;
206 
207         // similar (XStatusIndicator)
208         void start(const css::uno::Reference< css::task::XStatusIndicator >& xChild,
209                            const OUString&                                    sText ,
210                                  sal_Int32                                           nRange);
211 
212         void reset(const css::uno::Reference< css::task::XStatusIndicator >& xChild);
213 
214         void end(const css::uno::Reference< css::task::XStatusIndicator >& xChild);
215 
216         void setText(const css::uno::Reference< css::task::XStatusIndicator >& xChild,
217                                       const OUString&                                    sText );
218 
219         void setValue(const css::uno::Reference< css::task::XStatusIndicator >& xChild,
220                                              sal_Int32                                           nValue);
221 
222     // specials
223 
224     protected:
225 
226         virtual ~StatusIndicatorFactory() override;
227 
228     // helper
229     private:
230 
231         /** @short  show the parent window of this progress ...
232                     if it's allowed to do so.
233 
234             @descr  By default we show the parent window automatically
235                     if this progress is used.
236                     If that isn't a valid operation, the user of this
237                     progress can suppress this feature by initializing
238                     us with a special parameter.
239 
240             @seealso    initialize()
241          */
242         void implts_makeParentVisibleIfAllowed();
243 
244         /** @short  creates a new internal used progress.
245             @descr  This factory does not paint the progress itself.
246                     It uses helper for that. They can be vcl based or
247                     layouted by the frame and provided as a uno interface.
248          */
249         void impl_createProgress();
250 
251         /** @short  shows the internal used progress.
252             @descr  This factory does not paint the progress itself.
253                     It uses helper for that. They can be vcl based or
254                     layouted by the frame and provided as a uno interface.
255          */
256         void impl_showProgress();
257 
258         /** @short  hides the internal used progress.
259             @descr  This factory does not paint the progress itself.
260                     It uses helper for that. They can be vcl based or
261                     layouted by the frame and provided as a uno interface.
262          */
263         void impl_hideProgress();
264 
265         /** @short  try to "share the current thread in an intelligent manner" :-)
266 
267             @param  Overwrites our algorithm for Reschedule and force it to be sure
268                     that our progress was painted right.
269          */
270         void impl_reschedule(bool bForceUpdate);
271 
272         void impl_startWakeUpThread();
273         void impl_stopWakeUpThread();
274 
275 }; // class StatusIndicatorFactory
276 
277 } // namespace framework
278 
279 #endif // INCLUDED_FRAMEWORK_INC_HELPER_STATUSINDICATORFACTORY_HXX
280 
281 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
282