source: Common/FormProgress.cs

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