merge the formfield patch from ooo-build
[ooovba.git] / dbaccess / source / ext / macromigration / progressmixer.cxx
blob0dfdee0199794e65f4de239601e4940abe24d91c
1 /*************************************************************************
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * Copyright 2008 by Sun Microsystems, Inc.
6 * OpenOffice.org - a multi-platform office productivity suite
8 * $RCSfile: progressmixer.cxx,v $
10 * $Revision: 1.1.2.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
28 ************************************************************************/
30 // MARKER(update_precomp.py): autogen include statement, do not remove
31 #include "precompiled_dbaccess.hxx"
33 #include "progressmixer.hxx"
35 /** === begin UNO includes === **/
36 /** === end UNO includes === **/
38 #include <osl/diagnose.h>
40 #include <map>
42 //........................................................................
43 namespace dbmm
45 //........................................................................
47 /** === begin UNO using === **/
48 /** === end UNO using === **/
50 #define OVERALL_RANGE 100000
52 //====================================================================
53 //= misc types
54 //====================================================================
55 struct PhaseData
57 // the weight of the phase, relative to all other phases
58 PhaseWeight nWeight;
59 // the "local" range of the phase
60 sal_uInt32 nRange;
61 // this is the point in the "overall range" at which this phase starts
62 sal_uInt32 nGlobalStart;
63 /** the "global" range of the phase, i.e. its range after weighting with all other
64 phases
66 sal_uInt32 nGlobalRange;
68 PhaseData()
69 :nWeight(1)
70 ,nRange(100)
71 ,nGlobalStart(0)
72 ,nGlobalRange(100)
76 PhaseData( const PhaseWeight _nWeight )
77 :nWeight( _nWeight )
78 ,nRange(100)
79 ,nGlobalStart(0)
80 ,nGlobalRange(100)
85 typedef ::std::map< PhaseID, PhaseData > Phases;
87 //====================================================================
88 //= ProgressMixer_Data
89 //====================================================================
90 struct ProgressMixer_Data
92 Phases aPhases;
93 Phases::iterator pCurrentPhase;
94 sal_uInt32 nWeightSum; /// the cached sum of the weights
95 double nOverallStretch;
96 IProgressConsumer& rConsumer;
98 ProgressMixer_Data( IProgressConsumer& _rConsumer )
99 :aPhases()
100 ,pCurrentPhase( aPhases.end() )
101 ,nWeightSum( 0 )
102 ,nOverallStretch( 0 )
103 ,rConsumer( _rConsumer )
108 //--------------------------------------------------------------------
109 namespace
111 //----------------------------------------------------------------
112 bool lcl_isRunning( const ProgressMixer_Data& _rData )
114 return _rData.pCurrentPhase != _rData.aPhases.end();
117 //----------------------------------------------------------------
118 void lcl_ensureInitialized( ProgressMixer_Data& _rData )
120 OSL_PRECOND( _rData.nWeightSum, "lcl_ensureInitialized: we have no phases, this will crash!" );
122 if ( _rData.nOverallStretch )
123 return;
125 _rData.nOverallStretch = 1.0 * OVERALL_RANGE / _rData.nWeightSum;
127 // tell the single phases their "overall starting point"
128 PhaseWeight nRunningWeight( 0 );
129 for ( Phases::iterator phase = _rData.aPhases.begin();
130 phase != _rData.aPhases.end();
131 ++phase
134 phase->second.nGlobalStart = (sal_uInt32)( nRunningWeight * _rData.nOverallStretch );
135 nRunningWeight += phase->second.nWeight;
137 sal_uInt32 nNextPhaseStart = (sal_uInt32)( nRunningWeight * _rData.nOverallStretch );
138 phase->second.nGlobalRange = nNextPhaseStart - phase->second.nGlobalStart;
141 _rData.rConsumer.start( OVERALL_RANGE );
145 //====================================================================
146 //= ProgressMixer
147 //====================================================================
148 //--------------------------------------------------------------------
149 ProgressMixer::ProgressMixer( IProgressConsumer& _rConsumer )
150 :m_pData( new ProgressMixer_Data( _rConsumer ) )
154 //--------------------------------------------------------------------
155 ProgressMixer::~ProgressMixer()
159 //--------------------------------------------------------------------
160 void ProgressMixer::registerPhase( const PhaseID _nID, const PhaseWeight _nWeight )
162 OSL_PRECOND( !lcl_isRunning( *m_pData ), "ProgressMixer::registerPhase: already running!" );
163 OSL_ENSURE( m_pData->aPhases.find( _nID ) == m_pData->aPhases.end(),
164 "ProgressMixer::registerPhase: ID already used!" );
165 m_pData->aPhases[ _nID ] = PhaseData( _nWeight );
166 m_pData->nWeightSum += _nWeight;
169 //--------------------------------------------------------------------
170 void ProgressMixer::startPhase( const PhaseID _nID, const sal_uInt32 _nPhaseRange )
172 OSL_ENSURE( m_pData->aPhases.find( _nID ) != m_pData->aPhases.end(),
173 "ProgresMixer::startPhase: unknown phase!" );
175 m_pData->aPhases[ _nID ].nRange = _nPhaseRange;
176 m_pData->pCurrentPhase = m_pData->aPhases.find( _nID );
179 //--------------------------------------------------------------------
180 void ProgressMixer::advancePhase( const sal_uInt32 _nPhaseProgress )
182 OSL_PRECOND( lcl_isRunning( *m_pData ), "ProgresMixer::advancePhase: not running!" );
184 // in case this is the first call, ensure all the ranges/weights are calculated
185 // correctly
186 lcl_ensureInitialized( *m_pData );
188 const PhaseData& rPhase( m_pData->pCurrentPhase->second );
190 double nLocalProgress = 1.0 * _nPhaseProgress / rPhase.nRange;
191 sal_uInt32 nOverallProgress = (sal_uInt32)
192 ( rPhase.nGlobalStart + nLocalProgress * rPhase.nGlobalRange );
194 m_pData->rConsumer.advance( nOverallProgress );
197 //--------------------------------------------------------------------
198 void ProgressMixer::endPhase()
200 OSL_PRECOND( lcl_isRunning( *m_pData ), "ProgresMixer::endPhase: not running!" );
202 // in case this is the first call, ensure all the ranges/weights are calculated
203 // correctly
204 lcl_ensureInitialized( *m_pData );
206 // simply assume the phase's complete range is over
207 advancePhase( m_pData->pCurrentPhase->second.nRange );
209 // if that's the last phase, this is the "global end", too
210 Phases::const_iterator pNextPhase( m_pData->pCurrentPhase );
211 ++pNextPhase;
212 if ( pNextPhase == m_pData->aPhases.end() )
213 m_pData->rConsumer.end();
216 //........................................................................
217 } // namespace dbmm
218 //........................................................................