GUI/MainForm.cs
author moel.mich
Sat, 22 May 2010 15:51:59 +0000
changeset 125 b1278888d9a9
parent 122 3ef997c53b50
child 126 2354fdb91ac4
permissions -rw-r--r--
A few bug fixes to avoid crashes on Linux systems.
     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         startMinMenuItem.Visible = false;
   162         minTrayMenuItem.Visible = false;
   163         startupMenuItem.Visible = false;
   164         separatorMenuItem.Visible = false;
   165       }
   166       
   167       if (startMinMenuItem.Checked) {
   168         if (!minTrayMenuItem.Checked) {
   169           WindowState = FormWindowState.Minimized;
   170           Show();
   171         }
   172       } else {
   173         Show();
   174       }
   175 
   176       // Create a handle, otherwise calling Close() does not fire FormClosed     
   177       IntPtr handle = Handle;
   178     }
   179 
   180     private void SubHardwareAdded(IHardware hardware, Node node) {
   181       Node hardwareNode = new HardwareNode(hardware);
   182       node.Nodes.Add(hardwareNode);
   183       foreach (IHardware subHardware in hardware.SubHardware)
   184         SubHardwareAdded(subHardware, hardwareNode);  
   185     }
   186 
   187     private void HardwareAdded(IHardware hardware) {
   188       Node hardwareNode = new HardwareNode(hardware);
   189       root.Nodes.Add(hardwareNode);
   190       foreach (IHardware subHardware in hardware.SubHardware)
   191         SubHardwareAdded(subHardware, hardwareNode);     
   192     }
   193 
   194     private void HardwareRemoved(IHardware hardware) {      
   195       List<Node> nodesToRemove = new List<Node>();
   196       foreach (Node node in root.Nodes) {
   197         HardwareNode hardwareNode = node as HardwareNode;
   198         if (hardwareNode != null && hardwareNode.Hardware == hardware)
   199           nodesToRemove.Add(node);
   200       }
   201       foreach (Node node in nodesToRemove)
   202         root.Nodes.Remove(node);
   203     }
   204 
   205     private void nodeTextBoxLimit_DrawText(object sender, DrawEventArgs e) {
   206       SensorNode sensorNode = e.Node.Tag as SensorNode;
   207       if (sensorNode != null) 
   208         e.Text = sensorNode.ValueToString(sensorNode.Sensor.Limit);
   209     }
   210 
   211     private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {       
   212       Node node = e.Node.Tag as Node;
   213       if (node != null) {
   214         Color color;
   215         if (node.IsVisible) {
   216           SensorNode sensorNode = node as SensorNode;
   217           if (plotMenuItem.Checked && sensorNode != null &&
   218             sensorPlotColors.TryGetValue(sensorNode.Sensor, out color))
   219             e.TextColor = color;
   220         } else {
   221           e.TextColor = Color.DarkGray;
   222         }
   223       }
   224     }
   225 
   226     private void UpdatePlotSelection(object sender, 
   227       TreePathEventArgs e) 
   228     {
   229       List<ISensor> selected = new List<ISensor>();
   230       IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
   231       int colorIndex = 0;
   232       foreach (TreeNodeAdv node in treeView.AllNodes) {
   233         SensorNode sensorNode = node.Tag as SensorNode;
   234         if (sensorNode != null && 
   235           sensorNode.Sensor.SensorType == SensorType.Temperature) {
   236           if (sensorNode.Plot) {
   237             colors.Add(sensorNode.Sensor,
   238               plotColorPalette[colorIndex % plotColorPalette.Length]);
   239             selected.Add(sensorNode.Sensor);
   240           }
   241           colorIndex++;
   242         }
   243       }
   244       sensorPlotColors = colors;
   245       plotPanel.SetSensors(selected, colors);
   246     }
   247 
   248     private void nodeCheckBox_IsVisibleValueNeeded(object sender, 
   249       NodeControlValueEventArgs e) {
   250       SensorNode node = e.Node.Tag as SensorNode;
   251       e.Value = (node != null) && 
   252         (node.Sensor.SensorType == SensorType.Temperature) && 
   253         plotMenuItem.Checked;
   254     }
   255 
   256     private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
   257       Close();      
   258     }
   259 
   260     private void timer_Tick(object sender, EventArgs e) {
   261       computer.Accept(updateVisitor);
   262       treeView.Invalidate();
   263       plotPanel.Invalidate();
   264       sensorSystemTray.Redraw();
   265     }
   266 
   267     private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
   268       
   269       Config.Set(hiddenMenuItem.Name, hiddenMenuItem.Checked);
   270       Config.Set(plotMenuItem.Name, plotMenuItem.Checked);
   271 
   272       Config.Set(valueMenuItem.Name, valueMenuItem.Checked);
   273       Config.Set(minMenuItem.Name, minMenuItem.Checked);
   274       Config.Set(maxMenuItem.Name, maxMenuItem.Checked);
   275       Config.Set(limitMenuItem.Name, limitMenuItem.Checked);
   276 
   277       Config.Set(startMinMenuItem.Name, startMinMenuItem.Checked);
   278       Config.Set(minTrayMenuItem.Name, minTrayMenuItem.Checked);
   279       Config.Set(hddMenuItem.Name, hddMenuItem.Checked);   
   280 
   281       if (WindowState != FormWindowState.Minimized) {
   282         Config.Set("mainForm.Location.X", Location.X);
   283         Config.Set("mainForm.Location.Y", Location.Y);
   284         Config.Set("mainForm.Width", Width);
   285         Config.Set("mainForm.Height", Height);
   286       }
   287 
   288       foreach (TreeColumn column in treeView.Columns) 
   289         Config.Set("treeView.Columns." + column.Header + ".Width", 
   290           column.Width);
   291 
   292       timer.Enabled = false;
   293 
   294       sensorSystemTray.Dispose();
   295       notifyIcon.Dispose();
   296       computer.Close();
   297     }
   298 
   299     private void aboutToolStripMenuItem_Click(object sender, EventArgs e) {
   300       new AboutBox().ShowDialog();
   301     }
   302 
   303     private void plotToolStripMenuItem_CheckedChanged(object sender, 
   304       EventArgs e) 
   305     {
   306       splitContainer.Panel2Collapsed = !plotMenuItem.Checked;
   307       treeView.Invalidate();
   308     }
   309 
   310     private void treeView_Click(object sender, EventArgs e) {
   311       
   312       MouseEventArgs m = e as MouseEventArgs;
   313       if (m == null || m.Button != MouseButtons.Right)
   314         return;
   315 
   316       NodeControlInfo info = treeView.GetNodeControlInfoAt(new Point(m.X, m.Y));
   317       if (info.Control != null) {
   318         SensorNode node = info.Node.Tag as SensorNode;
   319         if (node != null && node.Sensor != null) {
   320 
   321           sensorContextMenuStrip.Items.Clear();
   322           if (node.Sensor.Parameters.Length > 0) {
   323             ToolStripMenuItem item = new ToolStripMenuItem("Parameters...");
   324             item.Click += delegate(object obj, EventArgs args) {
   325               ShowParameterForm(node.Sensor);
   326             };
   327             sensorContextMenuStrip.Items.Add(item);
   328           }
   329           if (node.IsVisible) {
   330             ToolStripMenuItem item = new ToolStripMenuItem("Hide");
   331             item.Click += delegate(object obj, EventArgs args) {
   332               node.IsVisible = false;
   333             };
   334             sensorContextMenuStrip.Items.Add(item);
   335           } else {
   336             ToolStripMenuItem item = new ToolStripMenuItem("Unhide");
   337             item.Click += delegate(object obj, EventArgs args) {
   338               node.IsVisible = true;
   339             };
   340             sensorContextMenuStrip.Items.Add(item);
   341           }         
   342           if (sensorSystemTray.Contains(node.Sensor)) {
   343             ToolStripMenuItem item = new ToolStripMenuItem("Remove From Tray");
   344             item.Click += delegate(object obj, EventArgs args) {
   345               sensorSystemTray.Remove(node.Sensor);
   346             };
   347             sensorContextMenuStrip.Items.Add(item);
   348           } else {
   349             ToolStripMenuItem item = new ToolStripMenuItem("Add To Tray");
   350             item.Click += delegate(object obj, EventArgs args) {
   351               sensorSystemTray.Add(node.Sensor, true);
   352             };
   353             sensorContextMenuStrip.Items.Add(item);
   354           }
   355           sensorContextMenuStrip.Show(treeView, m.X, m.Y);
   356         }
   357       }
   358     }
   359 
   360     private void saveReportToolStripMenuItem_Click(object sender, EventArgs e) {
   361       string report = computer.GetReport();
   362       if (saveFileDialog.ShowDialog() == DialogResult.OK) {
   363         using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
   364           w.Write(report);
   365         }
   366       }
   367     }
   368 
   369     private void hddsensorsToolStripMenuItem_CheckedChanged(object sender, 
   370       EventArgs e) 
   371     {
   372       computer.HDDEnabled = hddMenuItem.Checked;
   373       UpdatePlotSelection(null, null);      
   374     }
   375 
   376     private void SysTrayHideShow() {
   377       Visible = !Visible;
   378       if (Visible)
   379         Activate();    
   380     }
   381 
   382     protected override void WndProc(ref Message m) {
   383       const int WM_SYSCOMMAND = 0x112;
   384       const int SC_MINIMIZE = 0xF020;
   385       if (minTrayMenuItem.Checked && 
   386         m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
   387         SysTrayHideShow();
   388       } else {      
   389         base.WndProc(ref m);
   390       }
   391     }
   392 
   393     private void hideShowClick(object sender, EventArgs e) {
   394       SysTrayHideShow();
   395     }
   396 
   397     private void removeToolStripMenuItem_Click(object sender, EventArgs e) {
   398       ToolStripMenuItem item = sender as ToolStripMenuItem;
   399       if (item == null)
   400         return;
   401 
   402       ISensor sensor = item.Owner.Tag as ISensor;
   403       if (sensor == null)
   404         return;
   405 
   406       sensorSystemTray.Remove(sensor);
   407     }
   408 
   409     private void ShowParameterForm(ISensor sensor) {
   410       ParameterForm form = new ParameterForm();
   411       form.Parameters = sensor.Parameters;
   412       form.captionLabel.Text = sensor.Name;
   413       form.ShowDialog();
   414     }
   415 
   416     private void treeView_NodeMouseDoubleClick(object sender, 
   417       TreeNodeAdvMouseEventArgs e) {
   418       SensorNode node = e.Node.Tag as SensorNode;
   419       if (node != null && node.Sensor != null && 
   420         node.Sensor.Parameters.Length > 0) {
   421         ShowParameterForm(node.Sensor);
   422       }
   423     }
   424 
   425     private void runOnWindowsStartupToolStripMenuItem_CheckedChanged(
   426       object sender, EventArgs e) 
   427     {
   428       startupManager.Startup = startupMenuItem.Checked;
   429     }
   430 
   431     private void minTrayMenuItem_CheckedChanged(object sender, EventArgs e) {
   432       notifyIcon.Visible = minTrayMenuItem.Checked;
   433     }
   434 
   435     private void hiddenSensorsMenuItem_CheckedChanged(object sender, 
   436       EventArgs e) {
   437       treeModel.ForceVisible = hiddenMenuItem.Checked;
   438     }
   439 
   440     private void valueMenuItem_CheckedChanged(object sender, EventArgs e) {
   441       treeView.Columns[1].IsVisible = valueMenuItem.Checked;
   442     }
   443 
   444     private void minMenuItem_CheckedChanged(object sender, EventArgs e) {
   445       treeView.Columns[2].IsVisible = minMenuItem.Checked;
   446     }
   447 
   448     private void maxMenuItem_CheckedChanged(object sender, EventArgs e) {
   449       treeView.Columns[3].IsVisible = maxMenuItem.Checked;
   450     }
   451 
   452     private void limitMenuItem_CheckedChanged(object sender, EventArgs e) {
   453       treeView.Columns[4].IsVisible = limitMenuItem.Checked;
   454     }
   455 
   456     private void celciusToolStripMenuItem_Click(object sender, EventArgs e) {
   457       celciusToolStripMenuItem.Checked = true;
   458       fahrenheitToolStripMenuItem.Checked = false;
   459       UnitManager.TemperatureUnit = TemperatureUnit.Celcius;
   460     }
   461 
   462     private void fahrenheitToolStripMenuItem_Click(object sender, EventArgs e) {
   463       celciusToolStripMenuItem.Checked = false;
   464       fahrenheitToolStripMenuItem.Checked = true;
   465       UnitManager.TemperatureUnit = TemperatureUnit.Fahrenheit;
   466     }
   467   }
   468 }