source: trunk/eraser/Eraser/SchedulerPanel.cs @ 2118

Revision 2118, 23.3 KB checked in by lowjoel, 5 years ago (diff)

When we use File.Exists, we have to also check using Directory.Exists as File.Exists returns false if the path points to a directory.

  • 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 System.Globalization;
30using System.Runtime.InteropServices;
31using System.Diagnostics;
32using System.IO;
33using System.Runtime.Serialization;
34using System.ComponentModel;
35
36using Eraser.Manager;
37using Eraser.Util;
38using Eraser.DefaultPlugins;
39using Microsoft.Samples;
40using ProgressChangedEventArgs = Eraser.Util.ProgressChangedEventArgs;
41
42namespace Eraser
43{
44    internal partial class SchedulerPanel : Eraser.BasePanel
45    {
46        public SchedulerPanel()
47        {
48            InitializeComponent();
49            Theming.ApplyTheme(schedulerDefaultMenu);
50            if (!IsHandleCreated)
51                CreateHandle();
52
53            //Populate the scheduler list-view with the current task list
54            ExecutorTasksCollection tasks = Program.eraserClient.Tasks;
55            foreach (Task task in tasks)
56                DisplayTask(task);
57
58            //Hook the event machinery to our class. Handle the task Added and Removed
59            //events.
60            Program.eraserClient.TaskAdded += TaskAdded;
61            Program.eraserClient.TaskDeleted += TaskDeleted;
62        }
63
64        private void DisplayTask(Task task)
65        {
66            //Add the item to the list view
67            ListViewItem item = scheduler.Items.Add(task.UIText);
68            item.SubItems.Add(string.Empty);
69            item.SubItems.Add(string.Empty);
70
71            //Set the tag of the item so we know which task on the LV corresponds
72            //to the physical task object.
73            item.Tag = task;
74
75            //Add our event handlers to the task
76            task.TaskStarted += task_TaskStarted;
77            task.ProgressChanged += task_ProgressChanged;
78            task.TaskFinished += task_TaskFinished;
79
80            //Show the fields on the list view
81            UpdateTask(item);
82        }
83
84        private void UpdateTask(ListViewItem item)
85        {
86            //Get the task object
87            Task task = (Task)item.Tag;
88
89            //Set the task name
90            item.Text = task.UIText;
91
92            //Set the next run time of the task
93            if (task.Queued)
94            {
95                item.SubItems[1].Text = S._("Queued for execution");
96                item.SubItems[2].Text = string.Empty;
97            }
98            else if (task.Executing && !schedulerProgress.Visible)
99                task_TaskStarted(null, EventArgs.Empty);
100            else if (task.Schedule is RecurringSchedule)
101                item.SubItems[1].Text = ((task.Schedule as RecurringSchedule).NextRun.
102                    ToString("F", CultureInfo.CurrentCulture));
103            else if (task.Schedule == Schedule.RunNow || task.Schedule == Schedule.RunManually)
104                item.SubItems[1].Text = S._("Not queued");
105            else
106                item.SubItems[1].Text = task.Schedule.UIText;
107
108            //Set the group of the task.
109            CategorizeTask(task, item);
110        }
111
112        private void CategorizeTask(Task task)
113        {
114            CategorizeTask(task, GetTaskItem(task));
115        }
116
117        private void CategorizeTask(Task task, ListViewItem item)
118        {
119            if (task.Schedule == Schedule.RunNow || task.Schedule == Schedule.RunManually)
120                item.Group = scheduler.Groups["manual"];
121            else if (task.Schedule == Schedule.RunOnRestart)
122                item.Group = scheduler.Groups["restart"];
123            else
124                item.Group = scheduler.Groups["recurring"];
125        }
126
127        /// <summary>
128        /// Handles the Task Added event.
129        /// </summary>
130        private void TaskAdded(object sender, TaskEventArgs e)
131        {
132            if (InvokeRequired)
133            {
134                Invoke((EventHandler<TaskEventArgs>)TaskAdded, sender, e);
135                return;
136            }
137
138            //Display a balloon notification if the parent frame has been minimised.
139            MainForm parent = (MainForm)FindForm();
140            if (parent != null && (parent.WindowState == FormWindowState.Minimized || !parent.Visible))
141            {
142                parent.ShowNotificationBalloon(S._("New task added"), S._("{0} " +
143                    "has just been added to the list of tasks.", e.Task.UIText),
144                    ToolTipIcon.Info);
145            }
146
147            DisplayTask(e.Task);
148        }
149
150        private void DeleteSelectedTasks()
151        {
152            if (MessageBox.Show(this, S._("Are you sure you want to delete the selected tasks?"),
153                    S._("Eraser"), MessageBoxButtons.YesNo, MessageBoxIcon.Question,
154                    MessageBoxDefaultButton.Button1, Localisation.IsRightToLeft(this) ?
155                        MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign : 0
156                ) != DialogResult.Yes)
157            {
158                return;
159            }
160
161            foreach (ListViewItem item in scheduler.SelectedItems)
162            {
163                Task task = (Task)item.Tag;
164                if (!task.Executing)
165                    Program.eraserClient.Tasks.Remove(task);
166            }
167        }
168
169        /// <summary>
170        /// Handles the task deleted event.
171        /// </summary>
172        private void TaskDeleted(object sender, TaskEventArgs e)
173        {
174            if (InvokeRequired)
175            {
176                Invoke((EventHandler<TaskEventArgs>)TaskDeleted, sender, e);
177                return;
178            }
179
180            foreach (ListViewItem item in scheduler.Items)
181                if (((Task)item.Tag) == e.Task)
182                {
183                    scheduler.Items.Remove(item);
184                    break;
185                }
186
187            PositionProgressBar();
188        }
189
190        /// <summary>
191        /// Handles the task start event.
192        /// </summary>
193        /// <param name="e">The task event object.</param>
194        void task_TaskStarted(object sender, EventArgs e)
195        {
196            if (InvokeRequired)
197            {
198                Invoke((EventHandler)task_TaskStarted, sender, e);
199                return;
200            }
201
202            //Get the list view item
203            Task task = (Task)sender;
204            ListViewItem item = GetTaskItem(task);
205
206            //Update the status.
207            item.SubItems[1].Text = S._("Running...");
208
209            //Show the progress bar
210            schedulerProgress.Tag = item;
211            schedulerProgress.Visible = true;
212            schedulerProgress.Value = 0;
213            PositionProgressBar();
214        }
215
216        /// <summary>
217        /// Handles the progress event by the task.
218        /// </summary>
219        void task_ProgressChanged(object sender, ProgressChangedEventArgs e)
220        {
221            //Make sure we handle the event in the main thread as this requires
222            //GUI calls.
223            if (InvokeRequired)
224            {
225                Invoke((EventHandler<ProgressChangedEventArgs>)task_ProgressChanged, sender, e);
226                return;
227            }
228
229            //Update the progress bar
230            ErasureTarget target = (ErasureTarget)sender;
231            schedulerProgress.Value = (int)(target.Task.Progress.Progress * 1000.0);
232        }
233
234        /// <summary>
235        /// Handles the task completion event.
236        /// </summary>
237        void task_TaskFinished(object sender, EventArgs e)
238        {
239            if (InvokeRequired)
240            {
241                Invoke((EventHandler)task_TaskFinished, sender, e);
242                return;
243            }
244
245            //Get the list view item
246            Task task = (Task)sender;
247            ListViewItem item = GetTaskItem(task);
248            if (item == null)
249                return;
250
251            //Hide the progress bar
252            if (schedulerProgress.Tag != null && schedulerProgress.Tag == item)
253            {
254                schedulerProgress.Tag = null;
255                schedulerProgress.Visible = false;
256            }
257
258            //Get the exit status of the task.
259            LogLevel highestLevel = task.Log.Last().Highest;
260
261            //Show a balloon to inform the user
262            MainForm parent = (MainForm)FindForm();
263            if (parent.WindowState == FormWindowState.Minimized || !parent.Visible)
264            {
265                string message = null;
266                ToolTipIcon icon = ToolTipIcon.None;
267
268                switch (highestLevel)
269                {
270                    case LogLevel.Warning:
271                        message = S._("The task {0} has completed with warnings.", task.UIText);
272                        icon = ToolTipIcon.Warning;
273                        break;
274                    case LogLevel.Error:
275                        message = S._("The task {0} has completed with errors.", task.UIText);
276                        icon = ToolTipIcon.Error;
277                        break;
278                    case LogLevel.Fatal:
279                        message = S._("The task {0} did not complete.", task.UIText);
280                        icon = ToolTipIcon.Error;
281                        break;
282                    default:
283                        message = S._("The task {0} has completed.", task.UIText);
284                        icon = ToolTipIcon.Info;
285                        break;
286                }
287
288                parent.ShowNotificationBalloon(S._("Task executed"), message,
289                    icon);
290            }
291
292            //If the user requested us to remove completed one-time tasks, do so.
293            if (EraserSettings.Get().ClearCompletedTasks &&
294                (task.Schedule == Schedule.RunNow) && highestLevel < LogLevel.Warning)
295            {
296                Program.eraserClient.Tasks.Remove(task);
297            }
298
299            //Otherwise update the UI
300            else
301            {
302                switch (highestLevel)
303                {
304                    case LogLevel.Warning:
305                        item.SubItems[2].Text = S._("Completed with warnings");
306                        break;
307                    case LogLevel.Error:
308                        item.SubItems[2].Text = S._("Completed with errors");
309                        break;
310                    case LogLevel.Fatal:
311                        item.SubItems[2].Text = S._("Not completed");
312                        break;
313                    default:
314                        item.SubItems[2].Text = S._("Completed");
315                        break;
316                }
317
318                //Recategorize the task. Do not assume the task has maintained the
319                //category since run-on-restart tasks will be changed to immediately
320                //run tasks.
321                CategorizeTask(task, item);
322
323                //Update the status of the task.
324                UpdateTask(item);
325            }
326        }
327
328        /// <summary>
329        /// Occurs when the user presses a key on the list view.
330        /// </summary>
331        /// <param name="sender">The list view which triggered the event.</param>
332        /// <param name="e">Event argument.</param>
333        private void scheduler_KeyDown(object sender, KeyEventArgs e)
334        {
335            if (e.KeyCode == Keys.Delete)
336                DeleteSelectedTasks();
337        }
338
339        /// <summary>
340        /// Occurs when the user double-clicks a scheduler item. This will result
341        /// in the log viewer being called, or the progress dialog to be displayed.
342        /// </summary>
343        /// <param name="sender">The list view which triggered the event.</param>
344        /// <param name="e">Event argument.</param>
345        private void scheduler_ItemActivate(object sender, EventArgs e)
346        {
347            if (scheduler.SelectedItems.Count == 0)
348                return;
349
350            ListViewItem item = scheduler.SelectedItems[0];
351            if (((Task)item.Tag).Executing)
352                using (ProgressForm form = new ProgressForm((Task)item.Tag))
353                    form.ShowDialog();
354            else
355                editTaskToolStripMenuItem_Click(sender, e);
356        }
357
358        /// <summary>
359        /// Occurs when the user drags a file over the scheduler
360        /// </summary>
361        private void scheduler_DragEnter(object sender, DragEventArgs e)
362        {
363            string descriptionMessage = string.Empty;
364            string descriptionInsert = string.Empty;
365            string descriptionItemFormat = S._("{0}, ");
366            const string descriptionPlaceholder = "%1";
367           
368            bool recycleBinIncluded = false;
369            List<string> files = e.Data.GetDataPresent(DataFormats.FileDrop) ?
370                new List<string>((string[])e.Data.GetData(DataFormats.FileDrop, false)) :
371                new List<string>();
372            if (e.Data.GetDataPresent("Shell IDList Array"))
373            {
374                MemoryStream stream = (MemoryStream)e.Data.GetData("Shell IDList Array");
375                byte[] buffer = new byte[stream.Length];
376                stream.Read(buffer, 0, buffer.Length);
377                ShellCIDA cida = new ShellCIDA(buffer);
378
379                if (cida.cidl > 0)
380                {
381                    for (int i = 1; i <= cida.cidl; ++i)
382                    {
383                        if (!string.IsNullOrEmpty(cida.aoffset[i].Path))
384                        {
385                            files.Add(cida.aoffset[i].Path);
386                        }
387                        else if (cida.aoffset[i].Guid != Guid.Empty)
388                        {
389                            if (cida.aoffset[i].Guid == Shell.KnownFolderIDs.RecycleBin)
390                            {
391                                descriptionInsert += string.Format(CultureInfo.InvariantCulture,
392                                    descriptionItemFormat, S._("Recycle Bin"));
393                                recycleBinIncluded = true;
394                            }
395                        }
396                    }
397                }
398            }
399
400            bool isTaskList = !recycleBinIncluded;
401            foreach (string file in files)
402            {
403                if (descriptionInsert.Length < 259 &&
404                    (descriptionInsert.Length < 3 || descriptionInsert.Substring(descriptionInsert.Length - 3) != "..."))
405                {
406                    string append = string.Format(CultureInfo.InvariantCulture,
407                        descriptionItemFormat, Path.GetFileNameWithoutExtension(file));
408                    if (descriptionInsert.Length + append.Length > 259)
409                    {
410                        descriptionInsert += ".....";
411                    }
412                    else
413                    {
414                        descriptionInsert += append;
415                    }
416                }
417
418                if (Path.GetExtension(file) != ".ersx")
419                    isTaskList = false;
420            }
421
422            if (!string.IsNullOrEmpty(descriptionInsert))
423                descriptionInsert = descriptionInsert.Remove(descriptionInsert.Length - 2);
424
425            if (!recycleBinIncluded && files.Count == 0)
426            {
427                e.Effect = DragDropEffects.None;
428                descriptionMessage = "Cannot erase the selected items";
429            }
430            else if (isTaskList)
431            {
432                e.Effect = DragDropEffects.Copy;
433                descriptionMessage = S._("Import tasks from {0}", descriptionPlaceholder);
434            }
435            else
436            {
437                e.Effect = DragDropEffects.Move;
438                descriptionMessage = S._("Erase {0}", descriptionPlaceholder);
439            }
440
441            if (e.Data.GetDataPresent("DragImageBits"))
442                DropTargetHelper.DragEnter(this, e.Data, new Point(e.X, e.Y), e.Effect,
443                    descriptionMessage, descriptionInsert);
444        }
445
446        private void scheduler_DragLeave(object sender, EventArgs e)
447        {
448            DropTargetHelper.DragLeave(this);
449        }
450
451        private void scheduler_DragOver(object sender, DragEventArgs e)
452        {
453            DropTargetHelper.DragOver(new Point(e.X, e.Y), e.Effect);
454        }
455
456        /// <summary>
457        /// Occurs when the user drops a file into the scheduler.
458        /// </summary>
459        private void scheduler_DragDrop(object sender, DragEventArgs e)
460        {
461            DropTargetHelper.Drop(e.Data, new Point(e.X, e.Y), e.Effect);
462            if (e.Effect == DragDropEffects.None)
463                return;
464
465            bool recycleBinIncluded = false;
466            List<string> files = e.Data.GetDataPresent(DataFormats.FileDrop) ?
467                new List<string>((string[])e.Data.GetData(DataFormats.FileDrop, false)) :
468                new List<string>();
469            if (e.Data.GetDataPresent("Shell IDList Array"))
470            {
471                MemoryStream stream = (MemoryStream)e.Data.GetData("Shell IDList Array");
472                byte[] buffer = new byte[stream.Length];
473                stream.Read(buffer, 0, buffer.Length);
474                ShellCIDA cida = new ShellCIDA(buffer);
475
476                if (cida.cidl > 0)
477                {
478                    for (int i = 1; i <= cida.cidl; ++i)
479                    {
480                        if (!string.IsNullOrEmpty(cida.aoffset[i].Path))
481                        {
482                            files.Add(cida.aoffset[i].Path);
483                        }
484                        else if (cida.aoffset[i].Guid != Guid.Empty)
485                        {
486                            if (cida.aoffset[i].Guid == Shell.KnownFolderIDs.RecycleBin)
487                                recycleBinIncluded = true;
488                        }
489                    }
490                }
491            }
492
493            //Schedule the task dialog to be shown (to get to the event loop so that
494            //ComCtl32.dll v6 is used.)
495            BeginInvoke((Action<DragDropEffects, List<string>, bool>)scheduler_DragDropConfirm,
496                e.Effect, files, recycleBinIncluded);
497        }
498
499        /// <summary>
500        /// Called after the files have been dropped into Eraser.
501        /// </summary>
502        /// <param name="effect">The Drag/drop effect of the operation.</param>
503        /// <param name="files">The files which were dropped into the program.</param>
504        /// <param name="recycleBinIncluded">True if the recycle bin was among the
505        /// items dropped.</param>
506        private void scheduler_DragDropConfirm(DragDropEffects effect, List<string> files,
507            bool recycleBinIncluded)
508        {
509            //Determine whether we are importing a task list or dragging files for
510            //erasure.
511            if (effect == DragDropEffects.Copy)
512            {
513                foreach (string file in files)
514                    using (FileStream stream = new FileStream(file, FileMode.Open,
515                        FileAccess.Read, FileShare.Read))
516                    {
517                        try
518                        {
519                            Program.eraserClient.Tasks.LoadFromStream(stream);
520                        }
521                        catch (InvalidDataException ex)
522                        {
523                            MessageBox.Show(S._("Could not import task list from {0}. The " +
524                                "error returned was: {1}", file, ex.Message), S._("Eraser"),
525                                MessageBoxButtons.OK, MessageBoxIcon.Error,
526                                MessageBoxDefaultButton.Button1,
527                                Localisation.IsRightToLeft(this) ?
528                                    MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign : 0);
529                        }
530                    }
531            }
532            else if (effect == DragDropEffects.Move)
533            {
534                //Create a task with the default settings
535                Task task = new Task();
536                if (files != null)
537                    foreach (string file in files)
538                    {
539                        //If the path doesn't exist, skip the file
540                        if (!(File.Exists(file) && Directory.Exists(file)))
541                            continue;
542
543                        FileSystemObjectErasureTarget target;
544                        if ((File.GetAttributes(file) & FileAttributes.Directory) != 0)
545                            target = new FolderErasureTarget();
546                        else
547                            target = new FileErasureTarget();
548                        target.Path = file;
549
550                        task.Targets.Add(target);
551                    }
552
553                //Add the recycle bin if it was specified
554                if (recycleBinIncluded)
555                    task.Targets.Add(new RecycleBinErasureTarget());
556
557                //Add the task, asking the user for his intent.
558                DialogResult action = DialogResult.No;
559                if (TaskDialog.IsAvailableOnThisOS)
560                {
561                    TaskDialog dialog = new TaskDialog();
562                    dialog.WindowTitle = S._("Eraser");
563                    dialog.MainIcon = TaskDialogIcon.Information;
564                    dialog.MainInstruction = S._("You have dropped a set of files and folders into Eraser. What do you want to do with them?");
565                    dialog.AllowDialogCancellation = true;
566                    dialog.Buttons = new TaskDialogButton[] {
567                        new TaskDialogButton((int)DialogResult.Yes, S._("Erase the selected items\nSchedules the selected items for immediate erasure.")),
568                        new TaskDialogButton((int)DialogResult.OK, S._("Create a new Task\nA task will be created containing the selected items.")),
569                        new TaskDialogButton((int)DialogResult.No, S._("Cancel the drag-and-drop operation"))
570                    };
571                    dialog.RightToLeftLayout = Localisation.IsRightToLeft(this);
572                    dialog.UseCommandLinks = true;
573                    action = (DialogResult)dialog.Show(this);
574                }
575                else
576                {
577                    action = MessageBox.Show(S._("Are you sure you wish to erase the selected "
578                        + "items?"), S._("Eraser"), MessageBoxButtons.YesNo,
579                        MessageBoxIcon.Question, MessageBoxDefaultButton.Button2,
580                        Localisation.IsRightToLeft(this) ?
581                            MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign : 0);
582                }
583
584                switch (action)
585                {
586                    case DialogResult.OK:
587                        task.Schedule = Schedule.RunManually;
588                        goto case DialogResult.Yes;
589
590                    case DialogResult.Yes:
591                        Program.eraserClient.Tasks.Add(task);
592                        break;
593                }
594            }
595        }
596
597        /// <summary>
598        /// Occurs when the user right-clicks the list view.
599        /// </summary>
600        /// <param name="sender">The list view which generated this event.</param>
601        /// <param name="e">Event argument.</param>
602        private void schedulerMenu_Opening(object sender, CancelEventArgs e)
603        {
604            //If nothing's selected, show the Scheduler menu which just allows users to
605            //create new tasks (like from the toolbar)
606            if (scheduler.SelectedItems.Count == 0)
607            {
608                schedulerDefaultMenu.Show(schedulerMenu.Left, schedulerMenu.Top);
609                e.Cancel = true;
610                return;
611            }
612
613            bool aTaskNotQueued = false;
614            bool aTaskExecuting = false;
615            foreach (ListViewItem item in scheduler.SelectedItems)
616            {
617                Task task = (Task)item.Tag;
618                aTaskNotQueued = aTaskNotQueued || (!task.Queued && !task.Executing);
619                aTaskExecuting = aTaskExecuting || task.Executing;
620            }
621
622            runNowToolStripMenuItem.Enabled = aTaskNotQueued;
623            cancelTaskToolStripMenuItem.Enabled = aTaskExecuting;
624
625            editTaskToolStripMenuItem.Enabled = scheduler.SelectedItems.Count == 1 &&
626                !((Task)scheduler.SelectedItems[0].Tag).Executing &&
627                !((Task)scheduler.SelectedItems[0].Tag).Queued;
628            deleteTaskToolStripMenuItem.Enabled = !aTaskExecuting;
629        }
630
631        /// <summary>
632        /// Occurs when the user selects the New Task context menu item.
633        /// </summary>
634        /// <param name="sender">The menu which generated this event.</param>
635        /// <param name="e">Event argument.</param>
636        private void newTaskToolStripMenuItem_Click(object sender, EventArgs e)
637        {
638            using (TaskPropertiesForm form = new TaskPropertiesForm())
639            {
640                if (form.ShowDialog() == DialogResult.OK)
641                {
642                    Task task = form.Task;
643                    Program.eraserClient.Tasks.Add(task);
644                }
645            }
646        }
647
648        /// <summary>
649        /// Occurs whent the user selects the Run Now context menu item.
650        /// </summary>
651        /// <param name="sender">The menu which generated this event.</param>
652        /// <param name="e">Event argument.</param>
653        private void runNowToolStripMenuItem_Click(object sender, EventArgs e)
654        {
655            foreach (ListViewItem item in scheduler.SelectedItems)
656            {
657                //Queue the task
658                Task task = (Task)item.Tag;
659                if (!task.Executing && !task.Queued)
660                {
661                    Program.eraserClient.QueueTask(task);
662
663                    //Update the UI
664                    item.SubItems[1].Text = S._("Queued for execution");
665                }
666            }
667        }
668
669        /// <summary>
670        /// Occurs whent the user selects the Cancel Task context menu item.
671        /// </summary>
672        /// <param name="sender">The menu which generated this event.</param>
673        /// <param name="e">Event argument.</param>
674        private void cancelTaskToolStripMenuItem_Click(object sender, EventArgs e)
675        {
676            foreach (ListViewItem item in scheduler.SelectedItems)
677            {
678                //Queue the task
679                Task task = (Task)item.Tag;
680                if (task.Executing || task.Queued)
681                {
682                    task.Cancel();
683
684                    //Update the UI
685                    item.SubItems[1].Text = string.Empty;
686                }
687            }
688        }
689
690        /// <summary>
691        /// Occurs when the user selects the View Task Log context menu item.
692        /// </summary>
693        /// <param name="sender">The menu item which generated this event.</param>
694        /// <param name="e">Event argument.</param>
695        private void viewTaskLogToolStripMenuItem_Click(object sender, EventArgs e)
696        {
697            if (scheduler.SelectedItems.Count != 1)
698                return;
699
700            ListViewItem item = scheduler.SelectedItems[0];
701            using (LogForm form = new LogForm((Task)item.Tag))
702                form.ShowDialog();
703        }
704
705        /// <summary>
706        /// Occurs when the user selects the Edit Task context menu item.
707        /// </summary>
708        /// <param name="sender">The menu item which generated this event.</param>
709        /// <param name="e">Event argument.</param>
710        private void editTaskToolStripMenuItem_Click(object sender, EventArgs e)
711        {
712            if (scheduler.SelectedItems.Count != 1 ||
713                ((Task)scheduler.SelectedItems[0].Tag).Executing ||
714                ((Task)scheduler.SelectedItems[0].Tag).Queued)
715            {
716                return;
717            }
718
719            //Make sure that the task is not being executed, or else. This can
720            //be done in the Client library, but there will be no effect on the
721            //currently running task.
722            ListViewItem item = scheduler.SelectedItems[0];
723            Task task = (Task)item.Tag;
724            if (task.Executing)
725                return;
726
727            //Edit the task.
728            using (TaskPropertiesForm form = new TaskPropertiesForm())
729            {
730                form.Task = task;
731                if (form.ShowDialog() == DialogResult.OK)
732                {
733                    task = form.Task;
734
735                    //Update the list view
736                    UpdateTask(item);
737                }
738            }
739        }
740
741        /// <summary>
742        /// Occurs when the user selects the Delete Task context menu item.
743        /// </summary>
744        /// <param name="sender">The menu item which generated this event.</param>
745        /// <param name="e">Event argument.</param>
746        private void deleteTaskToolStripMenuItem_Click(object sender, EventArgs e)
747        {
748            DeleteSelectedTasks();
749        }
750
751        #region Item management
752        /// <summary>
753        /// Retrieves the ListViewItem for the given task.
754        /// </summary>
755        /// <param name="task">The task object whose list view entry is being sought.</param>
756        /// <returns>A ListViewItem for the given task object.</returns>
757        private ListViewItem GetTaskItem(Task task)
758        {
759            foreach (ListViewItem item in scheduler.Items)
760                if (item.Tag == task)
761                    return item;
762
763            return null;
764        }
765
766        /// <summary>
767        /// Maintains the position of the progress bar.
768        /// </summary>
769        private void PositionProgressBar()
770        {
771            if (schedulerProgress.Tag == null)
772                return;
773
774            Rectangle rect = ((ListViewItem)schedulerProgress.Tag).SubItems[2].Bounds;
775            rect.Offset(2, 2);
776            schedulerProgress.Location = rect.Location;
777            schedulerProgress.Size = rect.Size;
778        }
779
780        private void scheduler_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
781        {
782            e.DrawDefault = true;
783            if (schedulerProgress.Tag != null)
784                PositionProgressBar();
785        }
786
787        private void scheduler_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
788        {
789            e.DrawDefault = true;
790        }
791        #endregion
792    }
793}
Note: See TracBrowser for help on using the repository browser.