GUI/MainForm.cs
author moel.mich
Tue, 25 May 2010 22:33:03 +0000
changeset 128 cea5477b4d72
parent 126 2354fdb91ac4
child 133 9ad699538c89
permissions -rw-r--r--
Added an event handler to save the configuration when the user logs off without closing the application first (http://blogs.msdn.com/b/oldnewthing/archive/2008/04/21/8413175.aspx), because FormClosed is not called in that case.
     1 /*
     2   
     3   Version: MPL 1.1/GPL 2.0/LGPL 2.1
     4 
     5   The contents of this file are subject to the Mozilla Public License Version
     6   1.1 (the "License"); you may not use this file except in compliance with
     7   the License. You may obtain a copy of the License at
     8  
     9   http://www.mozilla.org/MPL/
    10 
    11   Software distributed under the License is distributed on an "AS IS" basis,
    12   WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    13   for the specific language governing rights and limitations under the License.
    14 
    15   The Original Code is the Open Hardware Monitor code.
    16 
    17   The Initial Developer of the Original Code is 
    18   Michael Möller <m.moeller@gmx.ch>.
    19   Portions created by the Initial Developer are Copyright (C) 2009-2010
    20   the Initial Developer. All Rights Reserved.
    21 
    22   Contributor(s):
    23 
    24   Alternatively, the contents of this file may be used under the terms of
    25   either the GNU General Public License Version 2 or later (the "GPL"), or
    26   the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    27   in which case the provisions of the GPL or the LGPL are applicable instead
    28   of those above. If you wish to allow use of your version of this file only
    29   under the terms of either the GPL or the LGPL, and not to allow others to
    30   use your version of this file under the terms of the MPL, indicate your
    31   decision by deleting the provisions above and replace them with the notice
    32   and other provisions required by the GPL or the LGPL. If you do not delete
    33   the provisions above, a recipient may use your version of this file under
    34   the terms of any one of the MPL, the GPL or the LGPL.
    35  
    36 */
    37 
    38 using System;
    39 using System.Collections.Generic;
    40 using System.ComponentModel;
    41 using System.Configuration;
    42 using System.Drawing;
    43 using System.IO;
    44 using System.Text;
    45 using System.Windows.Forms;
    46 using Aga.Controls.Tree;
    47 using Aga.Controls.Tree.NodeControls;
    48 using OpenHardwareMonitor.Hardware;
    49 using OpenHardwareMonitor.Utilities;
    50 
    51 namespace OpenHardwareMonitor.GUI {
    52   public partial class MainForm : Form {
    53 
    54     private Computer computer = new Computer();
    55     private Node root;
    56     private TreeModel treeModel;
    57     private IDictionary<ISensor, Color> sensorPlotColors = 
    58       new Dictionary<ISensor, Color>();
    59     private Color[] plotColorPalette;
    60     private SensorSystemTray sensorSystemTray;
    61     private NotifyIcon notifyIcon;
    62     private StartupManager startupManager = new StartupManager();
    63     private UpdateVisitor updateVisitor = new UpdateVisitor();
    64 
    65     public MainForm() {      
    66       InitializeComponent();
    67       this.Font = SystemFonts.MessageBoxFont;
    68       treeView.Font = SystemFonts.MessageBoxFont;
    69       plotPanel.Font = SystemFonts.MessageBoxFont;
    70       
    71       nodeCheckBox.IsVisibleValueNeeded += 
    72         new EventHandler<NodeControlValueEventArgs>(
    73           nodeCheckBox_IsVisibleValueNeeded);
    74       nodeCheckBox.CheckStateChanged += 
    75         new EventHandler<TreePathEventArgs>(UpdatePlotSelection);
    76       nodeTextBoxText.DrawText += 
    77         new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
    78       nodeTextBoxValue.DrawText +=
    79         new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
    80       nodeTextBoxMin.DrawText +=
    81         new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
    82       nodeTextBoxMax.DrawText +=
    83         new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
    84       nodeTextBoxLimit.DrawText += 
    85         new EventHandler<DrawEventArgs>(nodeTextBoxLimit_DrawText);
    86 
    87       if (Utilities.Config.Contains("mainForm.Location.X")) {
    88         int x = Utilities.Config.Get("mainForm.Location.X", Location.X);
    89         x = x < 0 ? 0 : x;
    90         int y = Utilities.Config.Get("mainForm.Location.Y", Location.Y);
    91         y = y < 0 ? 0 : y;
    92         this.Location = new Point(x, y);
    93       } else {
    94         StartPosition = FormStartPosition.CenterScreen;
    95       }
    96 
    97       Width = Utilities.Config.Get("mainForm.Width", Width);
    98       Height = Utilities.Config.Get("mainForm.Height", Height);
    99 
   100       foreach (TreeColumn column in treeView.Columns) 
   101         column.Width = Math.Max(20, Math.Min(400, 
   102           Config.Get("treeView.Columns." + column.Header + ".Width",
   103           column.Width)));
   104 
   105       treeModel = new TreeModel();
   106       root = new Node(System.Environment.MachineName);
   107       root.Image = Utilities.EmbeddedResources.GetImage("computer.png");
   108       
   109       treeModel.Nodes.Add(root);
   110       treeView.Model = treeModel;
   111       
   112       notifyIcon = new NotifyIcon();
   113       notifyIcon.ContextMenuStrip = this.notifyContextMenuStrip;
   114       notifyIcon.Icon = EmbeddedResources.GetIcon("smallicon.ico");
   115       notifyIcon.Text = "Open Hardware Monitor";      
   116       notifyIcon.DoubleClick += new EventHandler(this.hideShowClick);
   117 
   118       sensorSystemTray = new SensorSystemTray(computer);
   119 
   120       computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
   121       computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
   122       computer.Open();
   123 
   124       timer.Enabled = true;
   125 
   126       plotColorPalette = new Color[13];
   127       plotColorPalette[0] = Color.Blue;
   128       plotColorPalette[1] = Color.OrangeRed;
   129       plotColorPalette[2] = Color.Green;
   130       plotColorPalette[3] = Color.LightSeaGreen;
   131       plotColorPalette[4] = Color.Goldenrod;
   132       plotColorPalette[5] = Color.DarkViolet;
   133       plotColorPalette[6] = Color.YellowGreen;
   134       plotColorPalette[7] = Color.SaddleBrown;
   135       plotColorPalette[8] = Color.RoyalBlue;
   136       plotColorPalette[9] = Color.DeepPink;
   137       plotColorPalette[10] = Color.MediumSeaGreen;
   138       plotColorPalette[11] = Color.Olive;
   139       plotColorPalette[12] = Color.Firebrick;
   140 
   141       hiddenMenuItem.Checked = Config.Get(hiddenMenuItem.Name, false);
   142       plotMenuItem.Checked = Config.Get(plotMenuItem.Name, false);
   143 
   144       valueMenuItem.Checked = Config.Get(valueMenuItem.Name, true);
   145       minMenuItem.Checked = Config.Get(minMenuItem.Name, false);
   146       maxMenuItem.Checked = Config.Get(maxMenuItem.Name, true);
   147       limitMenuItem.Checked = Config.Get(limitMenuItem.Name, false);
   148 
   149       startMinMenuItem.Checked = Config.Get(startMinMenuItem.Name, false); 
   150       minTrayMenuItem.Checked = Config.Get(minTrayMenuItem.Name, true);
   151       startupMenuItem.Checked = startupManager.Startup;
   152       hddMenuItem.Checked = Config.Get(hddMenuItem.Name, true);
   153 
   154       celciusToolStripMenuItem.Checked = 
   155         UnitManager.TemperatureUnit == TemperatureUnit.Celcius;
   156       fahrenheitToolStripMenuItem.Checked = !celciusToolStripMenuItem.Checked;
   157 
   158       // Hide the system tray and auto startup menu items on Unix
   159       int p = (int)System.Environment.OSVersion.Platform;
   160       if ((p == 4) || (p == 128)) {
   161         minTrayMenuItem.Visible = false;
   162         startupMenuItem.Visible = false;
   163       }
   164       
   165       if (startMinMenuItem.Checked) {
   166         if (!minTrayMenuItem.Checked) {
   167           WindowState = FormWindowState.Minimized;
   168           Show();
   169         }
   170       } else {
   171         Show();
   172       }
   173 
   174       // Create a handle, otherwise calling Close() does not fire FormClosed     
   175       IntPtr handle = Handle;
   176 
   177       // Make sure the settings are saved when the user logs off
   178       Microsoft.Win32.SystemEvents.SessionEnded +=
   179         delegate(object sender, Microsoft.Win32.SessionEndedEventArgs e) {
   180           SaveConfiguration();
   181         };
   182     }
   183     
   184     private void SubHardwareAdded(IHardware hardware, Node node) {
   185       Node hardwareNode = new HardwareNode(hardware);
   186       node.Nodes.Add(hardwareNode);
   187       foreach (IHardware subHardware in hardware.SubHardware)
   188         SubHardwareAdded(subHardware, hardwareNode);  
   189     }
   190 
   191     private void HardwareAdded(IHardware hardware) {
   192       Node hardwareNode = new HardwareNode(hardware);
   193       root.Nodes.Add(hardwareNode);
   194       foreach (IHardware subHardware in hardware.SubHardware)
   195         SubHardwareAdded(subHardware, hardwareNode);     
   196     }
   197 
   198     private void HardwareRemoved(IHardware hardware) {      
   199       List<Node> nodesToRemove = new List<Node>();
   200       foreach (Node node in root.Nodes) {
   201         HardwareNode hardwareNode = node as HardwareNode;
   202         if (hardwareNode != null && hardwareNode.Hardware == hardware)
   203           nodesToRemove.Add(node);
   204       }
   205       foreach (Node node in nodesToRemove)
   206         root.Nodes.Remove(node);
   207     }
   208 
   209     private void nodeTextBoxLimit_DrawText(object sender, DrawEventArgs e) {
   210       SensorNode sensorNode = e.Node.Tag as SensorNode;
   211       if (sensorNode != null) 
   212         e.Text = sensorNode.ValueToString(sensorNode.Sensor.Limit);
   213     }
   214 
   215     private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {       
   216       Node node = e.Node.Tag as Node;
   217       if (node != null) {
   218         Color color;
   219         if (node.IsVisible) {
   220           SensorNode sensorNode = node as SensorNode;
   221           if (plotMenuItem.Checked && sensorNode != null &&
   222             sensorPlotColors.TryGetValue(sensorNode.Sensor, out color))
   223             e.TextColor = color;
   224         } else {
   225           e.TextColor = Color.DarkGray;
   226         }
   227       }
   228     }
   229 
   230     private void UpdatePlotSelection(object sender, 
   231       TreePathEventArgs e) 
   232     {
   233       List<ISensor> selected = new List<ISensor>();
   234       IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
   235       int colorIndex = 0;
   236       foreach (TreeNodeAdv node in treeView.AllNodes) {
   237         SensorNode sensorNode = node.Tag as SensorNode;
   238         if (sensorNode != null && 
   239           sensorNode.Sensor.SensorType == SensorType.Temperature) {
   240           if (sensorNode.Plot) {
   241             colors.Add(sensorNode.Sensor,
   242               plotColorPalette[colorIndex % plotColorPalette.Length]);
   243             selected.Add(sensorNode.Sensor);
   244           }
   245           colorIndex++;
   246         }
   247       }
   248       sensorPlotColors = colors;
   249       plotPanel.SetSensors(selected, colors);
   250     }
   251 
   252     private void nodeCheckBox_IsVisibleValueNeeded(object sender, 
   253       NodeControlValueEventArgs e) {
   254       SensorNode node = e.Node.Tag as SensorNode;
   255       e.Value = (node != null) && 
   256         (node.Sensor.SensorType == SensorType.Temperature) && 
   257         plotMenuItem.Checked;
   258     }
   259 
   260     private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
   261       Close();      
   262     }
   263 
   264     private void timer_Tick(object sender, EventArgs e) {
   265       computer.Accept(updateVisitor);
   266       treeView.Invalidate();
   267       plotPanel.Invalidate();
   268       sensorSystemTray.Redraw();
   269     }
   270 
   271     private void SaveConfiguration() {
   272       Config.Set(hiddenMenuItem.Name, hiddenMenuItem.Checked);
   273       Config.Set(plotMenuItem.Name, plotMenuItem.Checked);
   274 
   275       Config.Set(valueMenuItem.Name, valueMenuItem.Checked);
   276       Config.Set(minMenuItem.Name, minMenuItem.Checked);
   277       Config.Set(maxMenuItem.Name, maxMenuItem.Checked);
   278       Config.Set(limitMenuItem.Name, limitMenuItem.Checked);
   279 
   280       Config.Set(startMinMenuItem.Name, startMinMenuItem.Checked);
   281       Config.Set(minTrayMenuItem.Name, minTrayMenuItem.Checked);
   282       Config.Set(hddMenuItem.Name, hddMenuItem.Checked);
   283 
   284       if (WindowState != FormWindowState.Minimized) {
   285         Config.Set("mainForm.Location.X", Location.X);
   286         Config.Set("mainForm.Location.Y", Location.Y);
   287         Config.Set("mainForm.Width", Width);
   288         Config.Set("mainForm.Height", Height);
   289       }
   290 
   291       foreach (TreeColumn column in treeView.Columns)
   292         Config.Set("treeView.Columns." + column.Header + ".Width",
   293           column.Width);
   294 
   295       Config.Save();
   296     }
   297 
   298     private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
   299       SaveConfiguration();
   300 
   301       timer.Enabled = false;
   302       sensorSystemTray.Dispose();
   303       notifyIcon.Dispose();
   304       computer.Close();
   305     }
   306 
   307     private void aboutToolStripMenuItem_Click(object sender, EventArgs e) {
   308       new AboutBox().ShowDialog();
   309     }
   310 
   311     private void plotToolStripMenuItem_CheckedChanged(object sender, 
   312       EventArgs e) 
   313     {
   314       splitContainer.Panel2Collapsed = !plotMenuItem.Checked;
   315       treeView.Invalidate();
   316     }
   317 
   318     private void treeView_Click(object sender, EventArgs e) {
   319       
   320       MouseEventArgs m = e as MouseEventArgs;
   321       if (m == null || m.Button != MouseButtons.Right)
   322         return;
   323 
   324       NodeControlInfo info = treeView.GetNodeControlInfoAt(new Point(m.X, m.Y));
   325       if (info.Control != null) {
   326         SensorNode node = info.Node.Tag as SensorNode;
   327         if (node != null && node.Sensor != null) {
   328 
   329           sensorContextMenuStrip.Items.Clear();
   330           if (node.Sensor.Parameters.Length > 0) {
   331             ToolStripMenuItem item = new ToolStripMenuItem("Parameters...");
   332             item.Click += delegate(object obj, EventArgs args) {
   333               ShowParameterForm(node.Sensor);
   334             };
   335             sensorContextMenuStrip.Items.Add(item);
   336           }
   337           if (node.IsVisible) {
   338             ToolStripMenuItem item = new ToolStripMenuItem("Hide");
   339             item.Click += delegate(object obj, EventArgs args) {
   340               node.IsVisible = false;
   341             };
   342             sensorContextMenuStrip.Items.Add(item);
   343           } else {
   344             ToolStripMenuItem item = new ToolStripMenuItem("Unhide");
   345             item.Click += delegate(object obj, EventArgs args) {
   346               node.IsVisible = true;
   347             };
   348             sensorContextMenuStrip.Items.Add(item);
   349           }         
   350           if (sensorSystemTray.Contains(node.Sensor)) {
   351             ToolStripMenuItem item = new ToolStripMenuItem("Remove From Tray");
   352             item.Click += delegate(object obj, EventArgs args) {
   353               sensorSystemTray.Remove(node.Sensor);
   354             };
   355             sensorContextMenuStrip.Items.Add(item);
   356           } else {
   357             ToolStripMenuItem item = new ToolStripMenuItem("Add To Tray");
   358             item.Click += delegate(object obj, EventArgs args) {
   359               sensorSystemTray.Add(node.Sensor, true);
   360             };
   361             sensorContextMenuStrip.Items.Add(item);
   362           }
   363           sensorContextMenuStrip.Show(treeView, m.X, m.Y);
   364         }
   365       }
   366     }
   367 
   368     private void saveReportToolStripMenuItem_Click(object sender, EventArgs e) {
   369       string report = computer.GetReport();
   370       if (saveFileDialog.ShowDialog() == DialogResult.OK) {
   371         using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
   372           w.Write(report);
   373         }
   374       }
   375     }
   376 
   377     private void hddsensorsToolStripMenuItem_CheckedChanged(object sender, 
   378       EventArgs e) 
   379     {
   380       computer.HDDEnabled = hddMenuItem.Checked;
   381       UpdatePlotSelection(null, null);      
   382     }
   383 
   384     private void SysTrayHideShow() {
   385       Visible = !Visible;
   386       if (Visible)
   387         Activate();    
   388     }
   389 
   390     protected override void WndProc(ref Message m) {
   391       const int WM_SYSCOMMAND = 0x112;
   392       const int SC_MINIMIZE = 0xF020;
   393       if (minTrayMenuItem.Checked && 
   394         m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
   395         SysTrayHideShow();
   396       } else {      
   397         base.WndProc(ref m);
   398       }
   399     }
   400 
   401     private void hideShowClick(object sender, EventArgs e) {
   402       SysTrayHideShow();
   403     }
   404 
   405     private void removeToolStripMenuItem_Click(object sender, EventArgs e) {
   406       ToolStripMenuItem item = sender as ToolStripMenuItem;
   407       if (item == null)
   408         return;
   409 
   410       ISensor sensor = item.Owner.Tag as ISensor;
   411       if (sensor == null)
   412         return;
   413 
   414       sensorSystemTray.Remove(sensor);
   415     }
   416 
   417     private void ShowParameterForm(ISensor sensor) {
   418       ParameterForm form = new ParameterForm();
   419       form.Parameters = sensor.Parameters;
   420       form.captionLabel.Text = sensor.Name;
   421       form.ShowDialog();
   422     }
   423 
   424     private void treeView_NodeMouseDoubleClick(object sender, 
   425       TreeNodeAdvMouseEventArgs e) {
   426       SensorNode node = e.Node.Tag as SensorNode;
   427       if (node != null && node.Sensor != null && 
   428         node.Sensor.Parameters.Length > 0) {
   429         ShowParameterForm(node.Sensor);
   430       }
   431     }
   432 
   433     private void runOnWindowsStartupToolStripMenuItem_CheckedChanged(
   434       object sender, EventArgs e) 
   435     {
   436       startupManager.Startup = startupMenuItem.Checked;
   437     }
   438 
   439     private void minTrayMenuItem_CheckedChanged(object sender, EventArgs e) {
   440       notifyIcon.Visible = minTrayMenuItem.Checked;
   441     }
   442 
   443     private void hiddenSensorsMenuItem_CheckedChanged(object sender, 
   444       EventArgs e) {
   445       treeModel.ForceVisible = hiddenMenuItem.Checked;
   446     }
   447 
   448     private void valueMenuItem_CheckedChanged(object sender, EventArgs e) {
   449       treeView.Columns[1].IsVisible = valueMenuItem.Checked;
   450     }
   451 
   452     private void minMenuItem_CheckedChanged(object sender, EventArgs e) {
   453       treeView.Columns[2].IsVisible = minMenuItem.Checked;
   454     }
   455 
   456     private void maxMenuItem_CheckedChanged(object sender, EventArgs e) {
   457       treeView.Columns[3].IsVisible = maxMenuItem.Checked;
   458     }
   459 
   460     private void limitMenuItem_CheckedChanged(object sender, EventArgs e) {
   461       treeView.Columns[4].IsVisible = limitMenuItem.Checked;
   462     }
   463 
   464     private void celciusToolStripMenuItem_Click(object sender, EventArgs e) {
   465       celciusToolStripMenuItem.Checked = true;
   466       fahrenheitToolStripMenuItem.Checked = false;
   467       UnitManager.TemperatureUnit = TemperatureUnit.Celcius;
   468     }
   469 
   470     private void fahrenheitToolStripMenuItem_Click(object sender, EventArgs e) {
   471       celciusToolStripMenuItem.Checked = false;
   472       fahrenheitToolStripMenuItem.Checked = true;
   473       UnitManager.TemperatureUnit = TemperatureUnit.Fahrenheit;
   474     }
   475   }
   476 }