Changeset 1777
- Timestamp:
- 2/9/2010 7:23:22 AM (3 years ago)
- Location:
- branches/eraser6/CodeReview
- Files:
-
- 10 edited
- 1 moved
-
Eraser.DefaultPlugins/FileSystems/Windows.cs (modified) (8 diffs)
-
Eraser.Manager/DirectExecutor.cs (modified) (9 diffs)
-
Eraser.Manager/Eraser.Manager.csproj (modified) (1 diff)
-
Eraser.Manager/FileSystem.cs (modified) (1 diff)
-
Eraser.Manager/Task.cs (modified) (6 diffs)
-
Eraser.Util/Eraser.Util.csproj (modified) (2 diffs)
-
Eraser.Util/Logger.cs (moved) (moved from branches/eraser6/CodeReview/Eraser.Manager/Logger.cs) (4 diffs)
-
Eraser.Util/Theming.cs (modified) (1 diff)
-
Eraser/LogForm.cs (modified) (9 diffs)
-
Eraser/ProgressForm.cs (modified) (2 diffs)
-
Eraser/SchedulerPanel.cs (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/eraser6/CodeReview/Eraser.DefaultPlugins/FileSystems/Windows.cs
r1745 r1777 155 155 156 156 public override void EraseClusterTips(VolumeInfo info, ErasureMethod method, 157 Logger log, ClusterTipsSearchProgress searchCallback, 158 ClusterTipsEraseProgress eraseCallback) 157 ClusterTipsSearchProgress searchCallback, ClusterTipsEraseProgress eraseCallback) 159 158 { 160 159 //List all the files which can be erased. … … 163 162 throw new InvalidOperationException(S._("Could not erase cluster tips in {0} " + 164 163 "as the volume is not mounted.", info.VolumeId)); 165 ListFiles(new DirectoryInfo(info.MountPoints[0]), files, log,searchCallback);164 ListFiles(new DirectoryInfo(info.MountPoints[0]), files, searchCallback); 166 165 167 166 //For every file, erase the cluster tips. … … 180 179 catch (UnauthorizedAccessException) 181 180 { 182 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have its" +183 " cluster tips erased because you do not have the required permissions to " +184 "erase the file cluster tips.", files[i]), LogLevel.Information));181 Logger.Log(S._("{0} did not have its cluster tips erased because you do not " + 182 "have the required permissions to erase the file cluster tips.", files[i]), 183 LogLevel.Information); 185 184 } 186 185 catch (IOException e) 187 186 { 188 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have its " + 189 "cluster tips erased. The error returned was: {1}", files[i], 190 e.Message), LogLevel.Error)); 187 Logger.Log(S._("{0} did not have its cluster tips erased. The error returned " + 188 "was: {1}", files[i], e.Message), LogLevel.Error); 191 189 } 192 190 finally … … 194 192 streamInfo.Attributes = fileAttr; 195 193 } 194 196 195 eraseCallback(i, files.Count, files[i]); 197 196 } 198 197 } 199 198 200 private void ListFiles(DirectoryInfo info, List<string> files, Logger log,199 private void ListFiles(DirectoryInfo info, List<string> files, 201 200 ClusterTipsSearchProgress searchCallback) 202 201 { … … 206 205 if ((info.Attributes & FileAttributes.ReparsePoint) != 0) 207 206 { 208 log.LastSessionEntries.Add(new LogEntry(S._("Files in {0} did" +209 " not have their cluster tips erased because it is a hard link or " +210 "a symbolic link.", info.FullName), LogLevel.Information));207 Logger.Log(S._("Files in {0} did not have their cluster tips erased because " + 208 "it is a hard link or a symbolic link.", info.FullName), 209 LogLevel.Information); 211 210 return; 212 211 } … … 214 213 foreach (FileInfo file in info.GetFiles()) 215 214 if (file.IsProtectedSystemFile()) 216 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have " + 217 "its cluster tips erased, because it is a system file", 218 file.FullName), LogLevel.Information)); 215 Logger.Log(S._("{0} did not have its cluster tips erased, because it is " + 216 "a system file", file.FullName), LogLevel.Information); 219 217 else if ((file.Attributes & FileAttributes.ReparsePoint) != 0) 220 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have " + 221 "its cluster tips erased because it is a hard link or a " + 222 "symbolic link.", file.FullName), LogLevel.Information)); 218 Logger.Log(S._("{0} did not have its cluster tips erased because it is a " + 219 "hard link or a symbolic link.", file.FullName), LogLevel.Information); 223 220 else if ((file.Attributes & FileAttributes.Compressed) != 0 || 224 221 (file.Attributes & FileAttributes.Encrypted) != 0 || 225 222 (file.Attributes & FileAttributes.SparseFile) != 0) 226 223 { 227 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have" +228 " its cluster tips erased because it is compressed, encrypted " +229 "or a sparse file.", file.FullName), LogLevel.Information));224 Logger.Log(S._("{0} did not have its cluster tips erased because it is " + 225 "compressed, encrypted or a sparse file.", file.FullName), 226 LogLevel.Information); 230 227 } 231 228 else … … 240 237 catch (UnauthorizedAccessException e) 241 238 { 242 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not" +243 " have its cluster tips erased because of the following " +244 "error: {1}", info.FullName, e.Message), LogLevel.Error));239 Logger.Log(S._("{0} did not have its cluster tips erased because of " + 240 "the following error: {1}", info.FullName, e.Message), 241 LogLevel.Error); 245 242 } 246 243 catch (IOException e) 247 244 { 248 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not" +249 " have its cluster tips erased because of the following " +250 "error: {1}", info.FullName, e.Message), LogLevel.Error));245 Logger.Log(S._("{0} did not have its cluster tips erased because of " + 246 "the following error: {1}", info.FullName, e.Message), 247 LogLevel.Error); 251 248 } 252 249 } … … 255 252 { 256 253 searchCallback(subDirInfo.FullName); 257 ListFiles(subDirInfo, files, log,searchCallback);254 ListFiles(subDirInfo, files, searchCallback); 258 255 } 259 256 } 260 257 catch (UnauthorizedAccessException e) 261 258 { 262 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have its " + 263 "cluster tips erased because of the following error: {1}", 264 info.FullName, e.Message), LogLevel.Error)); 259 Logger.Log(S._("{0} did not have its cluster tips erased because of the " + 260 "following error: {1}", info.FullName, e.Message), LogLevel.Error); 265 261 } 266 262 catch (IOException e) 267 263 { 268 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have its " + 269 "cluster tips erased because of the following error: {1}", 270 info.FullName, e.Message), LogLevel.Error)); 264 Logger.Log(S._("{0} did not have its cluster tips erased because of the " + 265 "following error: {1}", info.FullName, e.Message), LogLevel.Error); 271 266 } 272 267 } -
branches/eraser6/CodeReview/Eraser.Manager/DirectExecutor.cs
r1772 r1777 255 255 currentTask = task; 256 256 257 //Prevent the system from sleeping. 258 Power.ExecutionState = ExecutionState.Continuous | 259 ExecutionState.SystemRequired; 257 //Prevent the system from sleeping. 258 Power.ExecutionState = ExecutionState.Continuous | ExecutionState.SystemRequired; 260 259 261 260 //Start a new log session to separate this session's events 262 261 //from previous ones. 263 task.Log.Entries.NewSession(); 264 265 try 266 { 267 //Broadcast the task started event. 268 task.Canceled = false; 269 task.OnTaskStarted(); 270 271 //Run the task 272 foreach (ErasureTarget target in task.Targets) 273 try 274 { 275 UnusedSpaceTarget unusedSpaceTarget = 276 target as UnusedSpaceTarget; 277 FileSystemObjectTarget fileSystemObjectTarget = 278 target as FileSystemObjectTarget; 279 280 if (unusedSpaceTarget != null) 281 EraseUnusedSpace(task, unusedSpaceTarget); 282 else if (fileSystemObjectTarget != null) 283 EraseFilesystemObject(task, fileSystemObjectTarget); 284 else 285 throw new ArgumentException("Unknown erasure target."); 286 } 287 catch (FatalException) 288 { 289 throw; 290 } 291 catch (OperationCanceledException) 292 { 293 throw; 294 } 295 catch (ThreadAbortException) 296 { 297 } 298 catch (Exception e) 299 { 300 task.Log.LastSessionEntries.Add(new LogEntry(e.Message, LogLevel.Error)); 301 BlackBox.Get().CreateReport(e); 302 } 303 } 304 catch (FatalException e) 305 { 306 task.Log.LastSessionEntries.Add(new LogEntry(e.Message, LogLevel.Fatal)); 307 } 308 catch (OperationCanceledException e) 309 { 310 task.Log.LastSessionEntries.Add(new LogEntry(e.Message, LogLevel.Fatal)); 311 } 312 catch (ThreadAbortException) 313 { 314 //Do nothing. The exception will be rethrown after this block 315 //is executed. This is here mainly to ensure that no BlackBox 316 //report is created for this exception. 317 } 318 catch (Exception e) 319 { 320 task.Log.LastSessionEntries.Add(new LogEntry(e.Message, LogLevel.Error)); 321 BlackBox.Get().CreateReport(e); 322 } 323 finally 324 { 325 //Allow the system to sleep again. 326 Power.ExecutionState = ExecutionState.Continuous; 327 328 //If the task is a recurring task, reschedule it since we are done. 329 if (task.Schedule is RecurringSchedule) 330 ((RecurringSchedule)task.Schedule).Reschedule(DateTime.Now); 331 332 //If the task is an execute on restart task, it is only run 333 //once and can now be restored to an immediately executed task 334 if (task.Schedule == Schedule.RunOnRestart) 335 task.Schedule = Schedule.RunNow; 336 337 //And the task finished event. 338 task.OnTaskFinished(); 339 340 //Remove the actively executing task from our instance variable 341 currentTask = null; 262 LogSink sessionLog = new LogSink(); 263 task.Log.Add(sessionLog); 264 using (new LogSession(sessionLog)) 265 { 266 ExecuteTask(task); 342 267 } 343 268 } … … 345 270 //Wait for half a minute to check for the next scheduled task. 346 271 schedulerInterrupt.WaitOne(30000, false); 272 } 273 } 274 275 /// <summary> 276 /// Executes the given task. 277 /// </summary> 278 /// <param name="task">The task to execute.</param> 279 private void ExecuteTask(Task task) 280 { 281 try 282 { 283 //Broadcast the task started event. 284 task.Canceled = false; 285 task.OnTaskStarted(); 286 287 //Run the task 288 foreach (ErasureTarget target in task.Targets) 289 try 290 { 291 UnusedSpaceTarget unusedSpaceTarget = 292 target as UnusedSpaceTarget; 293 FileSystemObjectTarget fileSystemObjectTarget = 294 target as FileSystemObjectTarget; 295 296 if (unusedSpaceTarget != null) 297 EraseUnusedSpace(task, unusedSpaceTarget); 298 else if (fileSystemObjectTarget != null) 299 EraseFilesystemObject(task, fileSystemObjectTarget); 300 else 301 throw new ArgumentException("Unknown erasure target."); 302 } 303 catch (FatalException) 304 { 305 throw; 306 } 307 catch (OperationCanceledException) 308 { 309 throw; 310 } 311 catch (ThreadAbortException) 312 { 313 } 314 catch (Exception e) 315 { 316 Logger.Log(e.Message, LogLevel.Error); 317 BlackBox.Get().CreateReport(e); 318 } 319 } 320 catch (FatalException e) 321 { 322 Logger.Log(e.Message, LogLevel.Fatal); 323 } 324 catch (OperationCanceledException e) 325 { 326 Logger.Log(e.Message, LogLevel.Fatal); 327 } 328 catch (ThreadAbortException) 329 { 330 //Do nothing. The exception will be rethrown after this block 331 //is executed. This is here mainly to ensure that no BlackBox 332 //report is created for this exception. 333 } 334 catch (Exception e) 335 { 336 Logger.Log(e.Message, LogLevel.Error); 337 BlackBox.Get().CreateReport(e); 338 } 339 finally 340 { 341 //Allow the system to sleep again. 342 Power.ExecutionState = ExecutionState.Continuous; 343 344 //If the task is a recurring task, reschedule it since we are done. 345 if (task.Schedule is RecurringSchedule) 346 ((RecurringSchedule)task.Schedule).Reschedule(DateTime.Now); 347 348 //If the task is an execute on restart task, it is only run 349 //once and can now be restored to an immediately executed task 350 if (task.Schedule == Schedule.RunOnRestart) 351 task.Schedule = Schedule.RunNow; 352 353 //And the task finished event. 354 task.OnTaskFinished(); 355 356 //Remove the actively executing task from our instance variable 357 currentTask = null; 347 358 } 348 359 } … … 361 372 Environment.OSVersion.Version >= new Version(6, 0)) 362 373 { 363 task.Log.LastSessionEntries.Add(new LogEntry(S._("The program does not have " +364 "the required permissions to erase the unused space on disk. Run the" +365 " program as an administrator and retry the operation."), LogLevel.Error));374 Logger.Log(S._("The program does not have the required permissions to erase " + 375 "the unused space on disk. Run the program as an administrator and retry " + 376 "the operation."), LogLevel.Error); 366 377 } 367 378 else 368 379 { 369 task.Log.LastSessionEntries.Add(new LogEntry(S._("The program does not have " + 370 "the required permissions to erase the unused space on disk."), 371 LogLevel.Error)); 380 Logger.Log(S._("The program does not have the required permissions to erase " + 381 "the unused space on disk."), LogLevel.Error); 372 382 } 373 383 } … … 376 386 if (SystemRestore.GetInstances().Count != 0) 377 387 { 378 task.Log.LastSessionEntries.Add(new LogEntry(S._("The drive {0} has System " + 379 "Restore or Volume Shadow Copies enabled. This may allow copies of files " + 380 "stored on the disk to be recovered and pose a security concern.", 381 target.Drive), LogLevel.Warning)); 388 Logger.Log(S._("The drive {0} has System Restore or Volume Shadow Copies " + 389 "enabled. This may allow copies of files stored on the disk to be recovered " + 390 "and pose a security concern.", target.Drive), LogLevel.Warning); 382 391 } 383 392 384 393 //If the user is under disk quotas, log a warning message 385 394 if (VolumeInfo.FromMountPoint(target.Drive).HasQuota) 386 task.Log.LastSessionEntries.Add(new LogEntry(S._("The drive {0} has disk quotas" +387 " active. This will prevent the complete erasure of unused space and may pose " +388 "a security concern.", target.Drive), LogLevel.Warning));395 Logger.Log(S._("The drive {0} has disk quotas active. This will prevent the " + 396 "complete erasure of unused space and may pose a security concern.", 397 target.Drive), LogLevel.Warning); 389 398 390 399 //Get the erasure method if the user specified he wants the default. … … 439 448 //Start counting statistics 440 449 fsManager.EraseClusterTips(VolumeInfo.FromMountPoint(target.Drive), 441 method, task.Log,searchProgress, eraseProgress);450 method, searchProgress, eraseProgress); 442 451 tipProgress.MarkComplete(); 443 452 } … … 608 617 if (!info.Exists) 609 618 { 610 task.Log.LastSessionEntries.Add(new LogEntry(S._("The file {0} was not erased " +611 "as the file does not exist.", paths[i]), LogLevel.Notice));619 Logger.Log(S._("The file {0} was not erased as the file does not exist.", 620 paths[i]), LogLevel.Notice); 612 621 continue; 613 622 } … … 632 641 { 633 642 //Log the error 634 task.Log.LastSessionEntries.Add(new LogEntry(S._("The file {0} could" +635 " not be erased because the file was either compressed, encrypted or " +636 "a sparse file.", info.FullName), LogLevel.Error));643 Logger.Log(S._("The file {0} could not be erased because the file was " + 644 "either compressed, encrypted or a sparse file.", info.FullName), 645 LogLevel.Error); 637 646 continue; 638 647 } … … 659 668 catch (UnauthorizedAccessException) 660 669 { 661 task.Log.LastSessionEntries.Add(new LogEntry(S._("The file {0} could not " + 662 "be erased because the file's permissions prevent access to the file.", 663 info.FullName), LogLevel.Error)); 670 Logger.Log(S._("The file {0} could not be erased because the file's " + 671 "permissions prevent access to the file.", info.FullName), LogLevel.Error); 664 672 } 665 673 catch (IOException) … … 696 704 } 697 705 698 task.Log.LastSessionEntries.Add(new LogEntry(S._( 699 "Could not force closure of file \"{0}\" {1}", paths[i], 700 lockedBy == null ? string.Empty : lockedBy).Trim(), LogLevel.Error)); 706 Logger.Log(S._("Could not force closure of file \"{0}\" {1}", paths[i], 707 lockedBy == null ? string.Empty : lockedBy).Trim(), LogLevel.Error); 701 708 } 702 709 else -
branches/eraser6/CodeReview/Eraser.Manager/Eraser.Manager.csproj
r1625 r1777 71 71 <Compile Include="FileSystem.cs" /> 72 72 <Compile Include="Language.cs" /> 73 <Compile Include="Logger.cs" />74 73 <Compile Include="ManagerLibrary.cs" /> 75 74 <Compile Include="Method.cs" /> -
branches/eraser6/CodeReview/Eraser.Manager/FileSystem.cs
r1746 r1777 203 203 /// <param name="eraseCallback">The callback function for erasure progress.</param> 204 204 public abstract void EraseClusterTips(VolumeInfo info, ErasureMethod method, 205 Logger log, ClusterTipsSearchProgress searchCallback, 206 ClusterTipsEraseProgress eraseCallback); 205 ClusterTipsSearchProgress searchCallback, ClusterTipsEraseProgress eraseCallback); 207 206 208 207 /// <summary> -
branches/eraser6/CodeReview/Eraser.Manager/Task.cs
r1767 r1777 47 47 Targets = (ErasureTargetsCollection)info.GetValue("Targets", typeof(ErasureTargetsCollection)); 48 48 Targets.Owner = this; 49 Log = (L ogger)info.GetValue("Log", typeof(Logger));49 Log = (List<LogSink>)info.GetValue("Log", typeof(List<LogSink>)); 50 50 Canceled = false; 51 51 … … 83 83 Schedule = Schedule.RunNow; 84 84 Canceled = false; 85 Log = new L ogger();85 Log = new List<LogSink>(); 86 86 } 87 87 … … 198 198 /// The log entries which this task has accumulated. 199 199 /// </summary> 200 public L oggerLog { get; private set; }200 public List<LogSink> Log { get; private set; } 201 201 202 202 /// <summary> … … 481 481 //The system cannot read the file, assume no ADSes for lack of 482 482 //more information. 483 Task.Log.LastSessionEntries.Add(new LogEntry(e.Message, LogLevel.Error));483 Logger.Log(e.Message, LogLevel.Error); 484 484 } 485 485 } … … 743 743 catch (UnauthorizedAccessException e) 744 744 { 745 Task.Log.LastSessionEntries.Add(new LogEntry(S._("Could not erase files and " +746 "subfolders in {0} because {1}", info.FullName, e.Message), LogLevel.Error));745 Logger.Log(S._("Could not erase files and subfolders in {0} because {1}", 746 info.FullName, e.Message), LogLevel.Error); 747 747 } 748 748 } … … 840 840 catch (UnauthorizedAccessException e) 841 841 { 842 Task.Log.LastSessionEntries.Add(new LogEntry(e.Message, LogLevel.Error));842 Logger.Log(e.Message, LogLevel.Error); 843 843 } 844 844 } -
branches/eraser6/CodeReview/Eraser.Util/Eraser.Util.csproj
r1745 r1777 50 50 </PropertyGroup> 51 51 <ItemGroup> 52 <Reference Include="CommonLibrary, Version=0.9.3.10, Culture=neutral, PublicKeyToken=3ac89a0351e689b6, processorArchitecture=MSIL"> 53 <SpecificVersion>False</SpecificVersion> 54 <HintPath>..\Dependencies\CommonLibrary.dll</HintPath> 55 </Reference> 52 56 <Reference Include="ICSharpCode.SharpZipLib, Version=0.85.5.452, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL"> 53 57 <SpecificVersion>False</SpecificVersion> … … 102 106 <Compile Include="ConsoleWindow.cs" /> 103 107 <Compile Include="FileSize.cs" /> 108 <Compile Include="Logger.cs" /> 104 109 <Compile Include="NativeMethods\DbgHelp.cs" /> 105 110 <Compile Include="NativeMethods\Mpr.cs" /> -
branches/eraser6/CodeReview/Eraser.Util/Logger.cs
r1772 r1777 1 /*1 /* 2 2 * $Id$ 3 3 * Copyright 2008-2010 The Eraser Project … … 21 21 22 22 using System; 23 using System.Linq; 23 24 using System.Collections.Generic; 24 25 using System.Text; 26 27 using System.Collections.ObjectModel; 28 using System.Threading; 25 29 using System.Runtime.Serialization; 26 30 using System.Security.Permissions; 27 31 28 namespace Eraser. Manager32 namespace Eraser.Util 29 33 { 30 34 /// <summary> … … 60 64 61 65 /// <summary> 62 /// The Logger class which handles log entries and manages entries.63 ///64 /// The class has the notion of entries and sessions. Each session contains one65 /// or more (log) entries. This allows the program to determine if the last66 /// session had errors or not.67 /// </summary>68 [Serializable]69 public class Logger : ISerializable70 {71 #region Serialization code72 protected Logger(SerializationInfo info, StreamingContext context)73 {74 Entries = (LogSessionDictionary)info.GetValue("Entries", typeof(LogSessionDictionary));75 Entries.Owner = this;76 foreach (DateTime key in Entries.Keys)77 LastSession = key;78 }79 80 [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)]81 public virtual void GetObjectData(SerializationInfo info, StreamingContext context)82 {83 info.AddValue("Entries", Entries);84 }85 #endregion86 87 /// <summary>88 /// Constructor.89 /// </summary>90 public Logger()91 {92 Entries = new LogSessionDictionary(this);93 }94 95 /// <summary>96 /// All the registered event handlers for the log event of this task.97 /// </summary>98 public EventHandler<LogEventArgs> Logged { get; set; }99 100 internal void OnLogged(object sender, LogEventArgs e)101 {102 if (Logged != null)103 Logged(sender, e);104 }105 106 /// <summary>107 /// All the registered event handlers for handling when a new session has been108 /// started.109 /// </summary>110 public EventHandler<EventArgs> NewSession { get; set; }111 112 internal void OnNewSession(object sender, EventArgs e)113 {114 if (NewSession != null)115 NewSession(sender, e);116 }117 118 /// <summary>119 /// Retrieves the log for this task.120 /// </summary>121 public LogSessionDictionary Entries { get; private set; }122 123 /// <summary>124 /// Retrieves the log entries from the previous session.125 /// </summary>126 public LogEntryCollection LastSessionEntries127 {128 get129 {130 return Entries[LastSession];131 }132 }133 134 /// <summary>135 /// Clears the log entries from the log.136 /// </summary>137 public void Clear()138 {139 LogEntryCollection lastSessionEntries = null;140 if (Entries.ContainsKey(LastSession))141 lastSessionEntries = Entries[LastSession];142 Entries.Clear();143 144 if (lastSessionEntries != null)145 Entries.Add(LastSession, lastSessionEntries);146 }147 148 /// <summary>149 /// The date and time of the last session.150 /// </summary>151 public DateTime LastSession152 {153 get { return lastSession; }154 internal set { lastSession = value; OnNewSession(null, EventArgs.Empty); }155 }156 157 private DateTime lastSession;158 }159 160 public class LogEventArgs : EventArgs161 {162 /// <summary>163 /// Constructor.164 /// </summary>165 /// <param name="entry">The log entry that was just logged.</param>166 public LogEventArgs(LogEntry entry)167 {168 LogEntry = entry;169 }170 171 /// <summary>172 /// The log entry that was just logged.173 /// </summary>174 public LogEntry LogEntry { get; private set; }175 }176 177 [Serializable]178 public class LogSessionDictionary : IDictionary<DateTime, LogEntryCollection>,179 ISerializable180 {181 /// <summary>182 /// Constructor.183 /// </summary>184 /// <param name="logger">The logger object managing the logging.</param>185 public LogSessionDictionary(Logger logger)186 {187 Owner = logger;188 }189 190 public void NewSession()191 {192 DateTime sessionTime = DateTime.Now;193 Add(sessionTime, new LogEntryCollection(Owner));194 Owner.LastSession = sessionTime;195 }196 197 #region ISerializable Members198 protected LogSessionDictionary(SerializationInfo info, StreamingContext context)199 {200 dictionary = (Dictionary<DateTime, LogEntryCollection>)info.GetValue("Dictionary",201 dictionary.GetType());202 }203 204 [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]205 public virtual void GetObjectData(SerializationInfo info, StreamingContext context)206 {207 lock (dictionary)208 info.AddValue("Dictionary", dictionary);209 }210 #endregion211 212 #region IDictionary<DateTime,LogSessionEntryCollection> Members213 public void Add(DateTime key, LogEntryCollection value)214 {215 lock (dictionary)216 dictionary.Add(key, value);217 }218 219 public bool ContainsKey(DateTime key)220 {221 lock (dictionary)222 return dictionary.ContainsKey(key);223 }224 225 public ICollection<DateTime> Keys226 {227 get228 {229 lock (dictionary)230 {231 DateTime[] result = new DateTime[dictionary.Keys.Count];232 dictionary.Keys.CopyTo(result, 0);233 return result;234 }235 }236 }237 238 public bool Remove(DateTime key)239 {240 lock (dictionary)241 return dictionary.Remove(key);242 }243 244 public bool TryGetValue(DateTime key, out LogEntryCollection value)245 {246 lock (dictionary)247 return dictionary.TryGetValue(key, out value);248 }249 250 public ICollection<LogEntryCollection> Values251 {252 get253 {254 lock (dictionary)255 {256 LogEntryCollection[] result = new LogEntryCollection[dictionary.Values.Count];257 dictionary.Values.CopyTo(result, 0);258 return result;259 }260 }261 }262 263 public LogEntryCollection this[DateTime key]264 {265 get266 {267 lock (dictionary)268 return dictionary[key];269 }270 set271 {272 lock (dictionary)273 dictionary[key] = value;274 }275 }276 #endregion277 278 #region ICollection<KeyValuePair<DateTime,LogSessionEntryCollection>> Members279 public void Add(KeyValuePair<DateTime, LogEntryCollection> item)280 {281 Add(item.Key, item.Value);282 }283 284 public void Clear()285 {286 lock (dictionary)287 dictionary.Clear();288 }289 290 public bool Contains(KeyValuePair<DateTime, LogEntryCollection> item)291 {292 lock (dictionary)293 return dictionary.ContainsKey(item.Key) && dictionary[item.Key] == item.Value;294 }295 296 public void CopyTo(KeyValuePair<DateTime, LogEntryCollection>[] array, int arrayIndex)297 {298 throw new NotImplementedException();299 }300 301 public int Count302 {303 get304 {305 lock (dictionary)306 return dictionary.Count;307 }308 }309 310 public bool IsReadOnly311 {312 get { return false; }313 }314 315 public bool Remove(KeyValuePair<DateTime, LogEntryCollection> item)316 {317 lock (dictionary)318 return dictionary.Remove(item.Key);319 }320 #endregion321 322 #region IEnumerable<KeyValuePair<DateTime,LogSessionEntryCollection>> Members323 public IEnumerator<KeyValuePair<DateTime, LogEntryCollection>> GetEnumerator()324 {325 return dictionary.GetEnumerator();326 }327 #endregion328 329 #region IEnumerable Members330 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()331 {332 return GetEnumerator();333 }334 #endregion335 336 /// <summary>337 /// The log manager.338 /// </summary>339 internal Logger Owner340 {341 get342 {343 return owner;344 }345 set346 {347 lock (dictionary)348 foreach (LogEntryCollection entries in dictionary.Values)349 entries.owner = value;350 owner = value;351 }352 }353 354 /// <summary>355 /// The log manager.356 /// </summary>357 private Logger owner;358 359 /// <summary>360 /// The store for this object.361 /// </summary>362 private Dictionary<DateTime, LogEntryCollection> dictionary =363 new Dictionary<DateTime, LogEntryCollection>();364 }365 366 [Serializable]367 public class LogEntryCollection : IList<LogEntry>368 {369 /// <summary>370 /// Constructor.371 /// </summary>372 /// <param name="logger">The <see cref="Logger"/> object handling logging.</param>373 internal LogEntryCollection(Logger logger)374 {375 owner = logger;376 }377 378 #region IList<LogEntry> Members379 public int IndexOf(LogEntry item)380 {381 lock (list)382 return list.IndexOf(item);383 }384 385 public void Insert(int index, LogEntry item)386 {387 lock (list)388 list.Insert(index, item);389 owner.OnLogged(owner, new LogEventArgs(item));390 }391 392 public void RemoveAt(int index)393 {394 throw new InvalidOperationException();395 }396 397 public LogEntry this[int index]398 {399 get400 {401 lock (list)402 return list[index];403 }404 set405 {406 throw new InvalidOperationException();407 }408 }409 #endregion410 411 #region ICollection<LogEntry> Members412 public void Add(LogEntry item)413 {414 Insert(Count, item);415 }416 417 public void Clear()418 {419 throw new InvalidOperationException();420 }421 422 public bool Contains(LogEntry item)423 {424 lock (list)425 return list.Contains(item);426 }427 428 public void CopyTo(LogEntry[] array, int arrayIndex)429 {430 lock (list)431 list.CopyTo(array, arrayIndex);432 }433 434 public int Count435 {436 get437 {438 lock (list)439 return list.Count;440 }441 }442 443 public bool IsReadOnly444 {445 get { return false; }446 }447 448 public bool Remove(LogEntry item)449 {450 lock (list)451 return list.Remove(item);452 }453 #endregion454 455 #region IEnumerable<LogEntry> Members456 public IEnumerator<LogEntry> GetEnumerator()457 {458 return list.GetEnumerator();459 }460 #endregion461 462 #region IEnumerable Members463 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()464 {465 return GetEnumerator();466 }467 #endregion468 469 /// <summary>470 /// The Logger object managing logging.471 /// </summary>472 internal Logger owner;473 474 /// <summary>475 /// The store for this object.476 /// </summary>477 private List<LogEntry> list = new List<LogEntry>();478 }479 480 /// <summary>481 66 /// Represents a log entry. 482 67 /// </summary> … … 530 115 public string Message { get; private set; } 531 116 } 117 118 /// <summary> 119 /// Event Data for all Logger events. 120 /// </summary> 121 public class LogEventArgs : EventArgs 122 { 123 /// <summary> 124 /// Constructor. 125 /// </summary> 126 /// <param name="entry">The log entry that was just logged.</param> 127 public LogEventArgs(LogEntry entry) 128 { 129 LogEntry = entry; 130 } 131 132 /// <summary> 133 /// The log entry that was just logged. 134 /// </summary> 135 public LogEntry LogEntry { get; private set; } 136 } 137 138 /// <summary> 139 /// Provides a standard logging interface to the rest of the Eraser classes. 140 /// </summary> 141 public static class Logger 142 { 143 static Logger() 144 { 145 Listeners = new LogThreadDictionary(); 146 } 147 148 /// <summary> 149 /// Logs an informational message. 150 /// </summary> 151 /// <param name="message">The message to log.</param> 152 public static void Log(string message) 153 { 154 Log(new LogEntry(message, LogLevel.Information)); 155 } 156 157 /// <summary> 158 /// Logs a message to the logger. 159 /// </summary> 160 /// <param name="message">The message to store.</param> 161 /// <param name="level">The level of the message.</param> 162 public static void Log(string message, LogLevel level) 163 { 164 Log(new LogEntry(message, level)); 165 } 166 167 /// <summary> 168 /// Logs the provided entry to the logger. 169 /// </summary> 170 /// <param name="entry">The log entry to store.</param> 171 public static void Log(LogEntry entry) 172 { 173 Thread currentThread = Thread.CurrentThread; 174 List<ILogTarget> targets = new List<ILogTarget>(); 175 176 if (Listeners.ContainsKey(currentThread)) 177 { 178 LogThreadTargets threadTargets = Listeners[currentThread]; 179 if (threadTargets != null) 180 targets.AddRange(threadTargets); 181 } 182 183 targets.ForEach( 184 target => target.OnEventLogged(currentThread, new LogEventArgs(entry))); 185 } 186 187 /// <summary> 188 /// The list of listeners for events on a particular thread. 189 /// </summary> 190 public static LogThreadDictionary Listeners { get; private set; } 191 } 192 193 /// <summary> 194 /// The Logger Thread Dictionary, which maps log event listeners to threads. 195 /// This mainly serves as a thread-safe Dictionary. 196 /// </summary> 197 public class LogThreadDictionary : IDictionary<Thread, LogThreadTargets> 198 { 199 #region IDictionary<Thread,LogThreadTargets> Members 200 201 public void Add(Thread key, LogThreadTargets value) 202 { 203 lock (Dictionary) 204 Dictionary.Add(key, value); 205 } 206 207 public bool ContainsKey(Thread key) 208 { 209 return Dictionary.ContainsKey(key); 210 } 211 212 public ICollection<Thread> Keys 213 { 214 get 215 { 216 lock (Dictionary) 217 { 218 Thread[] result = new Thread[Dictionary.Keys.Count]; 219 Dictionary.Keys.CopyTo(result, 0); 220 221 return new ReadOnlyCollection<Thread>(result); 222 } 223 } 224 } 225 226 public bool Remove(Thread key) 227 { 228 lock (Dictionary) 229 return Dictionary.Remove(key); 230 } 231 232 public bool TryGetValue(Thread key, out LogThreadTargets value) 233 { 234 lock (Dictionary) 235 return Dictionary.TryGetValue(key, out value); 236 } 237 238 public ICollection<LogThreadTargets> Values 239 { 240 get 241 { 242 lock (Dictionary) 243 { 244 LogThreadTargets[] result = 245 new LogThreadTargets[Dictionary.Values.Count]; 246 Dictionary.Values.CopyTo(result, 0); 247 248 return new ReadOnlyCollection<LogThreadTargets>(result); 249 } 250 } 251 } 252 253 public LogThreadTargets this[Thread key] 254 { 255 get 256 { 257 lock (Dictionary) 258 return Dictionary[key]; 259 } 260 set 261 { 262 lock (Dictionary) 263 Dictionary[key] = value; 264 } 265 } 266 267 #endregion 268 269 #region ICollection<KeyValuePair<Thread,LogThreadTargets>> Members 270 271 public void Add(KeyValuePair<Thread, LogThreadTargets> item) 272 { 273 lock (Dictionary) 274 Dictionary.Add(item.Key, item.Value); 275 } 276 277 public void Clear() 278 { 279 lock (Dictionary) 280 Dictionary.Clear(); 281 } 282 283 public bool Contains(KeyValuePair<Thread, LogThreadTargets> item) 284 { 285 lock (Dictionary) 286 return Dictionary.ContainsKey(item.Key) && Dictionary[item.Key] == item.Value; 287 } 288 289 public void CopyTo(KeyValuePair<Thread, LogThreadTargets>[] array, int arrayIndex) 290 { 291 throw new NotImplementedException(); 292 } 293 294 public int Count 295 { 296 get 297 { 298 lock (Dictionary) 299 return Dictionary.Count; 300 } 301 } 302 303 public bool IsReadOnly 304 { 305 get { return false; } 306 } 307 308 public bool Remove(KeyValuePair<Thread, LogThreadTargets> item) 309 { 310 lock (Dictionary) 311 return Dictionary.Remove(item.Key); 312 } 313 314 #endregion 315 316 #region IEnumerable<KeyValuePair<Thread,LogThreadTargets>> Members 317 318 public IEnumerator<KeyValuePair<Thread, LogThreadTargets>> GetEnumerator() 319 { 320 return Dictionary.GetEnumerator(); 321 } 322 323 #endregion 324 325 #region IEnumerable Members 326 327 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 328 { 329 return Dictionary.GetEnumerator(); 330 } 331 332 #endregion 333 334 /// <summary> 335 /// The backing store for this dictionary. 336 /// </summary> 337 private Dictionary<Thread, LogThreadTargets> Dictionary = 338 new Dictionary<Thread, LogThreadTargets>(); 339 } 340 341 public class LogThreadTargets : IList<ILogTarget> 342 { 343 #region IList<ILogTarget> Members 344 345 public int IndexOf(ILogTarget item) 346 { 347 lock (List) 348 return List.IndexOf(item); 349 } 350 351 public void Insert(int index, ILogTarget item) 352 { 353 lock (List) 354 List.Insert(index, item); 355 } 356 357 public void RemoveAt(int index) 358 { 359 lock (List) 360 List.RemoveAt(index); 361 } 362 363 public ILogTarget this[int index] 364 { 365 get 366 { 367 lock (List) 368 return List[index]; 369 } 370 set 371 { 372 lock (List) 373 List[index] = value; 374 } 375 } 376 377 #endregion 378 379 #region ICollection<ILogTarget> Members 380 381 public void Add(ILogTarget item) 382 { 383 lock (List) 384 List.Add(item); 385 } 386 387 public void Clear() 388 { 389 lock (List) 390 List.Clear(); 391 } 392 393 public bool Contains(ILogTarget item) 394 { 395 lock (List) 396 return List.Contains(item); 397 } 398 399 public void CopyTo(ILogTarget[] array, int arrayIndex) 400 { 401 lock (List) 402 List.CopyTo(array, arrayIndex); 403 } 404 405 public int Count 406 { 407 get 408 { 409 lock (List) 410 return List.Count; 411 } 412 } 413 414 public bool IsReadOnly 415 { 416 get { return false; } 417 } 418 419 public bool Remove(ILogTarget item) 420 { 421 lock (List) 422 return List.Remove(item); 423 } 424 425 #endregion 426 427 #region IEnumerable<ILogTarget> Members 428 429 public IEnumerator<ILogTarget> GetEnumerator() 430 { 431 return List.GetEnumerator(); 432 } 433 434 #endregion 435 436 #region IEnumerable Members 437 438 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 439 { 440 return List.GetEnumerator(); 441 } 442 443 #endregion 444 445 /// <summary> 446 /// The backing store for this list. 447 /// </summary> 448 private List<ILogTarget> List = new List<ILogTarget>(); 449 } 450 451 /// <summary> 452 /// The logger target interface which all interested listeners of log events must 453 /// implement. 454 /// </summary> 455 public interface ILogTarget 456 { 457 /// <summary> 458 /// The handler for events. 459 /// </summary> 460 /// <param name="sender">The sender of the event.</param> 461 /// <param name="e">The event data associated with the event.</param> 462 void OnEventLogged(object sender, LogEventArgs e); 463 464 /// <summary> 465 /// Chains the provided target to the current target, so that when this 466 /// target receives an event, the provided target is also executed. 467 /// </summary> 468 /// <param name="target">The target to chain with the current one.</param> 469 /// <remarks>Chaining a target multiple times will cause the target to 470 /// be invoked multiple times for every event.</remarks> 471 void Chain(ILogTarget target); 472 473 /// <summary> 474 /// Unchains the provided target from the current target, so that the 475 /// provided target is no longer invoked when this target receives an event. 476 /// </summary> 477 /// <param name="target">The target to unchain</param> 478 /// <remarks>Multiply-chained targets need to be unchained the same amount 479 /// of time to be completely removed.</remarks> 480 void Unchain(ILogTarget target); 481 } 482 483 /// <summary> 484 /// Registers a provided log target to receive log messages for the lifespan 485 /// of this object. 486 /// </summary> 487 public sealed class LogSession : IDisposable 488 { 489 /// <summary> 490 /// Constructor. Registers the given log target with the provided threads 491 /// for listening for log messages. 492 /// </summary> 493 /// <param name="target">The target that should receive events.</param> 494 /// <param name="threads">The threads which the target will be registered 495 /// with for event notifications.</param> 496 public LogSession(ILogTarget target, params Thread[] threads) 497 { 498 Target = target; 499 Threads = threads.Distinct().ToArray(); 500 501 foreach (Thread thread in Threads) 502 Logger.Listeners[thread].Add(target); 503 } 504 505 /// <summary> 506 /// Constructor. Registered the given log target with the current thread 507 /// for listening for log messages. 508 /// </summary> 509 /// <param name="target">The target which should receive events</param> 510 public LogSession(ILogTarget target) 511 : this(target, Thread.CurrentThread) 512 { 513 } 514 515 #region IDisposable Members 516 517 ~LogSession() 518 { 519 Dispose(false); 520 } 521 522 private void Dispose(bool disposing) 523 { 524 if (Threads == null || Target == null) 525 return; 526 527 if (disposing) 528 { 529 //Disconnect the event handler from the threads. 530 foreach (Thread thread in Threads) 531 Logger.Listeners[thread].Remove(Target); 532 } 533 534 Threads = null; 535 Target = null; 536 } 537 538 public void Dispose() 539 { 540 Dispose(true); 541 GC.SuppressFinalize(this); 542 } 543 544 #endregion 545 546 /// <summary> 547 /// The target that should receive events. If this is null, the object 548 /// has been disposed. 549 /// </summary> 550 private ILogTarget Target; 551 552 /// <summary> 553 /// The list of threads which the target will be registered with for event 554 /// notifications. If this is null, the object is disposd. 555 /// </summary> 556 private Thread[] Threads; 557 } 558 559 /// <summary> 560 /// Collects a list of log entries into one session. 561 /// </summary> 562 /// <remarks>Instance functions of this class are thread-safe.</remarks> 563 public class LogSink : ILogTarget, IList<LogEntry> 564 { 565 #region ILoggerTarget Members 566 567 public void OnEventLogged(object sender, LogEventArgs e) 568 { 569 lock (List) 570 List.Add(e.LogEntry); 571 572 lock (ChainedTargets) 573 ChainedTargets.ForEach(target => target.OnEventLogged(sender, e)); 574 } 575 576 public void Chain(ILogTarget target) 577 { 578 lock (ChainedTargets) 579 ChainedTargets.Add(target); 580 } 581 582 public void Unchain(ILogTarget target) 583 { 584 lock (ChainedTargets) 585 ChainedTargets.Remove(target); 586 } 587 588 /// <summary> 589 /// The list of targets which are chained to this one. 590 /// </summary> 591 private List<ILogTarget> ChainedTargets = new List<ILogTarget>(); 592 593 #endregion 594 595 #region IList<LogEntry> Members 596 597 public int IndexOf(LogEntry item) 598 { 599 lock (List) 600 return IndexOf(item); 601 } 602 603 public void Insert(int index, LogEntry item) 604 { 605 lock (List) 606 List.Insert(index, item); 607 } 608 609 public void RemoveAt(int index) 610 { 611 lock (List) 612 List.RemoveAt(index); 613 } 614 615 public LogEntry this[int index] 616 { 617 get 618 { 619 lock (List) 620 return List[index]; 621 } 622 set 623 { 624 lock (List) 625 List[index] = value; 626 } 627 } 628 629 #endregion 630 631 #region ICollection<LogEntry> Members 632 633 public void Add(LogEntry item) 634 { 635 lock (List) 636 List.Add(item); 637 } 638 639 public void Clear() 640 { 641 lock (List) 642 List.Clear(); 643 } 644 645 public bool Contains(LogEntry item) 646 { 647 lock (List) 648 return List.Contains(item); 649 } 650 651 public void CopyTo(LogEntry[] array, int arrayIndex) 652 { 653 lock (List) 654 List.CopyTo(array, arrayIndex); 655 } 656 657 public int Count 658 { 659 get 660 { 661 lock(List) 662 return Count; 663 } 664 } 665 666 public bool IsReadOnly 667 { 668 get { return true; } 669 } 670 671 public bool Remove(LogEntry item) 672 { 673 lock (List) 674 return List.Remove(item); 675 } 676 677 #endregion 678 679 #region IEnumerable<LogEntry> Members 680 681 public IEnumerator<LogEntry> GetEnumerator() 682 { 683 return List.GetEnumerator(); 684 } 685 686 #endregion 687 688 #region IEnumerable Members 689 690 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 691 { 692 return List.GetEnumerator(); 693 } 694 695 #endregion 696 697 /// <summary> 698 /// Gets the highest log level in the current log sink. 699 /// </summary> 700 public LogLevel Highest 701 { 702 get 703 { 704 lock (List) 705 return List.Max(delegate(LogEntry e) { return e.Level; }); 706 } 707 } 708 709 /// <summary> 710 /// Gets the time the first message was logged. 711 /// </summary> 712 public DateTime StartTime 713 { 714 get 715 { 716 lock (List) 717 return List.First().Timestamp; 718 } 719 } 720 721 /// <summary> 722 /// Gets the time the last message was logged. 723 /// </summary> 724 public DateTime EndTime 725 { 726 get 727 { 728 lock (List) 729 return List.Last().Timestamp; 730 } 731 } 732 733 /// <summary> 734 /// The backing store of this session. 735 /// </summary> 736 private List<LogEntry> List = new List<LogEntry>(); 737 } 532 738 } -
branches/eraser6/CodeReview/Eraser.Util/Theming.cs
r1686 r1777 188 188 /// </summary> 189 189 private static Dictionary<ToolStrip, UXThemeMenuRenderer> ThemedMenus = 190 new Dictionary<ToolStrip, UXThemeMenuRenderer>();190 new Dictionary<ToolStrip, UXThemeMenuRenderer>(); 191 191 192 192 /// <summary> -
branches/eraser6/CodeReview/Eraser/LogForm.cs
r1768 r1777 23 23 using System.Collections.Generic; 24 24 using System.ComponentModel; 25 using System. Data;25 using System.Linq; 26 26 using System.Drawing; 27 27 using System.Text; … … 35 35 namespace Eraser 36 36 { 37 public partial class LogForm : Form 37 public partial class LogForm : Form, ILogTarget 38 38 { 39 39 public LogForm(Task task) … … 46 46 47 47 //Populate the list of sessions 48 foreach ( DateTime session in task.Log.Entries.Keys)49 filterSessionCombobox.Items.Add(s ession);50 if ( task.Log.Entries.Keys.Count != 0)48 foreach (LogSink sink in task.Log) 49 filterSessionCombobox.Items.Add(sink.StartTime); 50 if (filterSessionCombobox.Items.Count != 0) 51 51 filterSessionCombobox.SelectedIndex = filterSessionCombobox.Items.Count - 1; 52 52 … … 61 61 62 62 //Register our event handler to get live log messages 63 Task.Log.Logged += task_Logged; 64 Task.Log.NewSession += task_NewSession; 63 if (Task.Log.Count > 0) 64 Task.Log.Last().Chain(this); 65 Task.TaskStarted += task_TaskStarted; 65 66 } 66 67 67 68 private void LogForm_FormClosed(object sender, FormClosedEventArgs e) 68 69 { 69 Task.Log.NewSession -= task_NewSession; 70 Task.Log.Logged -= task_Logged; 70 Task.TaskStarted -= task_TaskStarted; 71 if (Task.Log.Count > 0) 72 Task.Log.Last().Unchain(this); 71 73 } 72 74 … … 76 78 } 77 79 78 private void task_ NewSession(object sender, EventArgs e)80 private void task_TaskStarted(object sender, EventArgs e) 79 81 { 80 82 if (IsDisposed || !IsHandleCreated) … … 82 84 if (InvokeRequired) 83 85 { 84 Invoke((EventHandler<EventArgs>)task_NewSession, sender, e); 85 return; 86 } 87 88 filterSessionCombobox.Items.Add(Task.Log.LastSession); 89 } 90 91 private void task_Logged(object sender, LogEventArgs e) 92 { 93 if (IsDisposed || !IsHandleCreated) 94 return; 95 if (InvokeRequired) 96 { 97 Invoke((EventHandler<LogEventArgs>)task_Logged, sender, e); 98 return; 99 } 100 101 //Check whether the current entry meets the criteria for display. Since 102 //this is an event handler for new log messages only, we should only 103 //display this entry when the session in question is the last one. 104 if (filterSessionCombobox.SelectedItem == null || 105 (DateTime)filterSessionCombobox.SelectedItem != Task.Log.LastSession || 106 !MeetsCriteria(e.LogEntry)) 107 { 108 return; 109 } 110 111 //Add it to the cache and increase our virtual list size. 112 EntryCache.Add(e.LogEntry); 113 ++log.VirtualListSize; 114 115 //Enable the clear and copy log buttons only if we have entries to copy. 116 EnableButtons(); 86 Invoke((EventHandler<EventArgs>)task_TaskStarted, sender, e); 87 return; 88 } 89 90 filterSessionCombobox.Items.Add(Task.Log.Last().StartTime); 117 91 } 118 92 … … 265 239 } 266 240 241 #region ILogTarget Members 242 243 public void OnEventLogged(object sender, LogEventArgs e) 244 { 245 if (IsDisposed || !IsHandleCreated) 246 return; 247 if (InvokeRequired) 248 { 249 Invoke((EventHandler<LogEventArgs>)OnEventLogged, sender, e); 250 return; 251 } 252 253 //Check whether the current entry meets the criteria for display. 254 if (filterSessionCombobox.SelectedItem == null || !MeetsCriteria(e.LogEntry)) 255 { 256 return; 257 } 258 259 //Add it to the cache and increase our virtual list size. 260 EntryCache.Add(e.LogEntry); 261 ++log.VirtualListSize; 262 263 //Enable the clear and copy log buttons only if we have entries to copy. 264 EnableButtons(); 265 } 266 267 public void Chain(ILogTarget target) 268 { 269 throw new NotImplementedException(); 270 } 271 272 public void Unchain(ILogTarget target) 273 { 274 throw new NotImplementedException(); 275 } 276 277 #endregion 278 267 279 /// <summary> 268 280 /// Checks whether the given log entry meets the current display criteria. … … 305 317 306 318 Application.UseWaitCursor = true; 307 LogS essionDictionary log = Task.Log.Entries;319 LogSink sink = Task.Log[filterSessionCombobox.SelectedIndex]; 308 320 EntryCache.Clear(); 309 321 SelectedEntries.Clear(); 310 311 //Iterate over every key 312 foreach (DateTime sessionTime in log.Keys) 313 { 314 //Check for the session time 315 if (filterSessionCombobox.SelectedItem == null || 316 sessionTime != (DateTime)filterSessionCombobox.SelectedItem) 317 continue; 318 319 foreach (LogEntry entry in log[sessionTime]) 320 { 321 //Check if the entry meets the criteria for viewing 322 if (MeetsCriteria(entry)) 323 EntryCache.Add(entry); 324 } 325 } 322 EntryCache.AddRange(sink.Where(MeetsCriteria)); 326 323 327 324 //Set the list view size and update all the control states 328 this.log.VirtualListSize = EntryCache.Count;329 this.log.Refresh();325 log.VirtualListSize = EntryCache.Count; 326 log.Refresh(); 330 327 EnableButtons(); 331 328 Application.UseWaitCursor = false; … … 337 334 private void EnableButtons() 338 335 { 339 clear.Enabled = Task.Log. Entries.Count > 0;336 clear.Enabled = Task.Log.Count > 0; 340 337 } 341 338 -
branches/eraser6/CodeReview/Eraser/ProgressForm.cs
r1765 r1777 22 22 using System; 23 23 using System.Collections.Generic; 24 using System. Data;24 using System.Linq; 25 25 using System.Drawing; 26 26 using System.Text; … … 109 109 110 110 //Inform the user on the status of the task. 111 LogLevel highestLevel = LogLevel.Information; 112 LogEntryCollection entries = task.Log.LastSessionEntries; 113 foreach (LogEntry log in entries) 114 if (log.Level > highestLevel) 115 highestLevel = log.Level; 116 111 LogLevel highestLevel = task.Log.Last().Highest; 117 112 switch (highestLevel) 118 113 { -
branches/eraser6/CodeReview/Eraser/SchedulerPanel.cs
r1768 r1777 22 22 using System; 23 23 using System.Collections.Generic; 24 using System. Data;24 using System.Linq; 25 25 using System.Drawing; 26 26 using System.Text; … … 252 252 253 253 //Get the exit status of the task. 254 LogLevel highestLevel = LogLevel.Information; 255 LogEntryCollection logs = task.Log.LastSessionEntries; 256 foreach (LogEntry log in logs) 257 if (log.Level > highestLevel) 258 highestLevel = log.Level; 254 LogLevel highestLevel = task.Log.Last().Highest; 259 255 260 256 //Show a balloon to inform the user 261 257 MainForm parent = (MainForm)FindForm(); 262 263 //TODO: Is this still needed?264 if (parent == null)265 throw new InvalidOperationException();266 258 if (parent.WindowState == FormWindowState.Minimized || !parent.Visible) 267 259 {
Note: See TracChangeset
for help on using the changeset viewer.
