GUI/MainForm.cs
author moel.mich
Tue, 21 Sep 2010 20:32:36 +0000
changeset 195 0ee888c485d5
parent 178 67b9b4d8c5fc
child 198 d5de6fa31bc6
permissions -rw-r--r--
Refactored some of the hardware monitoring code and fixed a few code inspection warnings.
     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 PersistentSettings settings;
    55     private UnitManager unitManager;
    56     private Computer computer;
    57     private Node root;
    58     private TreeModel treeModel;
    59     private IDictionary<ISensor, Color> sensorPlotColors = 
    60       new Dictionary<ISensor, Color>();
    61     private Color[] plotColorPalette;
    62     private SystemTray systemTray;    
    63     private StartupManager startupManager = new StartupManager();
    64     private UpdateVisitor updateVisitor = new UpdateVisitor();
    65     private SensorGadget gadget;
    66 
    67     private UserOption showHiddenSensors;
    68     private UserOption showPlot;
    69     private UserOption showValue;
    70     private UserOption showMin;
    71     private UserOption showMax;
    72     private UserOption startMinimized;
    73     private UserOption minimizeToTray;
    74     private UserOption autoStart;
    75     private UserOption readHddSensors;
    76     private UserOption showGadget;
    77 
    78     public MainForm() {      
    79       InitializeComponent();
    80 
    81       this.settings = new PersistentSettings();      
    82       this.settings.Load(Path.ChangeExtension(
    83         System.Windows.Forms.Application.ExecutablePath, ".config"));
    84 
    85       this.unitManager = new UnitManager(settings);
    86 
    87       // set the DockStyle here, to avoid conflicts with the MainMenu
    88       this.splitContainer.Dock = DockStyle.Fill;
    89       
    90       int p = (int)System.Environment.OSVersion.Platform;
    91       if ((p == 4) || (p == 128)) {
    92         splitContainer.BorderStyle = BorderStyle.None;
    93         splitContainer.Border3DStyle = Border3DStyle.Adjust;
    94         splitContainer.SplitterWidth = 4;
    95         treeView.BorderStyle = BorderStyle.Fixed3D;
    96         plotPanel.BorderStyle = BorderStyle.Fixed3D;
    97       }
    98       
    99       this.Font = SystemFonts.MessageBoxFont;
   100       treeView.Font = SystemFonts.MessageBoxFont;
   101       plotPanel.Font = SystemFonts.MessageBoxFont;
   102       
   103       nodeCheckBox.IsVisibleValueNeeded += nodeCheckBox_IsVisibleValueNeeded;
   104       nodeCheckBox.CheckStateChanged += UpdatePlotSelection;
   105       nodeTextBoxText.DrawText += nodeTextBoxText_DrawText;
   106       nodeTextBoxValue.DrawText += nodeTextBoxText_DrawText;
   107       nodeTextBoxMin.DrawText += nodeTextBoxText_DrawText;
   108       nodeTextBoxMax.DrawText += nodeTextBoxText_DrawText;
   109       nodeTextBoxText.EditorShowing += nodeTextBoxText_EditorShowing;
   110 
   111       if (settings.Contains("mainForm.Location.X")) {
   112         int x = settings.GetValue("mainForm.Location.X", Location.X);
   113         x = x < 0 ? 0 : x;
   114         int y = settings.GetValue("mainForm.Location.Y", Location.Y);
   115         y = y < 0 ? 0 : y;
   116         this.Location = new Point(x, y);
   117       } else {
   118         StartPosition = FormStartPosition.CenterScreen;
   119       }
   120 
   121       ClientSize = new Size(
   122         settings.GetValue("mainForm.Width", 470),
   123         settings.GetValue("mainForm.Height", 640));
   124 
   125       foreach (TreeColumn column in treeView.Columns) 
   126         column.Width = Math.Max(20, Math.Min(400,
   127           settings.GetValue("treeView.Columns." + column.Header + ".Width",
   128           column.Width)));
   129 
   130       treeModel = new TreeModel();
   131       root = new Node(System.Environment.MachineName);
   132       root.Image = Utilities.EmbeddedResources.GetImage("computer.png");
   133       
   134       treeModel.Nodes.Add(root);
   135       treeView.Model = treeModel;
   136 
   137       this.computer = new Computer(settings);
   138 
   139       systemTray = new SystemTray(computer, settings);
   140       systemTray.HideShowCommand += hideShowClick;
   141       systemTray.ExitCommand += exitClick;
   142 
   143       gadget = new SensorGadget(computer, settings, unitManager);
   144 
   145       computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
   146       computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
   147       computer.Open();
   148 
   149       timer.Enabled = true;
   150 
   151       plotColorPalette = new Color[13];
   152       plotColorPalette[0] = Color.Blue;
   153       plotColorPalette[1] = Color.OrangeRed;
   154       plotColorPalette[2] = Color.Green;
   155       plotColorPalette[3] = Color.LightSeaGreen;
   156       plotColorPalette[4] = Color.Goldenrod;
   157       plotColorPalette[5] = Color.DarkViolet;
   158       plotColorPalette[6] = Color.YellowGreen;
   159       plotColorPalette[7] = Color.SaddleBrown;
   160       plotColorPalette[8] = Color.RoyalBlue;
   161       plotColorPalette[9] = Color.DeepPink;
   162       plotColorPalette[10] = Color.MediumSeaGreen;
   163       plotColorPalette[11] = Color.Olive;
   164       plotColorPalette[12] = Color.Firebrick;
   165 
   166       showHiddenSensors = new UserOption("hiddenMenuItem", false, hiddenMenuItem, settings);
   167       showHiddenSensors.Changed += delegate(object sender, EventArgs e) {
   168         treeModel.ForceVisible = showHiddenSensors.Value;
   169       };
   170 
   171       showPlot = new UserOption("plotMenuItem", false, plotMenuItem, settings);
   172       showPlot.Changed += delegate(object sender, EventArgs e) {
   173         splitContainer.Panel2Collapsed = !showPlot.Value;
   174         treeView.Invalidate();
   175       };
   176 
   177       showValue = new UserOption("valueMenuItem", true, valueMenuItem, settings);
   178       showValue.Changed += delegate(object sender, EventArgs e) {
   179         treeView.Columns[1].IsVisible = showValue.Value;
   180       };
   181 
   182       showMin = new UserOption("minMenuItem", false, minMenuItem, settings);
   183       showMin.Changed += delegate(object sender, EventArgs e) {
   184         treeView.Columns[2].IsVisible = showMin.Value;
   185       };
   186 
   187       showMax = new UserOption("maxMenuItem", true, maxMenuItem, settings);
   188       showMax.Changed += delegate(object sender, EventArgs e) {
   189         treeView.Columns[3].IsVisible = showMax.Value;
   190       };
   191 
   192       startMinimized = new UserOption("startMinMenuItem", false, startMinMenuItem, settings);
   193 
   194       minimizeToTray = new UserOption("minTrayMenuItem", true, minTrayMenuItem, settings);
   195       minimizeToTray.Changed += delegate(object sender, EventArgs e) {
   196         systemTray.IsMainIconEnabled = minimizeToTray.Value;
   197       };
   198 
   199       autoStart = new UserOption(null, startupManager.Startup, startupMenuItem, settings);
   200       autoStart.Changed += delegate(object sender, EventArgs e) {
   201         try {
   202           startupManager.Startup = autoStart.Value;
   203         } catch (InvalidOperationException) {
   204           MessageBox.Show("Updating the auto-startup option failed.", "Error", 
   205             MessageBoxButtons.OK, MessageBoxIcon.Error);
   206           autoStart.Value = startupManager.Startup;
   207         }
   208       };
   209 
   210       readHddSensors = new UserOption("hddMenuItem", true, hddMenuItem, settings);
   211       readHddSensors.Changed += delegate(object sender, EventArgs e) {
   212         computer.HDDEnabled = readHddSensors.Value;
   213         UpdatePlotSelection(null, null);
   214       };
   215 
   216       showGadget = new UserOption("gadgetMenuItem", false, gadgetMenuItem, settings);
   217       showGadget.Changed += delegate(object sender, EventArgs e) {
   218         gadget.Visible = showGadget.Value;
   219       };
   220 
   221       celciusMenuItem.Checked = 
   222         unitManager.TemperatureUnit == TemperatureUnit.Celcius;
   223       fahrenheitMenuItem.Checked = !celciusMenuItem.Checked;
   224 
   225       startupMenuItem.Visible = startupManager.IsAvailable;
   226       
   227       if (startMinMenuItem.Checked) {
   228         if (!minTrayMenuItem.Checked) {
   229           WindowState = FormWindowState.Minimized;
   230           Show();
   231         }
   232       } else {
   233         Show();
   234       }
   235 
   236       // Create a handle, otherwise calling Close() does not fire FormClosed     
   237       IntPtr handle = Handle;
   238 
   239       // Make sure the settings are saved when the user logs off
   240       Microsoft.Win32.SystemEvents.SessionEnded +=
   241         delegate(object sender, Microsoft.Win32.SessionEndedEventArgs e) {
   242           SaveConfiguration();
   243         };  
   244     }
   245     
   246     private void SubHardwareAdded(IHardware hardware, Node node) {
   247       Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
   248       node.Nodes.Add(hardwareNode);
   249       foreach (IHardware subHardware in hardware.SubHardware)
   250         SubHardwareAdded(subHardware, hardwareNode);  
   251     }
   252 
   253     private void HardwareAdded(IHardware hardware) {
   254       Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
   255       root.Nodes.Add(hardwareNode);
   256       foreach (IHardware subHardware in hardware.SubHardware)
   257         SubHardwareAdded(subHardware, hardwareNode);     
   258     }
   259 
   260     private void HardwareRemoved(IHardware hardware) {      
   261       List<Node> nodesToRemove = new List<Node>();
   262       foreach (Node node in root.Nodes) {
   263         HardwareNode hardwareNode = node as HardwareNode;
   264         if (hardwareNode != null && hardwareNode.Hardware == hardware)
   265           nodesToRemove.Add(node);
   266       }
   267       foreach (Node node in nodesToRemove)
   268         root.Nodes.Remove(node);
   269     }
   270 
   271     private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {       
   272       Node node = e.Node.Tag as Node;
   273       if (node != null) {
   274         Color color;
   275         if (node.IsVisible) {
   276           SensorNode sensorNode = node as SensorNode;
   277           if (plotMenuItem.Checked && sensorNode != null &&
   278             sensorPlotColors.TryGetValue(sensorNode.Sensor, out color))
   279             e.TextColor = color;
   280         } else {
   281           e.TextColor = Color.DarkGray;
   282         }
   283       }
   284     }
   285 
   286     private void UpdatePlotSelection(object sender, 
   287       TreePathEventArgs e) 
   288     {
   289       List<ISensor> selected = new List<ISensor>();
   290       IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
   291       int colorIndex = 0;
   292       foreach (TreeNodeAdv node in treeView.AllNodes) {
   293         SensorNode sensorNode = node.Tag as SensorNode;
   294         if (sensorNode != null && 
   295           sensorNode.Sensor.SensorType == SensorType.Temperature) {
   296           if (sensorNode.Plot) {
   297             colors.Add(sensorNode.Sensor,
   298               plotColorPalette[colorIndex % plotColorPalette.Length]);
   299             selected.Add(sensorNode.Sensor);
   300           }
   301           colorIndex++;
   302         }
   303       }
   304       sensorPlotColors = colors;
   305       plotPanel.SetSensors(selected, colors);
   306     }
   307 
   308     private void nodeTextBoxText_EditorShowing(object sender, CancelEventArgs e) 
   309     {
   310       e.Cancel = !(treeView.CurrentNode != null &&
   311         treeView.CurrentNode.Tag is SensorNode);
   312     }
   313 
   314     private void nodeCheckBox_IsVisibleValueNeeded(object sender, 
   315       NodeControlValueEventArgs e) {
   316       SensorNode node = e.Node.Tag as SensorNode;
   317       e.Value = (node != null) && 
   318         (node.Sensor.SensorType == SensorType.Temperature) && 
   319         plotMenuItem.Checked;
   320     }
   321 
   322     private void exitClick(object sender, EventArgs e) {
   323       Close();      
   324     }
   325 
   326     private void timer_Tick(object sender, EventArgs e) {
   327       computer.Accept(updateVisitor);
   328       treeView.Invalidate();
   329       plotPanel.Invalidate();
   330       systemTray.Redraw();
   331       gadget.Redraw();
   332     }
   333 
   334     private void SaveConfiguration() {
   335       if (WindowState != FormWindowState.Minimized) {
   336         settings.SetValue("mainForm.Location.X", Location.X);
   337         settings.SetValue("mainForm.Location.Y", Location.Y);
   338         settings.SetValue("mainForm.Width", ClientSize.Width);
   339         settings.SetValue("mainForm.Height", ClientSize.Height);
   340       }
   341 
   342       foreach (TreeColumn column in treeView.Columns)
   343         settings.SetValue("treeView.Columns." + column.Header + ".Width",
   344           column.Width);
   345 
   346       settings.Save(Path.ChangeExtension(
   347         System.Windows.Forms.Application.ExecutablePath, ".config"));
   348     }
   349 
   350     private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
   351       Visible = false;
   352       SaveConfiguration();
   353 
   354       timer.Enabled = false;
   355       systemTray.Dispose();      
   356       computer.Close();
   357     }
   358 
   359     private void aboutMenuItem_Click(object sender, EventArgs e) {
   360       new AboutBox().ShowDialog();
   361     }
   362 
   363     private void treeView_Click(object sender, EventArgs e) {
   364       
   365       MouseEventArgs m = e as MouseEventArgs;
   366       if (m == null || m.Button != MouseButtons.Right)
   367         return;
   368 
   369       NodeControlInfo info = treeView.GetNodeControlInfoAt(new Point(m.X, m.Y));
   370       treeView.SelectedNode = info.Node;
   371       if (info.Node != null) {
   372         SensorNode node = info.Node.Tag as SensorNode;
   373         if (node != null && node.Sensor != null) {
   374           sensorContextMenu.MenuItems.Clear();
   375           if (node.Sensor.Parameters.Length > 0) {
   376             MenuItem item = new MenuItem("Parameters...");
   377             item.Click += delegate(object obj, EventArgs args) {
   378               ShowParameterForm(node.Sensor);
   379             };
   380             sensorContextMenu.MenuItems.Add(item);
   381           }
   382           if (nodeTextBoxText.EditEnabled) {
   383             MenuItem item = new MenuItem("Rename");
   384             item.Click += delegate(object obj, EventArgs args) {
   385               nodeTextBoxText.BeginEdit();
   386             };
   387             sensorContextMenu.MenuItems.Add(item);
   388           }
   389           if (node.IsVisible) {
   390             MenuItem item = new MenuItem("Hide");
   391             item.Click += delegate(object obj, EventArgs args) {
   392               node.IsVisible = false;
   393             };
   394             sensorContextMenu.MenuItems.Add(item);
   395           } else {
   396             MenuItem item = new MenuItem("Unhide");
   397             item.Click += delegate(object obj, EventArgs args) {
   398               node.IsVisible = true;
   399             };
   400             sensorContextMenu.MenuItems.Add(item);
   401           }
   402           sensorContextMenu.MenuItems.Add(new MenuItem("-"));
   403           {
   404             MenuItem item = new MenuItem("Show in Tray");
   405             item.Checked = systemTray.Contains(node.Sensor);
   406             item.Click += delegate(object obj, EventArgs args) {
   407               if (item.Checked)
   408                 systemTray.Remove(node.Sensor);
   409               else
   410                 systemTray.Add(node.Sensor, true);
   411             };
   412             sensorContextMenu.MenuItems.Add(item);
   413           }
   414           {
   415             MenuItem item = new MenuItem("Show in Gadget");
   416             item.Checked = gadget.Contains(node.Sensor);
   417             item.Click += delegate(object obj, EventArgs args) {
   418               if (item.Checked) {
   419                 gadget.Remove(node.Sensor);
   420               } else {
   421                 gadget.Add(node.Sensor);
   422               }
   423             };
   424             sensorContextMenu.MenuItems.Add(item);
   425           }
   426 
   427           sensorContextMenu.Show(treeView, new Point(m.X, m.Y));
   428         }
   429       }
   430     }
   431 
   432     private void saveReportMenuItem_Click(object sender, EventArgs e) {
   433       string report = computer.GetReport();
   434       if (saveFileDialog.ShowDialog() == DialogResult.OK) {
   435         using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
   436           w.Write(report);
   437         }
   438       }
   439     }
   440 
   441     private void SysTrayHideShow() {
   442       Visible = !Visible;
   443       if (Visible)
   444         Activate();    
   445     }
   446 
   447     protected override void WndProc(ref Message m) {
   448       const int WM_SYSCOMMAND = 0x112;
   449       const int SC_MINIMIZE = 0xF020;
   450       if (minimizeToTray.Value && 
   451         m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
   452         SysTrayHideShow();
   453       } else {      
   454         base.WndProc(ref m);
   455       }
   456     }
   457 
   458     private void hideShowClick(object sender, EventArgs e) {
   459       SysTrayHideShow();
   460     }
   461 
   462     private void removeMenuItem_Click(object sender, EventArgs e) {
   463       MenuItem item = sender as MenuItem;
   464       if (item == null)
   465         return;
   466 
   467       ISensor sensor = item.Parent.Tag as ISensor;
   468       if (sensor == null)
   469         return;
   470 
   471       systemTray.Remove(sensor);
   472     }
   473 
   474     private void ShowParameterForm(ISensor sensor) {
   475       ParameterForm form = new ParameterForm();
   476       form.Parameters = sensor.Parameters;
   477       form.captionLabel.Text = sensor.Name;
   478       form.ShowDialog();
   479     }
   480 
   481     private void treeView_NodeMouseDoubleClick(object sender, 
   482       TreeNodeAdvMouseEventArgs e) {
   483       SensorNode node = e.Node.Tag as SensorNode;
   484       if (node != null && node.Sensor != null && 
   485         node.Sensor.Parameters.Length > 0) {
   486         ShowParameterForm(node.Sensor);
   487       }
   488     }
   489 
   490     private void celciusMenuItem_Click(object sender, EventArgs e) {
   491       celciusMenuItem.Checked = true;
   492       fahrenheitMenuItem.Checked = false;
   493       unitManager.TemperatureUnit = TemperatureUnit.Celcius;
   494     }
   495 
   496     private void fahrenheitMenuItem_Click(object sender, EventArgs e) {
   497       celciusMenuItem.Checked = false;
   498       fahrenheitMenuItem.Checked = true;
   499       unitManager.TemperatureUnit = TemperatureUnit.Fahrenheit;
   500     }
   501 
   502     private void sumbitReportMenuItem_Click(object sender, EventArgs e) 
   503     {
   504       ReportForm form = new ReportForm();
   505       form.Report = computer.GetReport();
   506       form.ShowDialog();      
   507     }
   508 
   509     private void resetMinMaxMenuItem_Click(object sender, EventArgs e) {
   510       computer.Accept(new SensorVisitor(delegate(ISensor sensor) {
   511         sensor.ResetMin();
   512         sensor.ResetMax();
   513       }));
   514     }
   515   }
   516 }