Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/UnoControls/source/controls/statusindicator.cxx
Line
Count
Source (jump to first uncovered line)
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
#include <statusindicator.hxx>
21
22
#include <com/sun/star/awt/PosSize.hpp>
23
#include <com/sun/star/awt/XFixedText.hpp>
24
#include <com/sun/star/uno/XComponentContext.hpp>
25
#include <cppuhelper/queryinterface.hxx>
26
#include <cppuhelper/typeprovider.hxx>
27
28
#include <progressbar.hxx>
29
30
using namespace ::cppu;
31
using namespace ::osl;
32
using namespace ::com::sun::star::uno;
33
using namespace ::com::sun::star::lang;
34
using namespace ::com::sun::star::awt;
35
using namespace ::com::sun::star::task;
36
37
constexpr OUStringLiteral CONTROLNAME_TEXT = u"Text"; // identifier the control in container
38
constexpr OUStringLiteral CONTROLNAME_PROGRESSBAR = u"ProgressBar"; //              -||-
39
40
namespace unocontrols {
41
42
//  construct/destruct
43
44
StatusIndicator::StatusIndicator( const css::uno::Reference< XComponentContext >& rxContext )
45
0
    : StatusIndicator_BASE(rxContext)
46
0
{
47
    // It's not allowed to work with member in this method (refcounter !!!)
48
    // But with a HACK (++refcount) its "OK" :-(
49
0
    osl_atomic_increment(&m_refCount);
50
51
    // Create instances for fixedtext and progress ...
52
0
    m_xText = new UnoFixedTextControl();
53
0
    m_xProgressBar = new ProgressBar(rxContext);
54
    // ... cast controls to css::uno::Reference< XControl > and set model ...
55
    // ( ProgressBar has no model !!! )
56
0
    m_xText->setModel( new UnoControlFixedTextModel(rxContext) );
57
    // ... and add controls to basecontainercontrol!
58
0
    addControl( CONTROLNAME_TEXT, m_xText    );
59
0
    addControl( CONTROLNAME_PROGRESSBAR, m_xProgressBar );
60
    // FixedText make it automatically visible by himself ... but not the progressbar !!!
61
    // it must be set explicitly
62
0
    m_xProgressBar->setVisible( true );
63
    // Reset to defaults !!!
64
    // (progressbar take automatically its own defaults)
65
0
    m_xText->setText( u""_ustr );
66
67
0
    osl_atomic_decrement(&m_refCount);
68
0
}
69
70
0
StatusIndicator::~StatusIndicator() {}
71
72
//  XStatusIndicator
73
74
void SAL_CALL StatusIndicator::start( const OUString& sText, sal_Int32 nRange )
75
0
{
76
    // Ready for multithreading
77
0
    MutexGuard aGuard( m_aMutex );
78
79
    // Initialize status controls with given values.
80
0
    m_xText->setText( sText );
81
0
    m_xProgressBar->setRange( 0, nRange );
82
    // force repaint ... fixedtext has changed !
83
0
    impl_recalcLayout ( WindowEvent(getXWeak(),0,0,impl_getWidth(),impl_getHeight(),0,0,0,0) );
84
0
}
85
86
//  XStatusIndicator
87
88
void SAL_CALL StatusIndicator::end()
89
0
{
90
    // Ready for multithreading
91
0
    MutexGuard aGuard( m_aMutex );
92
93
    // Clear values of status controls.
94
0
    m_xText->setText( OUString() );
95
0
    m_xProgressBar->setValue( 0 );
96
0
    setVisible( false );
97
0
}
98
99
//  XStatusIndicator
100
101
void SAL_CALL StatusIndicator::setText( const OUString& sText )
102
0
{
103
    // Ready for multithreading
104
0
    MutexGuard aGuard( m_aMutex );
105
106
    // Take text on right control
107
0
    m_xText->setText( sText );
108
0
}
109
110
//  XStatusIndicator
111
112
void SAL_CALL StatusIndicator::setValue( sal_Int32 nValue )
113
0
{
114
    // Ready for multithreading
115
0
    MutexGuard aGuard( m_aMutex );
116
117
    // Take value on right control
118
0
    m_xProgressBar->setValue( nValue );
119
0
}
120
121
//  XStatusIndicator
122
123
void SAL_CALL StatusIndicator::reset()
124
0
{
125
    // Ready for multithreading
126
0
    MutexGuard aGuard( m_aMutex );
127
128
    // Clear values of status controls.
129
    // (Don't hide the window! User will reset current values ... but he will not finish using of indicator!)
130
0
    m_xText->setText( OUString() );
131
0
    m_xProgressBar->setValue( 0 );
132
0
}
133
134
//  XLayoutConstrains
135
136
css::awt::Size SAL_CALL StatusIndicator::getMinimumSize ()
137
0
{
138
0
    return css::awt::Size(STATUSINDICATOR_DEFAULT_WIDTH, STATUSINDICATOR_DEFAULT_HEIGHT);
139
0
}
140
141
//  XLayoutConstrains
142
143
css::awt::Size SAL_CALL StatusIndicator::getPreferredSize ()
144
0
{
145
    // Ready for multithreading
146
0
    ClearableMutexGuard aGuard ( m_aMutex );
147
148
    // get information about required place of child controls
149
0
    css::awt::Size                            aTextSize   = m_xText->getPreferredSize();
150
151
0
    aGuard.clear ();
152
153
    // calc preferred size of status indicator
154
0
    sal_Int32 nWidth  = impl_getWidth();
155
0
    sal_Int32 nHeight = (2*STATUSINDICATOR_FREEBORDER)+aTextSize.Height;
156
157
    // norm to minimum
158
0
    if ( nWidth<STATUSINDICATOR_DEFAULT_WIDTH )
159
0
    {
160
0
        nWidth = STATUSINDICATOR_DEFAULT_WIDTH;
161
0
    }
162
0
    if ( nHeight<STATUSINDICATOR_DEFAULT_HEIGHT )
163
0
    {
164
0
        nHeight = STATUSINDICATOR_DEFAULT_HEIGHT;
165
0
    }
166
167
    // return to caller
168
0
    return css::awt::Size ( nWidth, nHeight );
169
0
}
170
171
//  XLayoutConstrains
172
173
css::awt::Size SAL_CALL StatusIndicator::calcAdjustedSize ( const css::awt::Size& /*rNewSize*/ )
174
0
{
175
0
    return getPreferredSize ();
176
0
}
177
178
//  XControl
179
180
void SAL_CALL StatusIndicator::createPeer (
181
    const css::uno::Reference< XToolkit > & rToolkit,
182
    const css::uno::Reference< XWindowPeer > & rParent
183
)
184
0
{
185
0
    if( !getPeer().is() )
186
0
    {
187
0
        BaseContainerControl::createPeer( rToolkit, rParent );
188
189
        // If user forget to call "setPosSize()", we have still a correct size.
190
        // And a "MinimumSize" IS A "MinimumSize"!
191
        // We change not the position of control at this point.
192
0
        css::awt::Size aDefaultSize = getMinimumSize ();
193
0
        setPosSize ( 0, 0, aDefaultSize.Width, aDefaultSize.Height, PosSize::SIZE );
194
0
    }
195
0
}
196
197
//  XControl
198
199
sal_Bool SAL_CALL StatusIndicator::setModel ( const css::uno::Reference< XControlModel > & /*rModel*/ )
200
0
{
201
    // We have no model.
202
0
    return false;
203
0
}
204
205
//  XControl
206
207
css::uno::Reference< XControlModel > SAL_CALL StatusIndicator::getModel ()
208
0
{
209
    // We have no model.
210
    // return (XControlModel*)this;
211
0
    return css::uno::Reference< XControlModel >  ();
212
0
}
213
214
//  XComponent
215
216
void SAL_CALL StatusIndicator::dispose ()
217
0
{
218
    // Ready for multithreading
219
0
    MutexGuard aGuard ( m_aMutex );
220
221
    // "removeControl()" control the state of a reference
222
223
0
    removeControl( m_xText     );
224
0
    removeControl( m_xProgressBar );
225
226
    // don't use "...->clear ()" or "... = XFixedText ()"
227
    // when other hold a reference at this object !!!
228
0
    m_xText->dispose();
229
0
    m_xProgressBar->dispose();
230
0
    m_xProgressBar.clear();
231
0
    m_xText.clear();
232
0
    BaseContainerControl::dispose();
233
0
}
234
235
//  XWindow
236
237
void SAL_CALL StatusIndicator::setPosSize (
238
    sal_Int32 nX,
239
    sal_Int32 nY,
240
    sal_Int32 nWidth,
241
    sal_Int32 nHeight,
242
    sal_Int16 nFlags
243
)
244
0
{
245
0
    Rectangle   aBasePosSize = getPosSize ();
246
0
    BaseContainerControl::setPosSize (nX, nY, nWidth, nHeight, nFlags);
247
248
    // if position or size changed
249
0
    if (
250
0
        ( nWidth  != aBasePosSize.Width ) ||
251
0
        ( nHeight != aBasePosSize.Height)
252
0
       )
253
0
    {
254
        // calc new layout for controls
255
0
        impl_recalcLayout ( WindowEvent(getXWeak(),0,0,nWidth,nHeight,0,0,0,0) );
256
        // clear background (!)
257
        // [Children were repainted in "recalcLayout" by setPosSize() automatically!]
258
0
        getPeer()->invalidate(2);
259
        // and repaint the control
260
0
        impl_paint ( 0, 0, impl_getGraphicsPeer() );
261
0
    }
262
0
}
263
264
//  protected method
265
266
WindowDescriptor StatusIndicator::impl_getWindowDescriptor( const css::uno::Reference< XWindowPeer >& xParentPeer )
267
0
{
268
0
    WindowDescriptor aDescriptor;
269
270
0
    aDescriptor.Type               =   WindowClass_SIMPLE;
271
0
    aDescriptor.WindowServiceName  =   "floatingwindow";
272
0
    aDescriptor.ParentIndex        =   -1;
273
0
    aDescriptor.Parent             =   xParentPeer;
274
0
    aDescriptor.Bounds             =   getPosSize ();
275
276
0
    return aDescriptor;
277
0
}
278
279
//  protected method
280
281
void StatusIndicator::impl_paint ( sal_Int32 nX, sal_Int32 nY, const css::uno::Reference< XGraphics > & rGraphics )
282
0
{
283
    // This paint method is not buffered!
284
    // Every request paint the completely control. (But only, if peer exist)
285
0
    if ( !rGraphics.is () )
286
0
        return;
287
288
0
    MutexGuard  aGuard (m_aMutex);
289
290
    // background = gray
291
0
    css::uno::Reference< XWindowPeer > xPeer( impl_getPeerWindow(), UNO_QUERY );
292
0
    if( xPeer.is() )
293
0
        xPeer->setBackground( STATUSINDICATOR_BACKGROUNDCOLOR );
294
295
    // FixedText background = gray
296
0
    xPeer = m_xText->getPeer();
297
0
    if( xPeer.is() )
298
0
        xPeer->setBackground( STATUSINDICATOR_BACKGROUNDCOLOR );
299
300
    // Progress background = gray
301
0
    xPeer = m_xProgressBar->getPeer();
302
0
    if( xPeer.is() )
303
0
        xPeer->setBackground( STATUSINDICATOR_BACKGROUNDCOLOR );
304
305
    // paint shadow border
306
0
    rGraphics->setLineColor ( STATUSINDICATOR_LINECOLOR_BRIGHT                          );
307
0
    rGraphics->drawLine     ( nX, nY, impl_getWidth(), nY               );
308
0
    rGraphics->drawLine     ( nX, nY, nX             , impl_getHeight() );
309
310
0
    rGraphics->setLineColor ( STATUSINDICATOR_LINECOLOR_SHADOW                                                              );
311
0
    rGraphics->drawLine     ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY                  );
312
0
    rGraphics->drawLine     ( impl_getWidth()-1, impl_getHeight()-1, nX               , impl_getHeight()-1  );
313
0
}
314
315
//  protected method
316
317
void StatusIndicator::impl_recalcLayout ( const WindowEvent& aEvent )
318
0
{
319
0
    sal_Int32   nX_ProgressBar;
320
0
    sal_Int32   nY_ProgressBar;
321
0
    sal_Int32   nWidth_ProgressBar;
322
0
    sal_Int32   nHeight_ProgressBar;
323
0
    sal_Int32   nX_Text;
324
0
    sal_Int32   nY_Text;
325
0
    sal_Int32   nWidth_Text;
326
0
    sal_Int32   nHeight_Text;
327
328
    // Ready for multithreading
329
0
    MutexGuard aGuard ( m_aMutex );
330
331
    // get information about required place of child controls
332
0
    css::awt::Size                            aWindowSize     ( aEvent.Width, aEvent.Height );
333
0
    css::awt::Size                            aTextSize       = m_xText->getPreferredSize();
334
335
0
    if( aWindowSize.Width < STATUSINDICATOR_DEFAULT_WIDTH )
336
0
    {
337
0
        aWindowSize.Width = STATUSINDICATOR_DEFAULT_WIDTH;
338
0
    }
339
0
    if( aWindowSize.Height < STATUSINDICATOR_DEFAULT_HEIGHT )
340
0
    {
341
0
        aWindowSize.Height = STATUSINDICATOR_DEFAULT_HEIGHT;
342
0
    }
343
344
    // calc position and size of child controls
345
0
    nX_Text             = STATUSINDICATOR_FREEBORDER;
346
0
    nY_Text             = STATUSINDICATOR_FREEBORDER;
347
0
    nWidth_Text         = aTextSize.Width;
348
0
    nHeight_Text        = aTextSize.Height;
349
350
0
    nX_ProgressBar      = nX_Text+nWidth_Text+STATUSINDICATOR_FREEBORDER;
351
0
    nY_ProgressBar      = nY_Text;
352
0
    nWidth_ProgressBar  = aWindowSize.Width-nWidth_Text-(3*STATUSINDICATOR_FREEBORDER);
353
0
    nHeight_ProgressBar = nHeight_Text;
354
355
    // Set new position and size on all controls
356
0
    m_xText->setPosSize     ( nX_Text       , nY_Text       , nWidth_Text       , nHeight_Text          , 15 );
357
0
    m_xProgressBar->setPosSize( nX_ProgressBar, nY_ProgressBar, nWidth_ProgressBar, nHeight_ProgressBar, 15 );
358
0
}
359
360
}   // namespace unocontrols
361
362
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
363
stardiv_UnoControls_StatusIndicator_get_implementation(
364
    css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
365
0
{
366
0
    return cppu::acquire(new unocontrols::StatusIndicator(context));
367
0
}
368
369
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */