source: Common/FormProgress.cs

Last change on this file was 15, checked in by chronos, 13 months ago
  • Modified: Updated files.
File size: 6.5 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.ComponentModel;
4using System.Linq;
5using System.Windows.Forms;
6
7namespace Common
8{
9 public partial class FormProgress : FormEx
10 {
11 public List<Progress> Tasks;
12 public DateTime StartTime;
13 public Progress CurrentTask;
14 private bool _canClose;
15
16 public FormProgress()
17 {
18 InitializeComponent();
19
20 Tasks = new List<Progress>();
21 CurrentTask = null;
22 _canClose = false;
23 }
24
25 private void timer1_Tick(object sender, EventArgs e)
26 {
27 const int steps = 10000;
28 int total = Tasks.Count * steps;
29 int current;
30 int index = Tasks.IndexOf(CurrentTask);
31 if (index >= 0)
32 {
33 current = index * steps;
34 if (CurrentTask.Total > 0) current += (int)(index + ((double)CurrentTask.Current / CurrentTask.Total) * steps);
35 }
36 else current = 0;
37 progressBar1.Maximum = total;
38 if (current <= total) progressBar1.Value = current;
39 else progressBar1.Value = total;
40 progressBar1.Visible = current > 0;
41 if (CurrentTask != null) labelOperation.Text = CurrentTask.Operation;
42 else labelOperation.Text = "";
43 if ((current > 0) && (total > 0))
44 {
45 TimeSpan timeDiff = TimeSpan.FromSeconds((DateTime.Now - StartTime).TotalSeconds / current * (total - current));
46 string remaining = timeDiff.ToString(@"hh\:mm\:ss");
47 if (timeDiff.TotalDays >= 1) remaining = Math.Truncate(timeDiff.TotalDays) + " days " + remaining;
48 labelTime.Text = @"Remaining time: " + remaining;
49 }
50 else labelTime.Text = "";
51
52 // Update task bar progress
53 if (progressBar1.Value < progressBar1.Maximum)
54 {
55 TaskBarProgress.SetValue(Handle, progressBar1.Value, progressBar1.Maximum);
56 if (progressBar1.Value == 0)
57 {
58 TaskBarProgress.SetState(Handle, TaskBarProgress.TaskBarStates.Indeterminate);
59 }
60 }
61 else
62 {
63 TaskBarProgress.SetState(Handle, TaskBarProgress.TaskBarStates.NoProgress);
64 }
65 }
66
67 private void FormProgress_Load(object sender, EventArgs e)
68 {
69 timer1_Tick(this, null);
70 timer1.Enabled = true;
71 progressBar1.Visible = false;
72 }
73
74 private void FormProgress_FormClosing(object sender, FormClosingEventArgs e)
75 {
76 e.Cancel = !_canClose;
77 CurrentTask.Terminated = true;
78 timer1.Enabled = false;
79 }
80
81 private void bg_DoWork(object sender, DoWorkEventArgs e)
82 {
83 CurrentTask.Execute();
84 CurrentTask.Completed = !CurrentTask.Terminated;
85 }
86
87 private void bg_DoWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
88 {
89 if (e.Error != null)
90 {
91 CurrentTask.Terminated = true;
92 MessageBox.Show(e.Error.Message, @"Error in background task", MessageBoxButtons.OK, MessageBoxIcon.Error);
93 }
94 if (!CurrentTask.Terminated)
95 {
96 int nextIndex = Tasks.IndexOf(CurrentTask) + 1;
97 if (nextIndex < Tasks.Count)
98 {
99 CurrentTask = Tasks[nextIndex];
100 BackgroundWorker backgroundWorker = new BackgroundWorker();
101 backgroundWorker.DoWork += bg_DoWork;
102 backgroundWorker.RunWorkerCompleted += bg_DoWorkerCompleted;
103 backgroundWorker.RunWorkerAsync();
104 }
105 else
106 {
107 _canClose = true;
108 Close();
109 }
110 }
111 else
112 {
113 _canClose = true;
114 Close();
115 }
116 }
117
118 public void AddTask(string name, Progress.CallbackEventHandler progressCallback)
119 {
120 Progress newTask = new Progress
121 {
122 Terminated = false,
123 Total = 0,
124 Current = 0,
125 Operation = name
126 };
127 newTask.Callback += progressCallback;
128 Tasks.Add(newTask);
129 }
130
131 public void StartTask(string name, Progress.CallbackEventHandler progressCallback)
132 {
133 Tasks.Clear();
134 AddTask(name, progressCallback);
135 Start();
136 }
137
138 public void Start()
139 {
140 if (Tasks.Count > 0)
141 {
142 StartTime = DateTime.Now;
143 CurrentTask = Tasks.First();
144 BackgroundWorker backgroundWorker = new BackgroundWorker();
145 backgroundWorker.DoWork += bg_DoWork;
146 backgroundWorker.RunWorkerCompleted += bg_DoWorkerCompleted;
147 backgroundWorker.RunWorkerAsync();
148 ShowDialog();
149 }
150 }
151
152 public bool Completed()
153 {
154 int completed = 0;
155 foreach (var task in Tasks)
156 {
157 if (task.Completed) completed += 1;
158 }
159 return completed == Tasks.Count;
160 }
161 }
162
163 public interface IProgress
164 {
165 void SetTotal(int value);
166 void SetProgress(int value);
167 bool GetTerminated();
168 void SetOperation(string text);
169 void Execute();
170 }
171
172 public class Progress : IProgress
173 {
174 public int Total;
175 public int Current;
176 public bool Terminated;
177 public bool Completed; // If task was not terminated during execution.
178 public string Operation;
179 public delegate void CallbackEventHandler(Progress progress);
180 public event CallbackEventHandler Callback;
181
182 public void SetTotal(int value)
183 {
184 Total = value;
185 }
186
187 public void SetProgress(int value)
188 {
189 Current = value;
190 }
191
192 public bool GetTerminated()
193 {
194 return Terminated;
195 }
196
197 public void SetOperation(string text)
198 {
199 Operation = text;
200 }
201
202 public void Execute()
203 {
204 Callback?.Invoke(this);
205 }
206 }
207}
Note: See TracBrowser for help on using the repository browser.