LibreOffice Module sc (master) 1
fprogressbar.cxx
Go to the documentation of this file.
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 <fprogressbar.hxx>
21#include <globstr.hrc>
22#include <scresid.hxx>
23#include <progress.hxx>
24#include <osl/diagnose.h>
25#include <tools/stream.hxx>
26
27#include <limits>
28#include <utility>
29
31 mnSize( nSize ),
32 mnPos( 0 )
33{
34}
35
37{
38}
39
40ScfProgressBar::ScfProgressBar( SfxObjectShell* pDocShell, OUString aText ) :
41 maText(std::move( aText ))
42{
43 Init( pDocShell );
44}
45
47 : maText(ScResId(pResId))
48{
49 Init( pDocShell );
50}
51
53{
54 Init( rParProgress.mpDocShell );
55 mpParentProgress = &rParProgress;
56 mpParentSegment = pParSegment;
57}
58
60{
61}
62
64{
65 mpDocShell = pDocShell;
66 mpParentProgress = nullptr;
69 mnSysProgressScale = 1; // used to workaround the SfxProgress sal_uInt32 limit
70 mbInProgress = false;
71}
72
74{
75 if( nSegment < 0 )
76 return nullptr;
77 return maSegments.at( nSegment ).get();
78}
79
81{
82 if( mpCurrSegment == pSegment )
83 return;
84
85 mpCurrSegment = pSegment;
86
88 {
90 }
91 else if( !mxSysProgress && (mnTotalSize > 0) )
92 {
93 // SfxProgress has a limit of sal_uInt32.
95 std::size_t nSysTotalSize = mnTotalSize;
96 while( nSysTotalSize > std::numeric_limits<sal_uInt32>::max() )
97 {
98 nSysTotalSize /= 2;
100 }
101 mxSysProgress.reset( new ScProgress( mpDocShell, maText, nSysTotalSize, true ) );
102 }
103
104 if( !mbInProgress && mpCurrSegment && (mnTotalSize > 0) )
105 {
106 mnUnitSize = mnTotalSize / 256 + 1; // at most 256 calls of system progress
107 mnNextUnitPos = 0;
108 mbInProgress = true;
109 }
110}
111
112void ScfProgressBar::IncreaseProgressBar( std::size_t nDelta )
113{
114 std::size_t nNewPos = mnTotalPos + nDelta;
115
116 // call back to parent progress bar
118 {
119 // calculate new position of parent progress bar
120 std::size_t nParentPos = static_cast< std::size_t >(
121 static_cast< double >( nNewPos ) * mpParentSegment->mnSize / mnTotalSize );
122 mpParentProgress->ProgressAbs( nParentPos );
123 }
124 // modify system progress bar
125 else if( mxSysProgress )
126 {
127 if( nNewPos >= mnNextUnitPos )
128 {
129 mnNextUnitPos = nNewPos + mnUnitSize;
130 mxSysProgress->SetState( static_cast< sal_uLong >( nNewPos / mnSysProgressScale ) );
131 }
132 }
133 else
134 {
135 OSL_FAIL( "ScfProgressBar::IncreaseProgressBar - no progress bar found" );
136 }
137
138 mnTotalPos = nNewPos;
139}
140
141sal_Int32 ScfProgressBar::AddSegment( std::size_t nSize )
142{
143 OSL_ENSURE( !mbInProgress, "ScfProgressBar::AddSegment - already in progress mode" );
144 if( nSize == 0 )
145 return SCF_INV_SEGMENT;
146
147 maSegments.push_back( std::make_unique<ScfProgressSegment>( nSize ) );
148 mnTotalSize += nSize;
149 return static_cast< sal_Int32 >( maSegments.size() - 1 );
150}
151
153{
154 ScfProgressSegment* pSegment = GetSegment( nSegment );
155 OSL_ENSURE( !pSegment || (pSegment->mnPos == 0), "ScfProgressBar::GetSegmentProgressBar - segment already started" );
156 if( pSegment && (pSegment->mnPos == 0) )
157 {
158 if( !pSegment->mxProgress )
159 pSegment->mxProgress.reset( new ScfProgressBar( *this, pSegment ) );
160 return *pSegment->mxProgress;
161 }
162 return *this;
163}
164
166{
167 OSL_ENSURE( mbInProgress && mpCurrSegment, "ScfProgressBar::IsFull - no segment started" );
169}
170
171void ScfProgressBar::ActivateSegment( sal_Int32 nSegment )
172{
173 OSL_ENSURE( mnTotalSize > 0, "ScfProgressBar::ActivateSegment - progress range is zero" );
174 if( mnTotalSize > 0 )
175 SetCurrSegment( GetSegment( nSegment ) );
176}
177
178void ScfProgressBar::ProgressAbs( std::size_t nPos )
179{
180 OSL_ENSURE( mbInProgress && mpCurrSegment, "ScfProgressBar::ProgressAbs - no segment started" );
181 if( mpCurrSegment )
182 {
183 OSL_ENSURE( mpCurrSegment->mnPos <= nPos, "ScfProgressBar::ProgressAbs - delta pos < 0" );
184 OSL_ENSURE( nPos <= mpCurrSegment->mnSize, "ScfProgressBar::ProgressAbs - segment overflow" );
185 if( (mpCurrSegment->mnPos < nPos) && (nPos <= mpCurrSegment->mnSize) )
186 {
189 }
190 }
191}
192
193void ScfProgressBar::Progress( std::size_t nDelta )
194{
195 ProgressAbs( mpCurrSegment ? (mpCurrSegment->mnPos + nDelta) : 0 );
196}
197
198ScfSimpleProgressBar::ScfSimpleProgressBar( std::size_t nSize, SfxObjectShell* pDocShell, const OUString& rText ) :
199 maProgress( pDocShell, rText )
200{
201 Init( nSize );
202}
203
205 : maProgress(pDocShell, pResId)
206{
207 Init( nSize );
208}
209
210void ScfSimpleProgressBar::Init( std::size_t nSize )
211{
212 sal_Int32 nSegment = maProgress.AddSegment( nSize );
213 if( nSegment >= 0 )
214 maProgress.ActivateSegment( nSegment );
215}
216
218 mrStrm( rStrm )
219{
220 Init( pDocShell, ScResId( STR_LOAD_DOC ) );
221}
222
224{
225 mxProgress->ProgressAbs( mrStrm.Tell() );
226}
227
228void ScfStreamProgressBar::Init( SfxObjectShell* pDocShell, const OUString& rText )
229{
230 sal_uInt64 const nSize = mrStrm.TellEnd();
231 mxProgress.reset( new ScfSimpleProgressBar( nSize, pDocShell, rText ) );
232 Progress();
233}
234
235/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Text maText
Progress bar for complex progress representation.
sal_Int32 AddSegment(std::size_t nSize)
Adds a new segment to the progress bar.
std::size_t mnNextUnitPos
Size between two calls of system progress.
ScfProgressSegment * mpParentSegment
Parent progress bar, if this is a segment progress bar.
bool mbInProgress
Additionally scaling factor for system progress.
std::size_t mnUnitSize
Sum of positions of all segments.
void ProgressAbs(std::size_t nPos)
Set current segment to the specified absolute position.
ScfSegmentList maSegments
void ActivateSegment(sal_Int32 nSegment)
Starts the progress bar or activates another segment.
ScProgressPtr mxSysProgress
UI string for system progress.
bool IsFull() const
Returns true, if the current progress segment is already full.
SfxObjectShell * mpDocShell
System progress bar.
ScfProgressBar & GetSegmentProgressBar(sal_Int32 nSegment)
Returns a complete progress bar for the specified segment.
void Progress(std::size_t nDelta=1)
Increase current segment by the passed value.
std::size_t mnSysProgressScale
Limit for next system progress call.
ScfProgressSegment * mpCurrSegment
Parent segment, if this is a segment progress bar.
ScfProgressBar * mpParentProgress
The document shell for the progress bar.
void SetCurrSegment(ScfProgressSegment *pSegment)
Activates progress bar and sets current segment.
OUString maText
List of progress segments.
void Init(SfxObjectShell *pDocShell)
Initializes all members on construction.
std::size_t mnTotalSize
Current segment for progress.
void IncreaseProgressBar(std::size_t nDelta)
Increases mnTotalPos and calls the system progress bar.
ScfProgressBar(const ScfProgressBar &)=delete
ScfProgressSegment * GetSegment(sal_Int32 nSegment)
Returns the segment specified by list index.
std::size_t mnTotalPos
Total size of all segments.
A simplified progress bar with only one segment.
ScfSimpleProgressBar(std::size_t nSize, SfxObjectShell *pDocShell, const OUString &rText)
void Init(std::size_t nSize)
Initializes and starts the progress bar.
ScfProgressBar maProgress
void Progress()
Sets the progress bar to the current stream position.
SvStream & mrStrm
The used progress bar.
void Init(SfxObjectShell *pDocShell, const OUString &rText)
Initializes and starts the progress bar.
ScfSimpleProgressBarPtr mxProgress
ScfStreamProgressBar(SvStream &rStrm, SfxObjectShell *pDocShell)
sal_uInt64 Tell() const
virtual sal_uInt64 TellEnd()
sal_uInt32 mnSize
const sal_Int32 SCF_INV_SEGMENT
sal_uInt16 nPos
void SvStream & rStrm
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
sal_uIntPtr sal_uLong
Contains all data of a segment of the progress bar.
std::size_t mnSize
Pointer to sub progress bar for this segment.
std::size_t mnPos
Size of this segment.
ScfProgressSegment(std::size_t nSize)
Current position of this segment.
Any maProgress