source: trunk/eraser6/Eraser/LogForm.cs @ 1360

Revision 1360, 8.9 KB checked in by lowjoel, 5 years ago (diff)

Eraser's still under development, so update the copyright notice.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 * Copyright 2008-2009 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;
29
30using Eraser.Manager;
31using System.Globalization;
32using Eraser.Util;
33using System.IO;
34
35namespace Eraser
36{
37    public partial class LogForm : Form
38    {
39        public LogForm(Task task)
40        {
41            InitializeComponent();
42            UXThemeApi.UpdateControlTheme(this);
43
44            //Update the title
45            Text = string.Format(CultureInfo.InvariantCulture, "{0} - {1}", Text, task.UIText);
46
47            //Populate the list of sessions
48            foreach (DateTime session in task.Log.Entries.Keys)
49                filterSessionCombobox.Items.Add(session);
50            if (task.Log.Entries.Keys.Count != 0)
51                filterSessionCombobox.SelectedIndex = filterSessionCombobox.Items.Count - 1;
52
53            //Set the filter settings
54            filterFilterTypeCombobox.SelectedIndex = 0;
55            filterSeverityCombobox.SelectedIndex = 0;
56
57            //Display the log entries
58            this.task = task;
59            RefreshMessages();
60            EnableButtons();
61
62            //Register our event handler to get live log messages
63            task.Log.Logged += task_Logged;
64            task.Log.NewSession += task_NewSession;
65        }
66
67        private void LogForm_FormClosed(object sender, FormClosedEventArgs e)
68        {
69            task.Log.Logged -= task_Logged;
70        }
71
72        private void filter_Changed(object sender, EventArgs e)
73        {
74            RefreshMessages();
75        }
76
77        private void task_NewSession(object sender, EventArgs e)
78        {
79            if (InvokeRequired)
80            {
81                Invoke(new EventHandler<EventArgs>(task_NewSession), sender, e);
82                return;
83            }
84
85            filterSessionCombobox.Items.Add(task.Log.LastSession);
86        }
87
88        private void task_Logged(object sender, LogEventArgs e)
89        {
90            if (InvokeRequired)
91            {
92                Invoke(new EventHandler<LogEventArgs>(task_Logged), sender, e);
93                return;
94            }
95
96            //Check whether the current entry meets the criteria for display. Since
97            //this is an event handler for new log messages only, we should only
98            //display this entry when the session in question is the last one.
99            if (filterSessionCombobox.SelectedItem == null ||
100                (DateTime)filterSessionCombobox.SelectedItem != task.Log.LastSession ||
101                !MeetsCriteria(e.LogEntry))
102            {
103                return;
104            }
105
106            //Add it to the cache and increase our virtual list size.
107            entryCache.Add(e.LogEntry);
108            ++log.VirtualListSize;
109
110            //Enable the clear and copy log buttons only if we have entries to copy.
111            EnableButtons();
112        }
113
114        private void log_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
115        {
116            LogEntry entry = entryCache[e.ItemIndex];
117            e.Item = new ListViewItem(entry.Timestamp.ToString("F", CultureInfo.CurrentCulture));
118            e.Item.SubItems.Add(entry.Level.ToString());
119            e.Item.SubItems.Add(entry.Message);
120
121            switch (entry.Level)
122            {
123                case LogLevel.Fatal:
124                    e.Item.ForeColor = Color.Red;
125                    break;
126                case LogLevel.Error:
127                    e.Item.ForeColor = Color.OrangeRed;
128                    break;
129                case LogLevel.Warning:
130                    e.Item.ForeColor = Color.Orange;
131                    break;
132            }
133        }
134
135        private void log_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
136        {
137            if (e.IsSelected)
138            {
139                if (!selectedEntries.ContainsKey(e.ItemIndex))
140                    selectedEntries.Add(e.ItemIndex, null);
141            }
142            else
143            {
144                selectedEntries.Remove(e.ItemIndex);
145            }
146        }
147
148        private void log_VirtualItemsSelectionRangeChanged(object sender, ListViewVirtualItemsSelectionRangeChangedEventArgs e)
149        {
150            for (int i = e.StartIndex; i <= e.EndIndex; ++i)
151            {
152                if (e.IsSelected)
153                {
154                    if (!selectedEntries.ContainsKey(i))
155                        selectedEntries.Add(i, null);
156                }
157                else
158                {
159                    selectedEntries.Remove(i);
160                }
161            }
162        }
163
164        private void logContextMenuStrip_Opening(object sender, CancelEventArgs e)
165        {
166            copySelectedEntriesToolStripMenuItem.Enabled = selectedEntries.Count != 0;
167        }
168
169        private void copySelectedEntriesToolStripMenuItem_Click(object sender, EventArgs e)
170        {
171            //Ensure we've got stuff to copy.
172            if (selectedEntries.Count == 0)
173                return;
174
175            StringBuilder csvText = new StringBuilder();
176            StringBuilder rawText = new StringBuilder();
177            LogSessionDictionary logEntries = task.Log.Entries;
178
179            DateTime sessionTime = (DateTime)filterSessionCombobox.SelectedItem;
180            csvText.AppendLine(S._("Session: {0:F}", sessionTime));
181            rawText.AppendLine(S._("Session: {0:F}", sessionTime));
182
183            int currentEntryIndex = 0;
184            foreach (LogEntry entry in logEntries[sessionTime])
185            {
186                //Only copy entries which meet the display criteria and that they are selected
187                if (!MeetsCriteria(entry))
188                    continue;
189                if (!selectedEntries.ContainsKey(currentEntryIndex++))
190                    continue;
191
192                string timeStamp = entry.Timestamp.ToString("F", CultureInfo.CurrentCulture);
193                string message = entry.Message;
194                csvText.AppendFormat("\"{0}\",\"{1}\",\"{2}\"\n",
195                    timeStamp.Replace("\"", "\"\""), entry.Level.ToString(),
196                    message.Replace("\"", "\"\""));
197                rawText.AppendFormat("{0}   {1} {2}\n", timeStamp, entry.Level.ToString(),
198                    message);
199            }
200
201            if (csvText.Length > 0 || rawText.Length > 0)
202            {
203                //Set the simple text data for data-unaware applications like Word
204                DataObject tableText = new DataObject();
205                tableText.SetText(rawText.ToString());
206
207                //Then a UTF-8 stream CSV for Excel
208                byte[] bytes = Encoding.UTF8.GetBytes(csvText.ToString());
209                MemoryStream tableStream = new MemoryStream(bytes);
210                tableText.SetData(DataFormats.CommaSeparatedValue, tableStream);
211
212                //Set the clipboard
213                Clipboard.SetDataObject(tableText, true);
214            }
215        }
216
217        private void clear_Click(object sender, EventArgs e)
218        {
219            //Clear the backing store
220            task.Log.Clear();
221
222            //Reset the list of sessions
223            filterSessionCombobox.Items.Clear();
224
225            //And reset the list-view control
226            log.VirtualListSize = 0;
227            selectedEntries.Clear();
228            entryCache.Clear();
229
230            //Finally update the UI state.
231            EnableButtons();
232        }
233
234        private void close_Click(object sender, EventArgs e)
235        {
236            Close();
237        }
238
239        /// <summary>
240        /// Checks whether the given log entry meets the current display criteria.
241        /// </summary>
242        /// <param name="entry">The entry to check.</param>
243        /// <returns>True if the entry meets the display criteria.</returns>
244        private bool MeetsCriteria(LogEntry entry)
245        {
246            //Check for the severity
247            switch (filterFilterTypeCombobox.SelectedIndex)
248            {
249                case 0: //and above
250                    if (entry.Level < (LogLevel)filterSeverityCombobox.SelectedIndex)
251                        return false;
252                    break;
253
254                case 1: //equal to
255                    if (entry.Level != (LogLevel)filterSeverityCombobox.SelectedIndex)
256                        return false;
257                    break;
258
259                case 2: //and below
260                    if (entry.Level > (LogLevel)filterSeverityCombobox.SelectedIndex)
261                        return false;
262                    break;
263            }
264
265            return true;
266        }
267
268        /// <summary>
269        /// Updates all messages in the list view to show only those meeting the
270        /// selection criteria.
271        /// </summary>
272        private void RefreshMessages()
273        {
274            //Check if we have a task
275            if (task == null)
276                return;
277
278            Application.UseWaitCursor = true;
279            LogSessionDictionary log = task.Log.Entries;
280            entryCache.Clear();
281            selectedEntries.Clear();
282
283            //Iterate over every key
284            foreach (DateTime sessionTime in log.Keys)
285            {
286                //Check for the session time
287                if (filterSessionCombobox.SelectedItem == null || 
288                    sessionTime != (DateTime)filterSessionCombobox.SelectedItem)
289                    continue;
290
291                foreach (LogEntry entry in log[sessionTime])
292                {
293                    //Check if the entry meets the criteria for viewing
294                    if (MeetsCriteria(entry))
295                        entryCache.Add(entry);
296                }
297            }
298
299            //Set the list view size and update all the control states
300            this.log.VirtualListSize = entryCache.Count;
301            this.log.Refresh();
302            EnableButtons();
303            Application.UseWaitCursor = false;
304        }
305
306        /// <summary>
307        /// Enables/disables buttons based on the current system state.
308        /// </summary>
309        private void EnableButtons()
310        {
311            clear.Enabled = task.Log.Entries.Count > 0;
312        }
313
314        /// <summary>
315        /// The task which this log is displaying entries for
316        /// </summary>
317        private Task task;
318
319        /// <summary>
320        /// Stores all log entries fulfilling the current criteria for rapid access.
321        /// </summary>
322        private List<LogEntry> entryCache = new List<LogEntry>();
323
324        /// <summary>
325        /// Stores all currently selected list view entry indices.
326        /// </summary>
327        private SortedList<int, object> selectedEntries = new SortedList<int, object>();
328    }
329}
Note: See TracBrowser for help on using the repository browser.