source: trunk/eraser/Eraser/TaskPropertiesForm.cs @ 2324

Revision 2324, 15.3 KB checked in by lowjoel, 3 years ago (diff)

Implemented smart path compaction for the targets in the Task Properties Dialog. All items will have the paths compacted according to Shell rules if they cannot fit in the column nicely.

  • 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.ComponentModel;
25using System.Data;
26using System.Drawing;
27using System.Text;
28using System.Windows.Forms;
29using System.Linq;
30using System.IO;
31
32using System.Globalization;
33using Eraser.Manager;
34using Eraser.Util;
35using Eraser.Util.ExtensionMethods;
36
37namespace Eraser
38{
39    public partial class TaskPropertiesForm : Form
40    {
41        public TaskPropertiesForm()
42        {
43            InitializeComponent();
44            Theming.ApplyTheme(this);
45            scheduleTime.CustomFormat = DateTimeFormatInfo.CurrentInfo.ShortTimePattern;
46
47            //Set a default task type
48            typeManual.Checked = true;
49            scheduleDaily.Checked = true;
50        }
51
52        /// <summary>
53        /// Sets or retrieves the task object to be edited or being edited.
54        /// </summary>
55        public Task Task
56        {
57            get { UpdateTaskFromUI(); return task; }
58            set { task = value; UpdateUIFromTask(); }
59        }
60
61        /// <summary>
62        /// Updates the local task object from the UI elements.
63        /// </summary>
64        private void UpdateTaskFromUI()
65        {
66            //Set the name of the task
67            task.Name = name.Text;
68
69            //And the schedule, if selected.
70            if (typeManual.Checked)
71            {
72                task.Schedule = Schedule.RunManually;
73            }
74            else if (typeImmediate.Checked)
75            {
76                task.Schedule = Schedule.RunNow;
77            }
78            else if (typeRestart.Checked)
79            {
80                task.Schedule = Schedule.RunOnRestart;
81            }
82            else if (typeRecurring.Checked)
83            {
84                RecurringSchedule schedule = new RecurringSchedule();
85                schedule.ExecutionTime = new DateTime(1, 1, 1, scheduleTime.Value.Hour,
86                    scheduleTime.Value.Minute, scheduleTime.Value.Second);
87
88                if (scheduleDaily.Checked)
89                {
90                    if (scheduleDailyByDay.Checked)
91                    {
92                        schedule.ScheduleType = RecurringScheduleUnit.Daily;
93                        schedule.Frequency = (int)scheduleDailyByDayFreq.Value;
94                    }
95                    else
96                    {
97                        schedule.ScheduleType = RecurringScheduleUnit.Weekdays;
98                    }
99                }
100                else if (scheduleWeekly.Checked)
101                {
102                    schedule.ScheduleType = RecurringScheduleUnit.Weekly;
103                    schedule.Frequency = (int)scheduleWeeklyFreq.Value;
104                    DaysOfWeek weeklySchedule = 0;
105                    if (scheduleWeeklyMonday.Checked)
106                        weeklySchedule |= DaysOfWeek.Monday;
107                    if (scheduleWeeklyTuesday.Checked)
108                        weeklySchedule |= DaysOfWeek.Tuesday;
109                    if (scheduleWeeklyWednesday.Checked)
110                        weeklySchedule |= DaysOfWeek.Wednesday;
111                    if (scheduleWeeklyThursday.Checked)
112                        weeklySchedule |= DaysOfWeek.Thursday;
113                    if (scheduleWeeklyFriday.Checked)
114                        weeklySchedule |= DaysOfWeek.Friday;
115                    if (scheduleWeeklySaturday.Checked)
116                        weeklySchedule |= DaysOfWeek.Saturday;
117                    if (scheduleWeeklySunday.Checked)
118                        weeklySchedule |= DaysOfWeek.Sunday;
119                    schedule.WeeklySchedule = weeklySchedule;
120                }
121                else if (scheduleMonthly.Checked)
122                {
123                    schedule.ScheduleType = RecurringScheduleUnit.Monthly;
124                    schedule.Frequency = (int)scheduleMonthlyFreq.Value;
125                    schedule.MonthlySchedule = (int)scheduleMonthlyDayNumber.Value;
126                }
127                else
128                    throw new ArgumentException("No such scheduling method.");
129
130                task.Schedule = schedule;
131            }
132        }
133
134        /// <summary>
135        /// Updates the UI elements to reflect the data in the Task object.
136        /// </summary>
137        private void UpdateUIFromTask()
138        {
139            //Set the name of the task
140            name.Text = task.Name;
141
142            //And the schedule, if selected.
143            if (task.Schedule == Schedule.RunManually)
144            {
145                typeManual.Checked = true;
146            }
147            else if (task.Schedule == Schedule.RunNow)
148            {
149                typeImmediate.Checked = true;
150            }
151            else if (task.Schedule == Schedule.RunOnRestart)
152            {
153                typeRestart.Checked = true;
154            }
155            else
156            {
157                typeRecurring.Checked = true;
158                RecurringSchedule schedule = (RecurringSchedule)task.Schedule;
159                scheduleTime.Value = scheduleTime.MinDate.Add(schedule.ExecutionTime.TimeOfDay);
160
161                switch (schedule.ScheduleType)
162                {
163                    case RecurringScheduleUnit.Daily:
164                        scheduleDaily.Checked = true;
165                        scheduleDailyByDay.Checked = true;
166                        scheduleDailyByDayFreq.Value = schedule.Frequency;
167                        break;
168                    case RecurringScheduleUnit.Weekdays:
169                        scheduleDaily.Checked = true;
170                        scheduleDailyByWeekday.Checked = true;
171                        break;
172                    case RecurringScheduleUnit.Weekly:
173                        scheduleWeeklyFreq.Value = schedule.Frequency;
174                        scheduleWeekly.Checked = true;
175                        scheduleWeeklyMonday.Checked =
176                            (schedule.WeeklySchedule & DaysOfWeek.Monday) != 0;
177                        scheduleWeeklyTuesday.Checked =
178                            (schedule.WeeklySchedule & DaysOfWeek.Tuesday) != 0;
179                        scheduleWeeklyWednesday.Checked =
180                            (schedule.WeeklySchedule & DaysOfWeek.Wednesday) != 0;
181                        scheduleWeeklyThursday.Checked =
182                            (schedule.WeeklySchedule & DaysOfWeek.Thursday) != 0;
183                        scheduleWeeklyFriday.Checked =
184                            (schedule.WeeklySchedule & DaysOfWeek.Friday) != 0;
185                        scheduleWeeklySaturday.Checked =
186                            (schedule.WeeklySchedule & DaysOfWeek.Saturday) != 0;
187                        scheduleWeeklySunday.Checked =
188                            (schedule.WeeklySchedule & DaysOfWeek.Sunday) != 0;
189                        break;
190                    case RecurringScheduleUnit.Monthly:
191                        scheduleMonthly.Checked = true;
192                        scheduleMonthlyFreq.Value = schedule.Frequency;
193                        scheduleMonthlyDayNumber.Value = schedule.MonthlySchedule;
194                        break;
195                    default:
196                        throw new ArgumentException("Unknown schedule type.");
197                }
198            }
199        }
200
201        /// <summary>
202        /// Triggered when the list view needs to display an item.
203        /// </summary>
204        /// <param name="sender">The list view.</param>
205        /// <param name="e">Event argument.</param>
206        private void data_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
207        {
208            ErasureTarget target = task.Targets[e.ItemIndex];
209            FileInfo info = new FileInfo(target.UIText);
210            e.Item = new ListViewItem(info.GetCompactPath(data.Columns[0].Width, data.Font));
211            e.Item.ToolTipText = target.UIText;
212
213            e.Item.SubItems.Add(target.Method == ErasureMethodRegistrar.Default ?
214                S._("(default)") : target.Method.Name);
215        }
216
217        /// <summary>
218        /// Triggered when the user clicks on the Add Data button.
219        /// </summary>
220        /// <param name="sender">The button.</param>
221        /// <param name="e">Event argument.</param>
222        private void dataAdd_Click(object sender, EventArgs e)
223        {
224            using (TaskDataSelectionForm form = new TaskDataSelectionForm())
225            {
226                if (form.ShowDialog() == DialogResult.OK)
227                {
228                    ErasureTarget target = form.Target;
229                    task.Targets.Add(target);
230                    errorProvider.Clear();
231
232                    ++data.VirtualListSize;
233                }
234            }
235        }
236
237        /// <summary>
238        /// Generated when the user double-clicks an item in the list-view.
239        /// </summary>
240        /// <param name="sender">The list-view which generated this event.</param>
241        /// <param name="e">Event argument.</param>
242        private void data_ItemActivate(object sender, EventArgs e)
243        {
244            using (TaskDataSelectionForm form = new TaskDataSelectionForm())
245            {
246                form.Target = task.Targets[data.SelectedIndices[0]];
247
248                if (form.ShowDialog() == DialogResult.OK)
249                {
250                    ErasureTarget target = form.Target;
251                    task.Targets.RemoveAt(data.SelectedIndices[0]);
252                    task.Targets.Insert(data.SelectedIndices[0], target);
253                }
254            }
255        }
256
257        private void data_DragEnter(object sender, DragEventArgs e)
258        {
259            //Get the list of files.
260            bool recycleBin = false;
261            List<string> paths = new List<string>(TaskDragDropHelper.GetFiles(e, out recycleBin));
262
263            for (int i = 0; i < paths.Count; ++i)
264            {
265                //Just use the file name/directory name.
266                paths[i] = Path.GetFileName(paths[i]);
267            }
268
269            //Add the recycle bin if it was dropped.
270            if (recycleBin)
271                paths.Add(S._("Recycle Bin"));
272
273            string description = null;
274            if (paths.Count == 0)
275            {
276                e.Effect = DragDropEffects.None;
277                description = S._("Cannot add the selected items");
278            }
279            else
280            {
281                e.Effect = DragDropEffects.Copy;
282                description = S._("Add {0}");
283            }
284
285            TaskDragDropHelper.OnDragEnter(this, e, description, paths);
286        }
287
288        private void data_DragLeave(object sender, EventArgs e)
289        {
290            DropTargetHelper.DragLeave((Control)sender);
291        }
292
293        private void data_DragOver(object sender, DragEventArgs e)
294        {
295            DropTargetHelper.DragOver(new Point(e.X, e.Y), e.Effect);
296        }
297
298        private void data_DragDrop(object sender, DragEventArgs e)
299        {
300            TaskDragDropHelper.OnDrop(e);
301            if (e.Effect == DragDropEffects.None)
302                return;
303
304            //Determine our action.
305            bool recycleBin = false;
306            List<string> paths = new List<string>(TaskDragDropHelper.GetFiles(e, out recycleBin));
307
308            //Add the targets
309            foreach (ErasureTarget target in TaskDragDropHelper.GetTargets(paths, recycleBin))
310            {
311                task.Targets.Add(target);
312                ++data.VirtualListSize;
313
314                errorProvider.Clear();
315            }
316        }
317
318        /// <summary>
319        /// Generated when the user right-clicks on the data selection list-view.
320        /// </summary>
321        /// <param name="sender">The menu being opened.</param>
322        /// <param name="e">Event argument.</param>
323        private void dataContextMenuStrip_Opening(object sender, CancelEventArgs e)
324        {
325            if (data.SelectedIndices.Count == 0)
326            {
327                e.Cancel = true;
328                return;
329            }
330        }
331
332        /// <summary>
333        /// Generated when the user selects the menu itm to remove the selected
334        /// data from the list of data to erase.
335        /// </summary>
336        /// <param name="sender">The object triggering the event.</param>
337        /// <param name="e">Event argument.</param>
338        private void deleteDataToolStripMenuItem_Click(object sender, EventArgs e)
339        {
340            if (data.SelectedIndices.Count == 0)
341                return;
342
343            //Get the list of selected indices; sort them in decreasing order so that we
344            //can iterate and remove items without changing indices
345            SortedSet<int> indices = new SortedSet<int>();
346            foreach (int index in data.SelectedIndices)
347                indices.Add(index);
348
349            //Remove the items from the list view
350            data.SelectedIndices.Clear();
351            data.VirtualListSize -= indices.Count;
352
353            //Then finally remove the items from the task list
354            foreach (int index in indices.Reverse())
355                task.Targets.RemoveAt(index);
356        }
357
358        /// <summary>
359        /// Generated when the task schedule type changes.
360        /// </summary>
361        /// <param name="sender">The object triggering the event.</param>
362        /// <param name="e">Event argument.</param>
363        private void taskType_CheckedChanged(object sender, EventArgs e)
364        {
365            scheduleTimeLbl.Enabled = scheduleTime.Enabled = schedulePattern.Enabled =
366                scheduleDaily.Enabled = scheduleWeekly.Enabled =
367                scheduleMonthly.Enabled = typeRecurring.Checked;
368            nonRecurringPanel.Visible = !typeRecurring.Checked;
369           
370            scheduleSpan_CheckedChanged(sender, e);
371        }
372
373        /// <summary>
374        /// Generated when any of the schedule spans have been clicked.
375        /// </summary>
376        /// <param name="sender">The radio button triggering the event.</param>
377        /// <param name="e">Event argument.</param>
378        private void scheduleSpan_Clicked(object sender, EventArgs e)
379        {
380            //Check the selected radio button
381            scheduleDaily.Checked = sender == scheduleDaily;
382            scheduleWeekly.Checked = sender == scheduleWeekly;
383            scheduleMonthly.Checked = sender == scheduleMonthly;
384
385            //Then trigger the checked changed event.
386            scheduleSpan_CheckedChanged(sender, e);
387        }
388
389        /// <summary>
390        /// Generated when the scheduling frequency is changed.
391        /// </summary>
392        /// <param name="sender">The object triggering the event.</param>
393        /// <param name="e">Event argument.</param>
394        private void scheduleSpan_CheckedChanged(object sender, EventArgs e)
395        {
396            RadioButton[] group = new RadioButton[] {
397                scheduleDaily, scheduleWeekly, scheduleMonthly
398            };
399            if (group.Contains(sender) && ((RadioButton)sender).Checked)
400            {
401                foreach (RadioButton button in group)
402                    if (button != sender)
403                        button.Checked = false;
404            }
405
406            scheduleDailyByDay.Enabled = scheduleDailyByDayLbl.Enabled =
407                scheduleDailyByWeekday.Enabled = scheduleDaily.Checked &&
408                typeRecurring.Checked;
409            scheduleWeeklyLbl.Enabled = scheduleWeeklyFreq.Enabled =
410                scheduleWeeklyFreqLbl.Enabled = scheduleWeeklyMonday.Enabled =
411                scheduleWeeklyTuesday.Enabled = scheduleWeeklyWednesday.Enabled =
412                scheduleWeeklyThursday.Enabled = scheduleWeeklyFriday.Enabled =
413                scheduleWeeklySaturday.Enabled = scheduleWeeklySunday.Enabled =
414                scheduleWeekly.Checked && typeRecurring.Checked;
415            scheduleMonthlyLbl.Enabled = scheduleMonthlyDayNumber.Enabled =
416                scheduleMonthlyEveryLbl.Enabled = scheduleMonthlyFreq.Enabled =
417                scheduleMonthlyMonthLbl.Enabled = scheduleMonthly.Checked &&
418                typeRecurring.Checked;
419
420            scheduleDailySpan_CheckedChanged(sender, e);
421        }
422
423        /// <summary>
424        /// Generated when any of the daily frequency radio buttons are clicked.
425        /// </summary>
426        /// <param name="sender">The radio button which triggers the event.</param>
427        /// <param name="e">Event argument.</param>
428        private void scheduleDailySpan_Clicked(object sender, EventArgs e)
429        {
430            scheduleDailyByDay.CheckedChanged -= scheduleDailySpan_CheckedChanged;
431            scheduleDailyByWeekday.CheckedChanged -= scheduleDailySpan_CheckedChanged;
432
433            scheduleDailyByDay.Checked = sender == scheduleDailyByDay;
434            scheduleDailyByWeekday.Checked = sender == scheduleDailyByWeekday;
435
436            scheduleDailyByDay.CheckedChanged += scheduleDailySpan_CheckedChanged;
437            scheduleDailyByWeekday.CheckedChanged += scheduleDailySpan_CheckedChanged;
438           
439            scheduleDailySpan_CheckedChanged(sender, e);
440        }
441
442        /// <summary>
443        /// Generated when the daily frequency argument is changed.
444        /// </summary>
445        /// <param name="sender">The object triggering the event.</param>
446        /// <param name="e">Event argument.</param>
447        private void scheduleDailySpan_CheckedChanged(object sender, EventArgs e)
448        {
449            scheduleDailyByDayLbl.Enabled = scheduleDailyByDayFreq.Enabled =
450                scheduleDailyByDay.Checked && scheduleDaily.Checked && typeRecurring.Checked;
451        }
452
453        /// <summary>
454        /// Generated when the dialog is closed.
455        /// </summary>
456        /// <param name="sender">The object triggering the event.</param>
457        /// <param name="e">Event argument.</param>
458        private void ok_Click(object sender, EventArgs e)
459        {
460            if (task.Targets.Count == 0)
461            {
462                errorProvider.SetIconPadding(data, -16);
463                errorProvider.SetIconAlignment(data, ErrorIconAlignment.BottomRight);
464                errorProvider.SetError(data, S._("The task has no data to erase."));
465                container.SelectedIndex = 0;
466                return;
467            }
468            else if (typeRecurring.Checked && scheduleWeekly.Checked)
469            {
470                if (!scheduleWeeklyMonday.Checked && !scheduleWeeklyTuesday.Checked &&
471                    !scheduleWeeklyWednesday.Checked && !scheduleWeeklyThursday.Checked &&
472                    !scheduleWeeklyFriday.Checked && !scheduleWeeklySaturday.Checked &&
473                    !scheduleWeeklySunday.Checked)
474                {
475                    errorProvider.SetIconPadding(scheduleWeeklyDays, -16);
476                    errorProvider.SetError(scheduleWeeklyDays, S._("The task needs to run " +
477                        "on at least one day a week"));
478                    container.SelectedIndex = 1;
479                    return;
480                }
481            }
482
483            errorProvider.Clear();
484
485            //Close the dialog
486            DialogResult = DialogResult.OK;
487            Close();
488        }
489
490        /// <summary>
491        /// The task being edited.
492        /// </summary>
493        private Task task = new Task();
494    }
495}
Note: See TracBrowser for help on using the repository browser.