1 /*************************************************************************
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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>
42 //........................................................................
45 //........................................................................
47 /** === begin UNO using === **/
48 /** === end UNO using === **/
50 #define OVERALL_RANGE 100000
52 //====================================================================
54 //====================================================================
57 // the weight of the phase, relative to all other phases
59 // the "local" range of the phase
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
66 sal_uInt32 nGlobalRange
;
76 PhaseData( const PhaseWeight _nWeight
)
85 typedef ::std::map
< PhaseID
, PhaseData
> Phases
;
87 //====================================================================
88 //= ProgressMixer_Data
89 //====================================================================
90 struct ProgressMixer_Data
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
)
100 ,pCurrentPhase( aPhases
.end() )
102 ,nOverallStretch( 0 )
103 ,rConsumer( _rConsumer
)
108 //--------------------------------------------------------------------
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
)
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();
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 //====================================================================
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
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
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
);
212 if ( pNextPhase
== m_pData
->aPhases
.end() )
213 m_pData
->rConsumer
.end();
216 //........................................................................
218 //........................................................................