1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 #include "fprogressbar.hxx"
27 #include "global.hxx"
28 #include "progress.hxx"
29
30 // ============================================================================
31
ScfProgressSegment(sal_Size nSize)32 ScfProgressBar::ScfProgressSegment::ScfProgressSegment( sal_Size nSize ) :
33 mxProgress( 0 ),
34 mnSize( nSize ),
35 mnPos( 0 )
36 {
37 }
38
~ScfProgressSegment()39 ScfProgressBar::ScfProgressSegment::~ScfProgressSegment()
40 {
41 }
42
43 // ============================================================================
44
ScfProgressBar(SfxObjectShell * pDocShell,const String & rText)45 ScfProgressBar::ScfProgressBar( SfxObjectShell* pDocShell, const String& rText ) :
46 maText( rText )
47 {
48 Init( pDocShell );
49 }
50
ScfProgressBar(SfxObjectShell * pDocShell,sal_uInt16 nResId)51 ScfProgressBar::ScfProgressBar( SfxObjectShell* pDocShell, sal_uInt16 nResId ) :
52 maText( ScGlobal::GetRscString( nResId ) )
53 {
54 Init( pDocShell );
55 }
56
ScfProgressBar(ScfProgressBar & rParProgress,ScfProgressSegment * pParSegment)57 ScfProgressBar::ScfProgressBar( ScfProgressBar& rParProgress, ScfProgressSegment* pParSegment )
58 {
59 Init( rParProgress.mpDocShell );
60 mpParentProgress = &rParProgress;
61 mpParentSegment = pParSegment;
62 }
63
~ScfProgressBar()64 ScfProgressBar::~ScfProgressBar()
65 {
66 }
67
Init(SfxObjectShell * pDocShell)68 void ScfProgressBar::Init( SfxObjectShell* pDocShell )
69 {
70 mpDocShell = pDocShell;
71 mpParentProgress = 0;
72 mpParentSegment = mpCurrSegment = 0;
73 mnTotalSize = mnTotalPos = mnUnitSize = mnNextUnitPos = 0;
74 mnSysProgressScale = 1; // used to workaround the ULONG_MAX/100 limit
75 mbInProgress = false;
76 }
77
GetSegment(sal_Int32 nSegment) const78 ScfProgressBar::ScfProgressSegment* ScfProgressBar::GetSegment( sal_Int32 nSegment ) const
79 {
80 if( nSegment < 0 )
81 return 0;
82 DBG_ASSERT( maSegments.GetObject( nSegment ), "ScfProgressBar::GetSegment - invalid segment index" );
83 return maSegments.GetObject( nSegment );
84 }
85
SetCurrSegment(ScfProgressSegment * pSegment)86 void ScfProgressBar::SetCurrSegment( ScfProgressSegment* pSegment )
87 {
88 if( mpCurrSegment != pSegment )
89 {
90 mpCurrSegment = pSegment;
91
92 if( mpParentProgress && mpParentSegment )
93 {
94 mpParentProgress->SetCurrSegment( mpParentSegment );
95 }
96 else if( !mxSysProgress.get() && (mnTotalSize > 0) )
97 {
98 // System progress has an internal limit of ULONG_MAX/100.
99 mnSysProgressScale = 1;
100 sal_uLong nSysTotalSize = static_cast< sal_uLong >( mnTotalSize );
101 while( nSysTotalSize >= ULONG_MAX / 100 )
102 {
103 nSysTotalSize /= 2;
104 mnSysProgressScale *= 2;
105 }
106 mxSysProgress.reset( new ScProgress( mpDocShell, maText, nSysTotalSize ) );
107 }
108
109 if( !mbInProgress && mpCurrSegment && (mnTotalSize > 0) )
110 {
111 mnUnitSize = mnTotalSize / 256 + 1; // at most 256 calls of system progress
112 mnNextUnitPos = 0;
113 mbInProgress = true;
114 }
115 }
116 }
117
IncreaseProgressBar(sal_Size nDelta)118 void ScfProgressBar::IncreaseProgressBar( sal_Size nDelta )
119 {
120 sal_Size nNewPos = mnTotalPos + nDelta;
121
122 // call back to parent progress bar
123 if( mpParentProgress && mpParentSegment )
124 {
125 // calculate new position of parent progress bar
126 sal_Size nParentPos = static_cast< sal_Size >(
127 static_cast< double >( nNewPos ) * mpParentSegment->mnSize / mnTotalSize );
128 mpParentProgress->ProgressAbs( nParentPos );
129 }
130 // modify system progress bar
131 else if( mxSysProgress.get() )
132 {
133 if( nNewPos >= mnNextUnitPos )
134 {
135 mnNextUnitPos = nNewPos + mnUnitSize;
136 mxSysProgress->SetState( static_cast< sal_uLong >( nNewPos / mnSysProgressScale ) );
137 }
138 }
139 else
140 {
141 DBG_ERRORFILE( "ScfProgressBar::IncreaseProgressBar - no progress bar found" );
142 }
143
144 mnTotalPos = nNewPos;
145 }
146
AddSegment(sal_Size nSize)147 sal_Int32 ScfProgressBar::AddSegment( sal_Size nSize )
148 {
149 DBG_ASSERT( !mbInProgress, "ScfProgressBar::AddSegment - already in progress mode" );
150 if( nSize == 0 )
151 return SCF_INV_SEGMENT;
152
153 maSegments.Append( new ScfProgressSegment( nSize ) );
154 mnTotalSize += nSize;
155 return static_cast< sal_Int32 >( maSegments.Count() - 1 );
156 }
157
GetSegmentProgressBar(sal_Int32 nSegment)158 ScfProgressBar& ScfProgressBar::GetSegmentProgressBar( sal_Int32 nSegment )
159 {
160 ScfProgressSegment* pSegment = GetSegment( nSegment );
161 DBG_ASSERT( !pSegment || (pSegment->mnPos == 0), "ScfProgressBar::GetSegmentProgressBar - segment already started" );
162 if( pSegment && (pSegment->mnPos == 0) )
163 {
164 if( !pSegment->mxProgress.get() )
165 pSegment->mxProgress.reset( new ScfProgressBar( *this, pSegment ) );
166 return *pSegment->mxProgress;
167 }
168 return *this;
169 }
170
IsFull() const171 bool ScfProgressBar::IsFull() const
172 {
173 DBG_ASSERT( mbInProgress && mpCurrSegment, "ScfProgressBar::IsFull - no segment started" );
174 return mpCurrSegment && (mpCurrSegment->mnPos >= mpCurrSegment->mnSize);
175 }
176
ActivateSegment(sal_Int32 nSegment)177 void ScfProgressBar::ActivateSegment( sal_Int32 nSegment )
178 {
179 DBG_ASSERT( mnTotalSize > 0, "ScfProgressBar::ActivateSegment - progress range is zero" );
180 if( mnTotalSize > 0 )
181 SetCurrSegment( GetSegment( nSegment ) );
182 }
183
ProgressAbs(sal_Size nPos)184 void ScfProgressBar::ProgressAbs( sal_Size nPos )
185 {
186 DBG_ASSERT( mbInProgress && mpCurrSegment, "ScfProgressBar::ProgressAbs - no segment started" );
187 if( mpCurrSegment )
188 {
189 DBG_ASSERT( mpCurrSegment->mnPos <= nPos, "ScfProgressBar::ProgressAbs - delta pos < 0" );
190 DBG_ASSERT( nPos <= mpCurrSegment->mnSize, "ScfProgressBar::ProgressAbs - segment overflow" );
191 if( (mpCurrSegment->mnPos < nPos) && (nPos <= mpCurrSegment->mnSize) )
192 {
193 IncreaseProgressBar( nPos - mpCurrSegment->mnPos );
194 mpCurrSegment->mnPos = nPos;
195 }
196 }
197 }
198
Progress(sal_Size nDelta)199 void ScfProgressBar::Progress( sal_Size nDelta )
200 {
201 ProgressAbs( mpCurrSegment ? (mpCurrSegment->mnPos + nDelta) : 0 );
202 }
203
204 // ============================================================================
205
ScfSimpleProgressBar(sal_Size nSize,SfxObjectShell * pDocShell,const String & rText)206 ScfSimpleProgressBar::ScfSimpleProgressBar( sal_Size nSize, SfxObjectShell* pDocShell, const String& rText ) :
207 maProgress( pDocShell, rText )
208 {
209 Init( nSize );
210 }
211
ScfSimpleProgressBar(sal_Size nSize,SfxObjectShell * pDocShell,sal_uInt16 nResId)212 ScfSimpleProgressBar::ScfSimpleProgressBar( sal_Size nSize, SfxObjectShell* pDocShell, sal_uInt16 nResId ) :
213 maProgress( pDocShell, nResId )
214 {
215 Init( nSize );
216 }
217
Init(sal_Size nSize)218 void ScfSimpleProgressBar::Init( sal_Size nSize )
219 {
220 sal_Int32 nSegment = maProgress.AddSegment( nSize );
221 if( nSegment >= 0 )
222 maProgress.ActivateSegment( nSegment );
223 }
224
225 // ============================================================================
226
227 //UNUSED2008-05 ScfStreamProgressBar::ScfStreamProgressBar( SvStream& rStrm, SfxObjectShell* pDocShell, const String& rText ) :
228 //UNUSED2008-05 mrStrm( rStrm )
229 //UNUSED2008-05 {
230 //UNUSED2008-05 Init( pDocShell, rText );
231 //UNUSED2008-05 }
232
ScfStreamProgressBar(SvStream & rStrm,SfxObjectShell * pDocShell,sal_uInt16 nResId)233 ScfStreamProgressBar::ScfStreamProgressBar( SvStream& rStrm, SfxObjectShell* pDocShell, sal_uInt16 nResId ) :
234 mrStrm( rStrm )
235 {
236 Init( pDocShell, ScGlobal::GetRscString( nResId ) );
237 }
238
Progress()239 void ScfStreamProgressBar::Progress()
240 {
241 mxProgress->ProgressAbs( mrStrm.Tell() );
242 }
243
Init(SfxObjectShell * pDocShell,const String & rText)244 void ScfStreamProgressBar::Init( SfxObjectShell* pDocShell, const String& rText )
245 {
246 sal_Size nPos = mrStrm.Tell();
247 mrStrm.Seek( STREAM_SEEK_TO_END );
248 sal_Size nSize = mrStrm.Tell();
249 mrStrm.Seek( nPos );
250
251 mxProgress.reset( new ScfSimpleProgressBar( nSize, pDocShell, rText ) );
252 Progress();
253 }
254
255 // ============================================================================
256
257