source: branches/eraser6/pluginsRewrite/Eraser/ProgressForm.cs @ 2488

Revision 2488, 5.8 KB checked in by lowjoel, 3 years ago (diff)

Change the progress updates to be a pull paradigm and not a push paradigm: this reduces the amount of time the CPU spends sending progress feedback, at the same time, allows future extensibility for decoupling the task executor from the front end.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 * Copyright 2008-2010 The Eraser Project
4 * Original Author: Joel Low <lowjoel@users.sourceforge.net>
5 * Modified By:
6 *
7 * This file is part of Eraser.
8 *
9 * Eraser is free software: you can redistribute it and/or modify it under the
10 * terms of the GNU General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option) any later
12 * version.
13 *
14 * Eraser is distributed in the hope that it will be useful, but WITHOUT ANY
15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 *
18 * A copy of the GNU General Public License can be found at
19 * <http://www.gnu.org/licenses/>.
20 */
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Drawing;
26using System.Text;
27using System.Windows.Forms;
28
29using Eraser.Manager;
30using Eraser.Plugins;
31using Eraser.Plugins.ExtensionPoints;
32using Eraser.Util;
33using System.Globalization;
34
35namespace Eraser
36{
37    public partial class ProgressForm : Form
38    {
39        private Task task;
40        private DateTime lastUpdate;
41
42        public ProgressForm(Task task)
43        {
44            InitializeComponent();
45            Theming.ApplyTheme(this);
46            this.task = task;
47            this.lastUpdate = DateTime.Now;
48            this.ActiveControl = hide;
49
50            //Register the event handlers
51            jobTitle.Text = task.ToString();
52            task.TaskFinished += task_TaskFinished;
53
54            //Set the current progress
55            UpdateProgress();
56        }
57
58        private void ProgressForm_FormClosed(object sender, FormClosedEventArgs e)
59        {
60            task.TaskFinished -= task_TaskFinished;
61        }
62
63        private void progressTimer_Tick(object sender, EventArgs e)
64        {
65            UpdateProgress();
66        }
67
68        private void task_TaskFinished(object sender, EventArgs e)
69        {
70            if (IsDisposed || !IsHandleCreated)
71                return;
72            if (InvokeRequired)
73            {
74                Invoke((EventHandler)task_TaskFinished, sender, e);
75                return;
76            }
77
78            //Update the UI. Set everything to 100%
79            Task task = (Task)sender;
80            timeLeft.Text = item.Text = pass.Text = string.Empty;
81            overallProgressLbl.Text = S._("Total: {0,2:#0.00%}", 1.0);
82            overallProgress.Value = overallProgress.Maximum;
83            itemProgressLbl.Text = "100%";
84            itemProgress.Style = ProgressBarStyle.Continuous;
85            itemProgress.Value = itemProgress.Maximum;
86
87            //Inform the user on the status of the task.
88            LogLevel highestLevel = task.Log.Last().Highest;
89            switch (highestLevel)
90            {
91                case LogLevel.Warning:
92                    status.Text = S._("Completed with warnings");
93                    break;
94                case LogLevel.Error:
95                    status.Text = S._("Completed with errors");
96                    break;
97                case LogLevel.Fatal:
98                    status.Text = S._("Not completed");
99                    break;
100                default:
101                    status.Text = S._("Completed");
102                    break;
103            }
104
105            //Change the Stop button to be a Close button and the Hide button
106            //to be disabled
107            hide.Enabled = false;
108            stop.Text = S._("Close");
109        }
110
111        private void hide_Click(object sender, EventArgs e)
112        {
113            Close();
114        }
115
116        private void stop_Click(object sender, EventArgs e)
117        {
118            if (task.Executing)
119                task.Cancel();
120            Close();
121        }
122
123        private void UpdateProgress()
124        {
125            //Get the name of the current erasure target to display the overall status
126            ErasureTargetProgressManagerStep taskStep =
127                (ErasureTargetProgressManagerStep)task.Progress.CurrentStep;
128            if (taskStep != null && !string.IsNullOrEmpty(taskStep.Name))
129                status.Text = taskStep.Name;
130            else
131                status.Text = S._("Erasing...");
132
133            //The get the current step of the target to set the current item name
134            SteppedProgressManagerStepBase targetStep =
135                (SteppedProgressManagerStepBase)taskStep.Target.Progress.CurrentStep;
136            if (!string.IsNullOrEmpty(targetStep.Name))
137                item.Text = WrapItemName(targetStep.Name);
138
139            //Determine if the tag information of the step's progress manager is an
140            //object array or a string.
141            ProgressManagerBase targetStepProgress = targetStep.Progress;
142            {
143                object tag = targetStepProgress.Tag;
144                if (tag.GetType() == typeof(string))
145                    item.Text = (string)tag;
146                else if (tag.GetType() == typeof(int[]))
147                    pass.Text = S._("{0} out of {1}", ((int[])tag)[0], ((int[])tag)[1]);
148            }
149
150            if (targetStepProgress.TimeLeft >= TimeSpan.Zero)
151                timeLeft.Text = S._("About {0} left", RoundToSeconds(targetStepProgress.TimeLeft));
152            else
153                timeLeft.Text = S._("Unknown");
154
155            if (!targetStepProgress.ProgressIndeterminate)
156            {
157                itemProgress.Style = ProgressBarStyle.Continuous;
158                itemProgress.Value = (int)(targetStepProgress.Progress * 1000);
159                itemProgressLbl.Text = targetStepProgress.Progress.ToString("#0%",
160                    CultureInfo.CurrentCulture);
161            }
162            else
163            {
164                itemProgress.Style = ProgressBarStyle.Marquee;
165                itemProgressLbl.Text = string.Empty;
166            }
167
168            if (!task.Progress.ProgressIndeterminate)
169            {
170                overallProgress.Style = ProgressBarStyle.Continuous;
171                overallProgress.Value = (int)(task.Progress.Progress * 1000);
172                overallProgressLbl.Text = S._("Total: {0,2:#0.00%}", task.Progress.Progress);
173            }
174            else
175            {
176                overallProgress.Style = ProgressBarStyle.Marquee;
177                overallProgressLbl.Text = S._("Total: Unknown");
178            }
179        }
180
181        private string WrapItemName(string itemName)
182        {
183            StringBuilder result = new StringBuilder(itemName.Length);
184            using (Graphics g = item.CreateGraphics())
185            {
186                //Split the long file name into lines which fit into the width of the label
187                while (itemName.Length > 0)
188                {
189                    int chars = 0;
190                    int lines = 0;
191                    g.MeasureString(itemName, item.Font, new SizeF(item.Width - 2, 15),
192                        StringFormat.GenericDefault, out chars, out lines);
193
194                    result.AppendLine(itemName.Substring(0, chars));
195                    itemName = itemName.Remove(0, chars);
196                }
197            }
198
199            return result.ToString();
200        }
201
202        private static TimeSpan RoundToSeconds(TimeSpan span)
203        {
204            return new TimeSpan(span.Ticks - span.Ticks % TimeSpan.TicksPerSecond);
205        }
206    }
207}
Note: See TracBrowser for help on using the repository browser.