-
Notifications
You must be signed in to change notification settings - Fork 7
/
InfoProgress.cs
171 lines (143 loc) · 5.71 KB
/
InfoProgress.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// Copyright (C) 2016 Chang Spivey
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
using System;
using System.Collections.Generic;
namespace subtitleMemorize
{
/// <summary>
/// Information for progress dialog. This is independent of any toolkit because it a handler. Progress
/// information is divided into two types:
///
/// a) the section, which describes what is currently done.
/// The section is a string like "Episode 01 - Extracting subtitle"
/// Every section has...
/// b) ... a number of steps. This is the information how much of the section is handled.
/// An example is the number of processed lines when matching. Each section is finished
/// after the number of processed steps is the same as the number of given steps for
/// this section.
///
///
/// Every section has the same share of the total 100%. There are some section fully completed, then there is the "active" section and then
/// sections, that are 0% complete.
/// Every of the n sections has 1/n part in the progress bar. In-between steps are determined by the sub-steps in the active section.
/// </summary>
public class InfoProgress
{
/// <summary>
/// A section in the whole process. See documentation of InfoProgress for more detail.
/// </summary>
private class ProgressSection
{
private String name; // "Episode 01 - Extracting subtitle"
private int numberOfStepsProcessed; // between 0 and numberOfStepsGiven
private int numberOfStepsGiven;
public String Name {
get { return name; }
}
public int NumbersOfStepsProcessed {
get { return numberOfStepsProcessed; }
}
public int NumbersOfStepsGiven {
get { return numberOfStepsGiven; }
set {
numberOfStepsGiven = value;
if (numberOfStepsProcessed > numberOfStepsGiven)
numberOfStepsProcessed = numberOfStepsGiven;
}
}
public ProgressSection(String name, int numberOfSteps) {
this.name = name;
this.numberOfStepsGiven = numberOfSteps;
this.numberOfStepsProcessed = 0;
}
/// <summary>
/// Increase counter for processed steps. Returns the number of
/// steps that were really increased (in case "new steps + saved steps > max steps").
/// </summary>
/// <returns>The processed steps.</returns>
/// <param name="steps">Steps.</param>
public int AddProcessedSteps(int steps) {
numberOfStepsProcessed += steps;
int restSteps = 0;
if (numberOfStepsProcessed > numberOfStepsGiven) {
restSteps = numberOfStepsProcessed - numberOfStepsGiven;
numberOfStepsProcessed = numberOfStepsGiven;
}
return restSteps;
}
}
private int m_currentSection = 0;
private readonly List<ProgressSection> m_progressSections = new List<ProgressSection>();
private readonly Action<String, double> m_setProgressHandler = null;
private bool m_cancelled = false;
public bool Cancelled {
get { return m_cancelled; }
}
/// <summary>
/// Initializes a new instance of the <see cref="subtitleMemorize.InfoProgress"/> class. The handler takes
/// an information string and a value between 0 and 1, indicating the progress.
/// </summary>
/// <param name="setProgressHandler">Set progress handler.</param>
public InfoProgress (Action<String, double> setProgressHandler)
{
m_setProgressHandler = setProgressHandler;
}
public void AddSection(String name, int numberOfSteps) {
m_progressSections.Add (new ProgressSection (name, numberOfSteps));
}
/// <summary>
/// Show information for 0%.
/// </summary>
public void StartProgressing() {
UpdateHandler ();
}
/// <summary>
/// Increase the number of processed steps by "steps".
/// </summary>
/// <param name="steps">Steps.</param>
public void ProcessedSteps(int steps) {
// update "current" section
int restSteps = m_progressSections [m_currentSection].AddProcessedSteps(steps);
if (m_progressSections [m_currentSection].NumbersOfStepsProcessed >= m_progressSections [m_currentSection].NumbersOfStepsGiven) {
m_currentSection++;
if (m_currentSection >= m_progressSections.Count)
m_currentSection = m_progressSections.Count - 1;
}
while (restSteps > 0) {
m_currentSection++;
if (m_currentSection >= m_progressSections.Count)
m_currentSection = m_progressSections.Count - 1;
restSteps = m_progressSections [m_currentSection].AddProcessedSteps (restSteps);
}
UpdateHandler ();
}
public void Update() {
UpdateHandler();
}
private void UpdateHandler() {
ProgressSection currentSec = m_progressSections [m_currentSection];
double inSectionProgress = (double)currentSec.NumbersOfStepsProcessed / (double)currentSec.NumbersOfStepsGiven;
double sectionPercents = 1.0 / (double) m_progressSections.Count;
double totalPercent = sectionPercents * (m_currentSection + inSectionProgress);
String stepInfo = currentSec.NumbersOfStepsGiven <= 1 ? "" : " " + currentSec.NumbersOfStepsProcessed + "/" + currentSec.NumbersOfStepsGiven;
m_setProgressHandler ((int)(totalPercent * 100) + "% - " + currentSec.Name + stepInfo, totalPercent);
}
public void Cancel() {
m_cancelled = true;
}
}
}