Line data Source code
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 : #ifndef SC_FPROGRESSBAR_HXX
21 : #define SC_FPROGRESSBAR_HXX
22 :
23 : #include <boost/noncopyable.hpp>
24 : #include <boost/ptr_container/ptr_vector.hpp>
25 : #include "globstr.hrc"
26 : #include "ftools.hxx"
27 : #include "scdllapi.h"
28 :
29 : class SfxObjectShell;
30 : class ScProgress;
31 :
32 : // ============================================================================
33 :
34 : const sal_Int32 SCF_INV_SEGMENT = -1;
35 :
36 : // ============================================================================
37 :
38 : /** Progress bar for complex progress representation.
39 :
40 : The progress bar contains one or more segments, each with customable
41 : size. Each segment is represented by a unique identifier. While showing the
42 : progress bar, several segments can be started simultaneously. The progress
43 : bar displays the sum of all started segments on screen.
44 :
45 : It is possible to create a full featured ScfProgressBar object from
46 : any segment. This sub progress bar works only on that parent segment, with
47 : the effect, that if the sub progress bar reaches 100%, the parent segment is
48 : filled completely.
49 :
50 : After adding segments, the progress bar has to be activated. In this step the
51 : total size of all segments is calculated. Therefore it is not possible to add
52 : more segments from here.
53 :
54 : If a sub progress bar is created from a segment, and the main progress bar
55 : has been started (but not the sub progress bar), it is still possible to add
56 : segments to the sub progress bar. It is not allowed to get the sub progress bar
57 : of a started segment. And it is not allowed to modify the segment containing
58 : a sub progress bar directly.
59 :
60 : Following a few code examples, how to use the progress bar.
61 :
62 : Example 1: Simple progress bar (see also ScfSimpleProgressBar below).
63 :
64 : ScfProgressBar aProgress( ... );
65 : sal_Int32 nSeg = aProgress.AddSegment( 50 ); // segment with 50 steps (1 step = 2%)
66 :
67 : aProgress.ActivateSegment( nSeg ); // start segment nSeg
68 : aProgress.Progress(); // 0->1; display: 2%
69 : aProgress.ProgressAbs( 9 ); // 1->9; display: 18%
70 :
71 : Example 2: Progress bar with 2 segments.
72 :
73 : ScfProgressBar aProgress( ... );
74 : sal_Int32 nSeg1 = aProgress.AddSegment( 70 ); // segment with 70 steps
75 : sal_Int32 nSeg2 = aProgress.AddSegment( 30 ); // segment with 30 steps
76 : // both segments: 100 steps (1 step = 1%)
77 :
78 : aProgress.ActivateSegment( nSeg1 ); // start first segment
79 : aProgress.Progress(); // 0->1, display: 1%
80 : aProgress.Progress( 2 ); // 1->3, display: 3%
81 : aProgress.ActivateSegment( nSeg2 ); // start second segment
82 : aProgress.Progress( 5 ); // 0->5, display: 8% (5+3 steps)
83 : aProgress.ActivateSegment( nSeg1 ); // continue with first segment
84 : aProgress.Progress(); // 3->4, display: 9% (5+4 steps)
85 :
86 : Example 3: Progress bar with 2 segments, one contains a sub progress bar.
87 :
88 : ScfProgressBar aProgress( ... );
89 : sal_Int32 nSeg1 = aProgress.AddSegment( 75 ); // segment with 75 steps
90 : sal_Int32 nSeg2 = aProgress.AddSegment( 25 ); // segment with 25 steps
91 : // both segments: 100 steps (1 step = 1%)
92 :
93 : aProgress.ActivateSegment( nSeg1 ); // start first segment
94 : aProgress.Progress(); // 0->1, display: 1%
95 :
96 : ScfProgressBar& rSubProgress = aProgress.GetSegmentProgressBar( nSeg2 );
97 : // sub progress bar from second segment
98 : sal_Int32 nSubSeg = rSubProgress.AddSegment( 5 ); // 5 steps, mapped to second segment
99 : // => 1 step = 5 steps in parent = 5%
100 :
101 : rSubProgress.ActivateSegment( nSubSeg ); // start the segment (auto activate parent segment)
102 : rSubProgress.Progress(); // 0->1 (0->5 in parent); display: 6% (1+5)
103 :
104 : // not allowed (second segment active): aProgress.Progress();
105 : // not allowed (first segment not empty): aProgress.GetSegmentProgressBar( nSeg1 );
106 : */
107 : class ScfProgressBar : private boost::noncopyable
108 : {
109 : public:
110 : explicit ScfProgressBar( SfxObjectShell* pDocShell, const String& rText );
111 : explicit ScfProgressBar( SfxObjectShell* pDocShell, sal_uInt16 nResId );
112 : virtual ~ScfProgressBar();
113 :
114 : /** Adds a new segment to the progress bar.
115 : @return the identifier of the segment. */
116 : sal_Int32 AddSegment( sal_Size nSize );
117 : /** Returns a complete progress bar for the specified segment.
118 : @descr The progress bar can be used to create sub segments inside of the
119 : segment. Do not delete it (done by root progress bar)!
120 : @return A reference to an ScfProgressBar connected to the segment. */
121 : ScfProgressBar& GetSegmentProgressBar( sal_Int32 nSegment );
122 :
123 : /** Returns true, if any progress segment has been started. */
124 : inline bool IsStarted() const { return mbInProgress; }
125 : /** Returns true, if the current progress segment is already full. */
126 : bool IsFull() const;
127 :
128 : /** Starts the progress bar or activates another segment. */
129 : void ActivateSegment( sal_Int32 nSegment );
130 : /** Starts the progress bar (with first segment). */
131 9 : inline void Activate() { ActivateSegment( 0 ); }
132 : /** Set current segment to the specified absolute position. */
133 : void ProgressAbs( sal_Size nPos );
134 : /** Increase current segment by the passed value. */
135 : void Progress( sal_Size nDelta = 1 );
136 :
137 : private:
138 : struct ScfProgressSegment;
139 :
140 : /** Used to create sub progress bars. */
141 : explicit ScfProgressBar(
142 : ScfProgressBar& rParProgress,
143 : ScfProgressSegment* pParSegment );
144 :
145 : /** Initializes all members on construction. */
146 : void Init( SfxObjectShell* pDocShell );
147 :
148 : /** Returns the segment specified by list index. */
149 : ScfProgressSegment* GetSegment( sal_Int32 nSegment );
150 : /** Activates progress bar and sets current segment. */
151 : void SetCurrSegment( ScfProgressSegment* pSegment );
152 : /** Increases mnTotalPos and calls the system progress bar. */
153 : void IncreaseProgressBar( sal_Size nDelta );
154 :
155 : private:
156 : /** Contains all data of a segment of the progress bar. */
157 : struct ScfProgressSegment
158 : {
159 : typedef ::std::auto_ptr< ScfProgressBar > ScfProgressBarPtr;
160 :
161 : ScfProgressBarPtr mxProgress; /// Pointer to sub progress bar for this segment.
162 : sal_Size mnSize; /// Size of this segment.
163 : sal_Size mnPos; /// Current position of this segment.
164 :
165 : explicit ScfProgressSegment( sal_Size nSize );
166 : ~ScfProgressSegment();
167 : };
168 :
169 : typedef ::std::auto_ptr< ScProgress > ScProgressPtr;
170 : typedef boost::ptr_vector< ScfProgressSegment > ScfSegmentList;
171 :
172 : ScfSegmentList maSegments; /// List of progress segments.
173 : String maText; /// UI string for system progress.
174 :
175 : ScProgressPtr mxSysProgress; /// System progress bar.
176 : SfxObjectShell* mpDocShell; /// The document shell for the progress bar.
177 : ScfProgressBar* mpParentProgress; /// Parent progress bar, if this is a segment progress bar.
178 : ScfProgressSegment* mpParentSegment; /// Parent segment, if this is a segment progress bar.
179 : ScfProgressSegment* mpCurrSegment; /// Current segment for progress.
180 :
181 : sal_Size mnTotalSize; /// Total size of all segments.
182 : sal_Size mnTotalPos; /// Sum of positions of all segments.
183 : sal_Size mnUnitSize; /// Size between two calls of system progress.
184 : sal_Size mnNextUnitPos; /// Limit for next system progress call.
185 : sal_Size mnSysProgressScale; /// Additionally scaling factor for system progress.
186 : bool mbInProgress; /// true = progress bar started.
187 : };
188 :
189 : // ============================================================================
190 :
191 : /** A simplified progress bar with only one segment. */
192 21 : class ScfSimpleProgressBar
193 : {
194 : public:
195 : explicit ScfSimpleProgressBar( sal_Size nSize, SfxObjectShell* pDocShell, const String& rText );
196 : explicit ScfSimpleProgressBar( sal_Size nSize, SfxObjectShell* pDocShell, sal_uInt16 nResId );
197 :
198 : /** Set progress bar to the specified position. */
199 33391 : inline void ProgressAbs( sal_Size nPos ) { maProgress.ProgressAbs( nPos ); }
200 : /** Increase progress bar by 1. */
201 : inline void Progress( sal_Size nDelta = 1 ) { maProgress.Progress( nDelta ); }
202 :
203 : private:
204 : /** Initializes and starts the progress bar. */
205 : void Init( sal_Size nSize );
206 :
207 : private:
208 : ScfProgressBar maProgress; /// The used progress bar.
209 : };
210 :
211 : // ============================================================================
212 :
213 : /** A simplified progress bar based on the stream position of an existing stream. */
214 1 : class ScfStreamProgressBar
215 : {
216 : public:
217 : explicit ScfStreamProgressBar( SvStream& rStrm, SfxObjectShell* pDocShell, sal_uInt16 nResId = STR_LOAD_DOC );
218 :
219 : /** Sets the progress bar to the current stream position. */
220 : void Progress();
221 :
222 : private:
223 : /** Initializes and starts the progress bar. */
224 : void Init( SfxObjectShell* pDocShell, const String& rText );
225 :
226 : private:
227 : typedef ::std::auto_ptr< ScfSimpleProgressBar > ScfSimpleProgressBarPtr;
228 :
229 : ScfSimpleProgressBarPtr mxProgress; /// The used progress bar.
230 : SvStream& mrStrm; /// The used stream.
231 : };
232 :
233 : // ============================================================================
234 :
235 : #endif
236 :
237 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|