10d29c390d
Change-Id: I076f16d0536b534abf0ced4d76051eadb4c0e033 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114949 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
402 lines
12 KiB
C++
402 lines
12 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <progressbar.hxx>
|
|
|
|
#include <com/sun/star/awt/XGraphics.hpp>
|
|
#include <tools/debug.hxx>
|
|
#include <cppuhelper/queryinterface.hxx>
|
|
#include <cppuhelper/typeprovider.hxx>
|
|
|
|
#include <limits.h>
|
|
|
|
using namespace ::cppu;
|
|
using namespace ::osl;
|
|
using namespace ::com::sun::star::uno;
|
|
using namespace ::com::sun::star::lang;
|
|
using namespace ::com::sun::star::awt;
|
|
|
|
namespace unocontrols {
|
|
|
|
// construct/destruct
|
|
|
|
ProgressBar::ProgressBar( const Reference< XComponentContext >& rxContext )
|
|
: BaseControl ( rxContext )
|
|
, m_bHorizontal ( PROGRESSBAR_DEFAULT_HORIZONTAL )
|
|
, m_aBlockSize ( PROGRESSBAR_DEFAULT_BLOCKDIMENSION )
|
|
, m_nForegroundColor ( PROGRESSBAR_DEFAULT_FOREGROUNDCOLOR )
|
|
, m_nBackgroundColor ( PROGRESSBAR_DEFAULT_BACKGROUNDCOLOR )
|
|
, m_nMinRange ( PROGRESSBAR_DEFAULT_MINRANGE )
|
|
, m_nMaxRange ( PROGRESSBAR_DEFAULT_MAXRANGE )
|
|
, m_nBlockValue ( PROGRESSBAR_DEFAULT_BLOCKVALUE )
|
|
, m_nValue ( PROGRESSBAR_DEFAULT_VALUE )
|
|
{
|
|
}
|
|
|
|
ProgressBar::~ProgressBar()
|
|
{
|
|
}
|
|
|
|
// XInterface
|
|
|
|
Any SAL_CALL ProgressBar::queryInterface( const Type& rType )
|
|
{
|
|
// Attention:
|
|
// Don't use mutex or guard in this method!!! Is a method of XInterface.
|
|
Any aReturn;
|
|
Reference< XInterface > xDel = BaseControl::impl_getDelegator();
|
|
if ( xDel.is() )
|
|
{
|
|
// If a delegator exists, forward question to its queryInterface.
|
|
// Delegator will ask its own queryAggregation!
|
|
aReturn = xDel->queryInterface( rType );
|
|
}
|
|
else
|
|
{
|
|
// If a delegator is unknown, forward question to own queryAggregation.
|
|
aReturn = queryAggregation( rType );
|
|
}
|
|
|
|
return aReturn;
|
|
}
|
|
|
|
// XInterface
|
|
|
|
void SAL_CALL ProgressBar::acquire() noexcept
|
|
{
|
|
// Attention:
|
|
// Don't use mutex or guard in this method!!! Is a method of XInterface.
|
|
|
|
// Forward to baseclass
|
|
BaseControl::acquire();
|
|
}
|
|
|
|
// XInterface
|
|
|
|
void SAL_CALL ProgressBar::release() noexcept
|
|
{
|
|
// Attention:
|
|
// Don't use mutex or guard in this method!!! Is a method of XInterface.
|
|
|
|
// Forward to baseclass
|
|
BaseControl::release();
|
|
}
|
|
|
|
// XTypeProvider
|
|
|
|
Sequence< Type > SAL_CALL ProgressBar::getTypes()
|
|
{
|
|
static OTypeCollection ourTypeCollection(
|
|
cppu::UnoType<XControlModel>::get(),
|
|
cppu::UnoType<XProgressBar>::get(),
|
|
BaseControl::getTypes() );
|
|
|
|
return ourTypeCollection.getTypes();
|
|
}
|
|
|
|
// XAggregation
|
|
|
|
Any SAL_CALL ProgressBar::queryAggregation( const Type& aType )
|
|
{
|
|
// Ask for my own supported interfaces ...
|
|
// Attention: XTypeProvider and XInterface are supported by OComponentHelper!
|
|
Any aReturn ( ::cppu::queryInterface( aType ,
|
|
static_cast< XControlModel* > ( this ) ,
|
|
static_cast< XProgressBar* > ( this )
|
|
)
|
|
);
|
|
|
|
// If searched interface not supported by this class ...
|
|
if ( !aReturn.hasValue() )
|
|
{
|
|
// ... ask baseclasses.
|
|
aReturn = BaseControl::queryAggregation( aType );
|
|
}
|
|
|
|
return aReturn;
|
|
}
|
|
|
|
// XProgressBar
|
|
|
|
void SAL_CALL ProgressBar::setForegroundColor( sal_Int32 nColor )
|
|
{
|
|
// Ready for multithreading
|
|
MutexGuard aGuard (m_aMutex);
|
|
|
|
// Safe color for later use.
|
|
m_nForegroundColor = Color(ColorTransparency, nColor);
|
|
|
|
// Repaint control
|
|
impl_paint ( 0, 0, impl_getGraphicsPeer() );
|
|
}
|
|
|
|
// XProgressBar
|
|
|
|
void SAL_CALL ProgressBar::setBackgroundColor ( sal_Int32 nColor )
|
|
{
|
|
// Ready for multithreading
|
|
MutexGuard aGuard (m_aMutex);
|
|
|
|
// Safe color for later use.
|
|
m_nBackgroundColor = Color(ColorTransparency, nColor);
|
|
|
|
// Repaint control
|
|
impl_paint ( 0, 0, impl_getGraphicsPeer() );
|
|
}
|
|
|
|
// XProgressBar
|
|
|
|
void SAL_CALL ProgressBar::setValue ( sal_Int32 nValue )
|
|
{
|
|
// This method is defined for follow things:
|
|
// 1) Values >= _nMinRange
|
|
// 2) Values <= _nMaxRange
|
|
|
|
// Ready for multithreading
|
|
MutexGuard aGuard (m_aMutex);
|
|
|
|
// save impossible cases
|
|
// This method is only defined for valid values
|
|
DBG_ASSERT ( (( nValue >= m_nMinRange ) && ( nValue <= m_nMaxRange )), "ProgressBar::setValue()\nNot valid value.\n" );
|
|
|
|
// If new value not valid ... do nothing in release version!
|
|
if (
|
|
( nValue >= m_nMinRange ) &&
|
|
( nValue <= m_nMaxRange )
|
|
)
|
|
{
|
|
// New value is ok => save this
|
|
m_nValue = nValue;
|
|
|
|
// Repaint to display changes
|
|
impl_paint ( 0, 0, impl_getGraphicsPeer() );
|
|
}
|
|
}
|
|
|
|
// XProgressBar
|
|
|
|
void SAL_CALL ProgressBar::setRange ( sal_Int32 nMin, sal_Int32 nMax )
|
|
{
|
|
// This method is defined for follow things:
|
|
// 1) All values of sal_Int32
|
|
// 2) Min < Max
|
|
// 3) Min > Max
|
|
|
|
// save impossible cases
|
|
// This method is only defined for valid values
|
|
// If you ignore this, the release version will produce an error "division by zero" in "ProgressBar::setValue()"!
|
|
DBG_ASSERT ( ( nMin != nMax ) , "ProgressBar::setRange()\nValues for MIN and MAX are the same. This is not allowed!\n" );
|
|
|
|
// Ready for multithreading
|
|
MutexGuard aGuard (m_aMutex);
|
|
|
|
// control the values for min and max
|
|
if ( nMin < nMax )
|
|
{
|
|
// Take correct Min and Max
|
|
m_nMinRange = nMin;
|
|
m_nMaxRange = nMax;
|
|
}
|
|
else
|
|
{
|
|
// Change Min and Max automatically
|
|
m_nMinRange = nMax;
|
|
m_nMaxRange = nMin;
|
|
}
|
|
|
|
// assure that m_nValue is within the range
|
|
if (m_nMinRange >= m_nValue || m_nValue >= m_nMaxRange)
|
|
m_nValue = m_nMinRange;
|
|
|
|
impl_recalcRange ();
|
|
|
|
// Do not repaint the control at this place!!!
|
|
// An old "m_nValue" is set and can not be correct for this new range.
|
|
// Next call of "ProgressBar::setValue()" do this.
|
|
}
|
|
|
|
// XProgressBar
|
|
|
|
sal_Int32 SAL_CALL ProgressBar::getValue ()
|
|
{
|
|
// Ready for multithreading
|
|
MutexGuard aGuard (m_aMutex);
|
|
|
|
return m_nValue;
|
|
}
|
|
|
|
// XWindow
|
|
|
|
void SAL_CALL ProgressBar::setPosSize (
|
|
sal_Int32 nX,
|
|
sal_Int32 nY,
|
|
sal_Int32 nWidth,
|
|
sal_Int32 nHeight,
|
|
sal_Int16 nFlags
|
|
)
|
|
{
|
|
// Take old size BEFORE you set the new values at baseclass!
|
|
// You will control changes. At the other way, the values are the same!
|
|
Rectangle aBasePosSize = getPosSize ();
|
|
BaseControl::setPosSize (nX, nY, nWidth, nHeight, nFlags);
|
|
|
|
// Do only, if size has changed.
|
|
if (
|
|
( nWidth != aBasePosSize.Width ) ||
|
|
( nHeight != aBasePosSize.Height )
|
|
)
|
|
{
|
|
impl_recalcRange ( );
|
|
impl_paint ( 0, 0, impl_getGraphicsPeer () );
|
|
}
|
|
}
|
|
|
|
// XControl
|
|
|
|
sal_Bool SAL_CALL ProgressBar::setModel( const Reference< XControlModel >& /*xModel*/ )
|
|
{
|
|
// A model is not possible for this control.
|
|
return false;
|
|
}
|
|
|
|
// XControl
|
|
|
|
Reference< XControlModel > SAL_CALL ProgressBar::getModel()
|
|
{
|
|
// A model is not possible for this control.
|
|
return Reference< XControlModel >();
|
|
}
|
|
|
|
// protected method
|
|
|
|
void ProgressBar::impl_paint ( sal_Int32 nX, sal_Int32 nY, const Reference< XGraphics > & rGraphics )
|
|
{
|
|
// save impossible cases
|
|
DBG_ASSERT ( rGraphics.is(), "ProgressBar::paint()\nCalled with invalid Reference< XGraphics > ." );
|
|
|
|
// This paint method is not buffered !!
|
|
// Every request paint the completely control. ( but only, if peer exist )
|
|
if ( !rGraphics.is () )
|
|
return;
|
|
|
|
MutexGuard aGuard (m_aMutex);
|
|
|
|
// Clear background
|
|
// (same color for line and fill)
|
|
rGraphics->setFillColor ( sal_Int32(m_nBackgroundColor) );
|
|
rGraphics->setLineColor ( sal_Int32(m_nBackgroundColor) );
|
|
rGraphics->drawRect ( nX, nY, impl_getWidth(), impl_getHeight() );
|
|
|
|
// same color for line and fill for blocks
|
|
rGraphics->setFillColor ( sal_Int32(m_nForegroundColor) );
|
|
rGraphics->setLineColor ( sal_Int32(m_nForegroundColor) );
|
|
|
|
sal_Int32 nBlockStart = 0; // = left site of new block
|
|
sal_Int32 nBlockCount = m_nBlockValue!=0.00 ? static_cast<sal_Int32>((m_nValue-m_nMinRange)/m_nBlockValue) : 0; // = number of next block
|
|
|
|
// Draw horizontal progressbar
|
|
// decision in "recalcRange()"
|
|
if (m_bHorizontal)
|
|
{
|
|
// Step to left side of window
|
|
nBlockStart = nX;
|
|
|
|
for ( sal_Int32 i=1; i<=nBlockCount; ++i )
|
|
{
|
|
// step free field
|
|
nBlockStart += PROGRESSBAR_FREESPACE;
|
|
// paint block
|
|
rGraphics->drawRect (nBlockStart, nY+PROGRESSBAR_FREESPACE, m_aBlockSize.Width, m_aBlockSize.Height);
|
|
// step next free field
|
|
nBlockStart += m_aBlockSize.Width;
|
|
}
|
|
}
|
|
// draw vertical progressbar
|
|
// decision in "recalcRange()"
|
|
else
|
|
{
|
|
// step to bottom side of window
|
|
nBlockStart = nY+impl_getHeight();
|
|
nBlockStart -= m_aBlockSize.Height;
|
|
|
|
for ( sal_Int32 i=1; i<=nBlockCount; ++i )
|
|
{
|
|
// step free field
|
|
nBlockStart -= PROGRESSBAR_FREESPACE;
|
|
// paint block
|
|
rGraphics->drawRect (nX+PROGRESSBAR_FREESPACE, nBlockStart, m_aBlockSize.Width, m_aBlockSize.Height);
|
|
// step next free field
|
|
nBlockStart -= m_aBlockSize.Height;
|
|
}
|
|
}
|
|
|
|
// Paint shadow border around the progressbar
|
|
rGraphics->setLineColor ( PROGRESSBAR_LINECOLOR_SHADOW );
|
|
rGraphics->drawLine ( nX, nY, impl_getWidth(), nY );
|
|
rGraphics->drawLine ( nX, nY, nX , impl_getHeight() );
|
|
|
|
rGraphics->setLineColor ( PROGRESSBAR_LINECOLOR_BRIGHT );
|
|
rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY );
|
|
rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, nX , impl_getHeight()-1 );
|
|
}
|
|
|
|
// protected method
|
|
|
|
void ProgressBar::impl_recalcRange ()
|
|
{
|
|
MutexGuard aGuard (m_aMutex);
|
|
|
|
sal_Int32 nWindowWidth = impl_getWidth();
|
|
sal_Int32 nWindowHeight = impl_getHeight();
|
|
double fBlockHeight;
|
|
double fBlockWidth;
|
|
double fMaxBlocks;
|
|
|
|
if( nWindowWidth > nWindowHeight )
|
|
{
|
|
m_bHorizontal = true;
|
|
fBlockHeight = (nWindowHeight-(2*PROGRESSBAR_FREESPACE));
|
|
fBlockWidth = fBlockHeight;
|
|
fMaxBlocks = nWindowWidth/(fBlockWidth+PROGRESSBAR_FREESPACE);
|
|
}
|
|
else
|
|
{
|
|
m_bHorizontal = false;
|
|
fBlockWidth = (nWindowWidth-(2*PROGRESSBAR_FREESPACE));
|
|
fBlockHeight = fBlockWidth;
|
|
fMaxBlocks = nWindowHeight/(fBlockHeight+PROGRESSBAR_FREESPACE);
|
|
}
|
|
|
|
double fRange = m_nMaxRange-m_nMinRange;
|
|
double fBlockValue = fRange/fMaxBlocks;
|
|
|
|
m_nBlockValue = fBlockValue;
|
|
m_aBlockSize.Height = static_cast<sal_Int32>(fBlockHeight);
|
|
m_aBlockSize.Width = static_cast<sal_Int32>(fBlockWidth);
|
|
}
|
|
|
|
} // namespace unocontrols
|
|
|
|
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
|
|
stardiv_UnoControls_ProgressBar_get_implementation(
|
|
css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
|
|
{
|
|
return cppu::acquire(new unocontrols::ProgressBar(context));
|
|
}
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|