GUI/MainForm.cs
author moel.mich
Mon, 13 Sep 2010 22:55:25 +0000
changeset 184 3ad822f418cb
parent 176 c16fd81b520a
child 185 edb59f3745e8
permissions -rw-r--r--
Fixed some hardware sorting issue in the gadget. Hardware with the same type and name would be added to the same section.
     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         startupManager.Startup = autoStart.Value; 
   202       };
   203 
   204       readHddSensors = new UserOption("hddMenuItem", true, hddMenuItem, settings);
   205       readHddSensors.Changed += delegate(object sender, EventArgs e) {
   206         computer.HDDEnabled = readHddSensors.Value;
   207         UpdatePlotSelection(null, null);
   208       };
   209 
   210       showGadget = new UserOption("gadgetMenuItem", false, gadgetMenuItem, settings);
   211       showGadget.Changed += delegate(object sender, EventArgs e) {
   212         gadget.Visible = showGadget.Value;
   213       };
   214 
   215       celciusMenuItem.Checked = 
   216         unitManager.TemperatureUnit == TemperatureUnit.Celcius;
   217       fahrenheitMenuItem.Checked = !celciusMenuItem.Checked;
   218 
   219       startupMenuItem.Visible = startupManager.IsAvailable;
   220       
   221       if (startMinMenuItem.Checked) {
   222         if (!minTrayMenuItem.Checked) {
   223           WindowState = FormWindowState.Minimized;
   224           Show();
   225         }
   226       } else {
   227         Show();
   228       }
   229 
   230       // Create a handle, otherwise calling Close() does not fire FormClosed     
   231       IntPtr handle = Handle;
   232 
   233       // Make sure the settings are saved when the user logs off
   234       Microsoft.Win32.SystemEvents.SessionEnded +=
   235         delegate(object sender, Microsoft.Win32.SessionEndedEventArgs e) {
   236           SaveConfiguration();
   237         };  
   238     }
   239     
   240     private void SubHardwareAdded(IHardware hardware, Node node) {
   241       Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
   242       node.Nodes.Add(hardwareNode);
   243       foreach (IHardware subHardware in hardware.SubHardware)
   244         SubHardwareAdded(subHardware, hardwareNode);  
   245     }
   246 
   247     private void HardwareAdded(IHardware hardware) {
   248       Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
   249       root.Nodes.Add(hardwareNode);
   250       foreach (IHardware subHardware in hardware.SubHardware)
   251         SubHardwareAdded(subHardware, hardwareNode);     
   252     }
   253 
   254     private void HardwareRemoved(IHardware hardware) {      
   255       List<Node> nodesToRemove = new List<Node>();
   256       foreach (Node node in root.Nodes) {
   257         HardwareNode hardwareNode = node as HardwareNode;
   258         if (hardwareNode != null && hardwareNode.Hardware == hardware)
   259           nodesToRemove.Add(node);
   260       }
   261       foreach (Node node in nodesToRemove)
   262         root.Nodes.Remove(node);
   263     }
   264 
   265     private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {       
   266       Node node = e.Node.Tag as Node;
   267       if (node != null) {
   268         Color color;
   269         if (node.IsVisible) {
   270           SensorNode sensorNode = node as SensorNode;
   271           if (plotMenuItem.Checked && sensorNode != null &&
   272             sensorPlotColors.TryGetValue(sensorNode.Sensor, out color))
   273             e.TextColor = color;
   274         } else {
   275           e.TextColor = Color.DarkGray;
   276         }
   277       }
   278     }
   279 
   280     private void UpdatePlotSelection(object sender, 
   281       TreePathEventArgs e) 
   282     {
   283       List<ISensor> selected = new List<ISensor>();
   284       IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
   285       int colorIndex = 0;
   286       foreach (TreeNodeAdv node in treeView.AllNodes) {
   287         SensorNode sensorNode = node.Tag as SensorNode;
   288         if (sensorNode != null && 
   289           sensorNode.Sensor.SensorType == SensorType.Temperature) {
   290           if (sensorNode.Plot) {
   291             colors.Add(sensorNode.Sensor,
   292               plotColorPalette[colorIndex % plotColorPalette.Length]);
   293             selected.Add(sensorNode.Sensor);
   294           }
   295           colorIndex++;
   296         }
   297       }
   298       sensorPlotColors = colors;
   299       plotPanel.SetSensors(selected, colors);
   300     }
   301 
   302     private void nodeTextBoxText_EditorShowing(object sender, CancelEventArgs e) 
   303     {
   304       e.Cancel = !(treeView.CurrentNode != null &&
   305         treeView.CurrentNode.Tag is SensorNode);
   306     }
   307 
   308     private void nodeCheckBox_IsVisibleValueNeeded(object sender, 
   309       NodeControlValueEventArgs e) {
   310       SensorNode node = e.Node.Tag as SensorNode;
   311       e.Value = (node != null) && 
   312         (node.Sensor.SensorType == SensorType.Temperature) && 
   313         plotMenuItem.Checked;
   314     }
   315 
   316     private void exitClick(object sender, EventArgs e) {
   317       Close();      
   318     }
   319 
   320     private void timer_Tick(object sender, EventArgs e) {
   321       computer.Accept(updateVisitor);
   322       treeView.Invalidate();
   323       plotPanel.Invalidate();
   324       systemTray.Redraw();
   325       gadget.Redraw();
   326     }
   327 
   328     private void SaveConfiguration() {
   329       if (WindowState != FormWindowState.Minimized) {
   330         settings.SetValue("mainForm.Location.X", Location.X);
   331         settings.SetValue("mainForm.Location.Y", Location.Y);
   332         settings.SetValue("mainForm.Width", ClientSize.Width);
   333         settings.SetValue("mainForm.Height", ClientSize.Height);
   334       }
   335 
   336       foreach (TreeColumn column in treeView.Columns)
   337         settings.SetValue("treeView.Columns." + column.Header + ".Width",
   338           column.Width);
   339 
   340       settings.Save(Path.ChangeExtension(
   341         System.Windows.Forms.Application.ExecutablePath, ".config"));
   342     }
   343 
   344     private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
   345       Visible = false;
   346       SaveConfiguration();
   347 
   348       timer.Enabled = false;
   349       systemTray.Dispose();      
   350       computer.Close();
   351     }
   352 
   353     private void aboutMenuItem_Click(object sender, EventArgs e) {
   354       new AboutBox().ShowDialog();
   355     }
   356 
   357     private void treeView_Click(object sender, EventArgs e) {
   358       
   359       MouseEventArgs m = e as MouseEventArgs;
   360       if (m == null || m.Button != MouseButtons.Right)
   361         return;
   362 
   363       NodeControlInfo info = treeView.GetNodeControlInfoAt(new Point(m.X, m.Y));
   364       treeView.SelectedNode = info.Node;
   365       if (info.Node != null) {
   366         SensorNode node = info.Node.Tag as SensorNode;
   367         if (node != null && node.Sensor != null) {
   368           sensorContextMenu.MenuItems.Clear();
   369           if (node.Sensor.Parameters.Length > 0) {
   370             MenuItem item = new MenuItem("Parameters...");
   371             item.Click += delegate(object obj, EventArgs args) {
   372               ShowParameterForm(node.Sensor);
   373             };
   374             sensorContextMenu.MenuItems.Add(item);
   375           }
   376           if (nodeTextBoxText.EditEnabled) {
   377             MenuItem item = new MenuItem("Rename");
   378             item.Click += delegate(object obj, EventArgs args) {
   379               nodeTextBoxText.BeginEdit();
   380             };
   381             sensorContextMenu.MenuItems.Add(item);
   382           }
   383           if (node.IsVisible) {
   384             MenuItem item = new MenuItem("Hide");
   385             item.Click += delegate(object obj, EventArgs args) {
   386               node.IsVisible = false;
   387             };
   388             sensorContextMenu.MenuItems.Add(item);
   389           } else {
   390             MenuItem item = new MenuItem("Unhide");
   391             item.Click += delegate(object obj, EventArgs args) {
   392               node.IsVisible = true;
   393             };
   394             sensorContextMenu.MenuItems.Add(item);
   395           }
   396           sensorContextMenu.MenuItems.Add(new MenuItem("-"));
   397           {
   398             MenuItem item = new MenuItem("Show in Tray");
   399             item.Checked = systemTray.Contains(node.Sensor);
   400             item.Click += delegate(object obj, EventArgs args) {
   401               if (item.Checked)
   402                 systemTray.Remove(node.Sensor);
   403               else
   404                 systemTray.Add(node.Sensor, true);
   405             };
   406             sensorContextMenu.MenuItems.Add(item);
   407           }
   408           {
   409             MenuItem item = new MenuItem("Show in Gadget");
   410             item.Checked = gadget.Contains(node.Sensor);
   411             item.Click += delegate(object obj, EventArgs args) {
   412               if (item.Checked) {
   413                 gadget.Remove(node.Sensor);
   414               } else {
   415                 gadget.Add(node.Sensor);
   416               }
   417             };
   418             sensorContextMenu.MenuItems.Add(item);
   419           }
   420 
   421           sensorContextMenu.Show(treeView, new Point(m.X, m.Y));
   422         }
   423       }
   424     }
   425 
   426     private void saveReportMenuItem_Click(object sender, EventArgs e) {
   427       string report = computer.GetReport();
   428       if (saveFileDialog.ShowDialog() == DialogResult.OK) {
   429         using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
   430           w.Write(report);
   431         }
   432       }
   433     }
   434 
   435     private void SysTrayHideShow() {
   436       Visible = !Visible;
   437       if (Visible)
   438         Activate();    
   439     }
   440 
   441     protected override void WndProc(ref Message m) {
   442       const int WM_SYSCOMMAND = 0x112;
   443       const int SC_MINIMIZE = 0xF020;
   444       if (minimizeToTray.Value && 
   445         m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
   446         SysTrayHideShow();
   447       } else {      
   448         base.WndProc(ref m);
   449       }
   450     }
   451 
   452     private void hideShowClick(object sender, EventArgs e) {
   453       SysTrayHideShow();
   454     }
   455 
   456     private void removeMenuItem_Click(object sender, EventArgs e) {
   457       MenuItem item = sender as MenuItem;
   458       if (item == null)
   459         return;
   460 
   461       ISensor sensor = item.Parent.Tag as ISensor;
   462       if (sensor == null)
   463         return;
   464 
   465       systemTray.Remove(sensor);
   466     }
   467 
   468     private void ShowParameterForm(ISensor sensor) {
   469       ParameterForm form = new ParameterForm();
   470       form.Parameters = sensor.Parameters;
   471       form.captionLabel.Text = sensor.Name;
   472       form.ShowDialog();
   473     }
   474 
   475     private void treeView_NodeMouseDoubleClick(object sender, 
   476       TreeNodeAdvMouseEventArgs e) {
   477       SensorNode node = e.Node.Tag as SensorNode;
   478       if (node != null && node.Sensor != null && 
   479         node.Sensor.Parameters.Length > 0) {
   480         ShowParameterForm(node.Sensor);
   481       }
   482     }
   483 
   484     private void celciusMenuItem_Click(object sender, EventArgs e) {
   485       celciusMenuItem.Checked = true;
   486       fahrenheitMenuItem.Checked = false;
   487       unitManager.TemperatureUnit = TemperatureUnit.Celcius;
   488     }
   489 
   490     private void fahrenheitMenuItem_Click(object sender, EventArgs e) {
   491       celciusMenuItem.Checked = false;
   492       fahrenheitMenuItem.Checked = true;
   493       unitManager.TemperatureUnit = TemperatureUnit.Fahrenheit;
   494     }
   495 
   496     private void sumbitReportMenuItem_Click(object sender, EventArgs e) 
   497     {
   498       ReportForm form = new ReportForm();
   499       form.Report = computer.GetReport();
   500       form.ShowDialog();      
   501     }
   502 
   503     private void resetMinMaxMenuItem_Click(object sender, EventArgs e) {
   504       computer.Accept(new SensorVisitor(delegate(ISensor sensor) {
   505         sensor.ResetMin();
   506         sensor.ResetMax();
   507       }));
   508     }
   509   }
   510 }