Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/UnoControls/source/controls/progressbar.cxx
Line
Count
Source
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 <progressbar.hxx>
21
22
#include <com/sun/star/awt/XGraphics.hpp>
23
#include <tools/debug.hxx>
24
#include <cppuhelper/queryinterface.hxx>
25
#include <cppuhelper/typeprovider.hxx>
26
27
using namespace ::cppu;
28
using namespace ::osl;
29
using namespace ::com::sun::star::uno;
30
using namespace ::com::sun::star::awt;
31
32
namespace unocontrols {
33
34
//  construct/destruct
35
36
ProgressBar::ProgressBar( const Reference< XComponentContext >& rxContext )
37
0
    : ProgressBar_BASE      (    rxContext                   )
38
0
    , m_bHorizontal         (    PROGRESSBAR_DEFAULT_HORIZONTAL         )
39
0
    , m_aBlockSize          (    PROGRESSBAR_DEFAULT_BLOCKDIMENSION     )
40
0
    , m_nForegroundColor    (    PROGRESSBAR_DEFAULT_FOREGROUNDCOLOR    )
41
0
    , m_nBackgroundColor    (    PROGRESSBAR_DEFAULT_BACKGROUNDCOLOR    )
42
0
    , m_nMinRange           (    PROGRESSBAR_DEFAULT_MINRANGE           )
43
0
    , m_nMaxRange           (    PROGRESSBAR_DEFAULT_MAXRANGE           )
44
0
    , m_nBlockValue         (    PROGRESSBAR_DEFAULT_BLOCKVALUE         )
45
0
    , m_nValue              (    PROGRESSBAR_DEFAULT_VALUE              )
46
0
{
47
0
}
48
49
ProgressBar::~ProgressBar()
50
0
{
51
0
}
52
53
//  XProgressBar
54
55
void SAL_CALL ProgressBar::setForegroundColor( sal_Int32 nColor )
56
0
{
57
    // Ready for multithreading
58
0
    MutexGuard  aGuard (m_aMutex);
59
60
    // Safe color for later use.
61
0
    m_nForegroundColor = Color(ColorTransparency, nColor);
62
63
    // Repaint control
64
0
    impl_paint ( 0, 0, impl_getGraphicsPeer() );
65
0
}
66
67
//  XProgressBar
68
69
void SAL_CALL ProgressBar::setBackgroundColor ( sal_Int32 nColor )
70
0
{
71
    // Ready for multithreading
72
0
    MutexGuard  aGuard (m_aMutex);
73
74
    // Safe color for later use.
75
0
    m_nBackgroundColor = Color(ColorTransparency, nColor);
76
77
    // Repaint control
78
0
    impl_paint ( 0, 0, impl_getGraphicsPeer() );
79
0
}
80
81
//  XProgressBar
82
83
void SAL_CALL ProgressBar::setValue ( sal_Int32 nValue )
84
0
{
85
    // This method is defined for follow things:
86
    //      1) Values >= _nMinRange
87
    //      2) Values <= _nMaxRange
88
89
    // Ready for multithreading
90
0
    MutexGuard aGuard (m_aMutex);
91
92
    // save impossible cases
93
    // This method is only defined for valid values
94
0
    DBG_ASSERT ( (( nValue >= m_nMinRange ) && ( nValue <= m_nMaxRange )), "ProgressBar::setValue()\nNot valid value.\n" );
95
96
    // If new value not valid ... do nothing in release version!
97
0
    if (
98
0
        ( nValue >= m_nMinRange ) &&
99
0
        ( nValue <= m_nMaxRange )
100
0
       )
101
0
    {
102
        // New value is ok => save this
103
0
        m_nValue = nValue;
104
105
        // Repaint to display changes
106
0
        impl_paint ( 0, 0, impl_getGraphicsPeer() );
107
0
    }
108
0
}
109
110
//  XProgressBar
111
112
void SAL_CALL ProgressBar::setRange ( sal_Int32 nMin, sal_Int32 nMax )
113
0
{
114
    // This method is defined for follow things:
115
    //      1) All values of sal_Int32
116
    //      2) Min < Max
117
    //      3) Min > Max
118
119
    // save impossible cases
120
    // This method is only defined for valid values
121
    // If you ignore this, the release version will produce an error "division by zero" in "ProgressBar::setValue()"!
122
0
    DBG_ASSERT ( ( nMin != nMax ) , "ProgressBar::setRange()\nValues for MIN and MAX are the same. This is not allowed!\n" );
123
124
    // Ready for multithreading
125
0
    MutexGuard  aGuard (m_aMutex);
126
127
    // control the values for min and max
128
0
    if ( nMin < nMax )
129
0
    {
130
        // Take correct Min and Max
131
0
        m_nMinRange = nMin;
132
0
        m_nMaxRange = nMax;
133
0
    }
134
0
    else
135
0
    {
136
        // Change Min and Max automatically
137
0
        m_nMinRange = nMax;
138
0
        m_nMaxRange = nMin;
139
0
    }
140
141
    // assure that m_nValue is within the range
142
0
    if (m_nMinRange >= m_nValue  ||  m_nValue >= m_nMaxRange)
143
0
        m_nValue = m_nMinRange;
144
145
0
    impl_recalcRange ();
146
147
    // Do not repaint the control at this place!!!
148
    // An old "m_nValue" is set and can not be correct for this new range.
149
    // Next call of "ProgressBar::setValue()" do this.
150
0
}
151
152
//  XProgressBar
153
154
sal_Int32 SAL_CALL ProgressBar::getValue ()
155
0
{
156
    // Ready for multithreading
157
0
    MutexGuard aGuard (m_aMutex);
158
159
0
    return m_nValue;
160
0
}
161
162
//  XWindow
163
164
void SAL_CALL ProgressBar::setPosSize (
165
    sal_Int32 nX,
166
    sal_Int32 nY,
167
    sal_Int32 nWidth,
168
    sal_Int32 nHeight,
169
    sal_Int16 nFlags
170
)
171
0
{
172
    // Take old size BEFORE you set the new values at baseclass!
173
    // You will control changes. At the other way, the values are the same!
174
0
    Rectangle aBasePosSize = getPosSize ();
175
0
    BaseControl::setPosSize (nX, nY, nWidth, nHeight, nFlags);
176
177
    // Do only, if size has changed.
178
0
    if (
179
0
        ( nWidth  != aBasePosSize.Width     ) ||
180
0
        ( nHeight != aBasePosSize.Height    )
181
0
       )
182
0
    {
183
0
        impl_recalcRange    (                           );
184
0
        impl_paint          ( 0, 0, impl_getGraphicsPeer () );
185
0
    }
186
0
}
187
188
//  XControl
189
190
sal_Bool SAL_CALL ProgressBar::setModel( const Reference< XControlModel >& /*xModel*/ )
191
0
{
192
    // A model is not possible for this control.
193
0
    return false;
194
0
}
195
196
//  XControl
197
198
Reference< XControlModel > SAL_CALL ProgressBar::getModel()
199
0
{
200
    // A model is not possible for this control.
201
0
    return Reference< XControlModel >();
202
0
}
203
204
//  protected method
205
206
void ProgressBar::impl_paint ( sal_Int32 nX, sal_Int32 nY, const Reference< XGraphics > & rGraphics )
207
0
{
208
    // save impossible cases
209
0
    DBG_ASSERT ( rGraphics.is(), "ProgressBar::paint()\nCalled with invalid Reference< XGraphics > ." );
210
211
    // This paint method is not buffered !!
212
    // Every request paint the completely control. ( but only, if peer exist )
213
0
    if ( !rGraphics.is () )
214
0
        return;
215
216
0
    MutexGuard  aGuard (m_aMutex);
217
218
    // Clear background
219
    // (same color for line and fill)
220
0
    rGraphics->setFillColor ( sal_Int32(m_nBackgroundColor) );
221
0
    rGraphics->setLineColor ( sal_Int32(m_nBackgroundColor) );
222
0
    rGraphics->drawRect     ( nX, nY, impl_getWidth(), impl_getHeight() );
223
224
    // same color for line and fill for blocks
225
0
    rGraphics->setFillColor ( sal_Int32(m_nForegroundColor) );
226
0
    rGraphics->setLineColor ( sal_Int32(m_nForegroundColor) );
227
228
0
    sal_Int32   nBlockStart     =   0;   // = left site of new block
229
0
    sal_Int32   nBlockCount     =   m_nBlockValue!=0.00 ? static_cast<sal_Int32>((m_nValue-m_nMinRange)/m_nBlockValue) : 0;   // = number of next block
230
231
    // Draw horizontal progressbar
232
    // decision in "recalcRange()"
233
0
    if (m_bHorizontal)
234
0
    {
235
        // Step to left side of window
236
0
        nBlockStart = nX;
237
238
0
        for ( sal_Int32 i=1; i<=nBlockCount; ++i )
239
0
        {
240
            // step free field
241
0
            nBlockStart +=  PROGRESSBAR_FREESPACE;
242
            // paint block
243
0
            rGraphics->drawRect (nBlockStart, nY+PROGRESSBAR_FREESPACE, m_aBlockSize.Width, m_aBlockSize.Height);
244
            // step next free field
245
0
            nBlockStart +=  m_aBlockSize.Width;
246
0
        }
247
0
    }
248
    // draw vertical progressbar
249
    // decision in "recalcRange()"
250
0
    else
251
0
    {
252
        // step to bottom side of window
253
0
        nBlockStart  =  nY+impl_getHeight();
254
0
        nBlockStart -=  m_aBlockSize.Height;
255
256
0
        for ( sal_Int32 i=1; i<=nBlockCount; ++i )
257
0
        {
258
            // step free field
259
0
            nBlockStart -=  PROGRESSBAR_FREESPACE;
260
            // paint block
261
0
            rGraphics->drawRect (nX+PROGRESSBAR_FREESPACE, nBlockStart, m_aBlockSize.Width, m_aBlockSize.Height);
262
            // step next free field
263
0
            nBlockStart -=  m_aBlockSize.Height;
264
0
        }
265
0
    }
266
267
    // Paint shadow border around the progressbar
268
0
    rGraphics->setLineColor ( PROGRESSBAR_LINECOLOR_SHADOW                          );
269
0
    rGraphics->drawLine     ( nX, nY, impl_getWidth(), nY               );
270
0
    rGraphics->drawLine     ( nX, nY, nX             , impl_getHeight() );
271
272
0
    rGraphics->setLineColor ( PROGRESSBAR_LINECOLOR_BRIGHT                                                              );
273
0
    rGraphics->drawLine     ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY                  );
274
0
    rGraphics->drawLine     ( impl_getWidth()-1, impl_getHeight()-1, nX               , impl_getHeight()-1  );
275
0
}
276
277
//  protected method
278
279
void ProgressBar::impl_recalcRange ()
280
0
{
281
0
    MutexGuard  aGuard (m_aMutex);
282
283
0
    sal_Int32 nWindowWidth  = impl_getWidth();
284
0
    sal_Int32 nWindowHeight = impl_getHeight();
285
0
    double    fBlockHeight;
286
0
    double    fBlockWidth;
287
0
    double    fMaxBlocks;
288
289
0
    if( nWindowWidth > nWindowHeight )
290
0
    {
291
0
        m_bHorizontal = true;
292
0
        fBlockHeight  = (nWindowHeight-(2*PROGRESSBAR_FREESPACE));
293
0
        fBlockWidth   = fBlockHeight;
294
0
        fMaxBlocks    = nWindowWidth/(fBlockWidth+PROGRESSBAR_FREESPACE);
295
0
    }
296
0
    else
297
0
    {
298
0
        m_bHorizontal = false;
299
0
        fBlockWidth   = (nWindowWidth-(2*PROGRESSBAR_FREESPACE));
300
0
        fBlockHeight  = fBlockWidth;
301
0
        fMaxBlocks    = nWindowHeight/(fBlockHeight+PROGRESSBAR_FREESPACE);
302
0
    }
303
304
0
    double fRange       = m_nMaxRange-m_nMinRange;
305
0
    double fBlockValue  = fRange/fMaxBlocks;
306
307
0
    m_nBlockValue       = fBlockValue;
308
0
    m_aBlockSize.Height = static_cast<sal_Int32>(fBlockHeight);
309
0
    m_aBlockSize.Width  = static_cast<sal_Int32>(fBlockWidth);
310
0
}
311
312
}   // namespace unocontrols
313
314
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
315
stardiv_UnoControls_ProgressBar_get_implementation(
316
    css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
317
0
{
318
0
    return cppu::acquire(new unocontrols::ProgressBar(context));
319
0
}
320
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */