GUI/MainForm.cs
author moel.mich
Mon, 06 Sep 2010 19:53:13 +0000
changeset 176 c16fd81b520a
parent 166 fa9dfbfc4145
child 178 67b9b4d8c5fc
permissions -rw-r--r--
Added a desktop gadget implementation.
     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 menuItem = new MenuItem("Show in Tray");
   399           menuItem.Checked = systemTray.Contains(node.Sensor);
   400           menuItem.Click += delegate(object obj, EventArgs args) {
   401             if (menuItem.Checked)
   402               systemTray.Remove(node.Sensor);
   403             else
   404               systemTray.Add(node.Sensor, true);
   405           };
   406           sensorContextMenu.MenuItems.Add(menuItem);
   407 
   408           menuItem = new MenuItem("Show in Gadget");
   409           menuItem.Checked = gadget.Contains(node.Sensor);
   410           menuItem.Click += delegate(object obj, EventArgs args) {
   411             if (menuItem.Checked) {
   412               gadget.Remove(node.Sensor);
   413             } else {
   414               gadget.Add(node.Sensor);
   415             }
   416           };
   417           sensorContextMenu.MenuItems.Add(menuItem);
   418 
   419           sensorContextMenu.Show(treeView, new Point(m.X, m.Y));
   420         }
   421       }
   422     }
   423 
   424     private void saveReportMenuItem_Click(object sender, EventArgs e) {
   425       string report = computer.GetReport();
   426       if (saveFileDialog.ShowDialog() == DialogResult.OK) {
   427         using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
   428           w.Write(report);
   429         }
   430       }
   431     }
   432 
   433     private void SysTrayHideShow() {
   434       Visible = !Visible;
   435       if (Visible)
   436         Activate();    
   437     }
   438 
   439     protected override void WndProc(ref Message m) {
   440       const int WM_SYSCOMMAND = 0x112;
   441       const int SC_MINIMIZE = 0xF020;
   442       if (minimizeToTray.Value && 
   443         m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
   444         SysTrayHideShow();
   445       } else {      
   446         base.WndProc(ref m);
   447       }
   448     }
   449 
   450     private void hideShowClick(object sender, EventArgs e) {
   451       SysTrayHideShow();
   452     }
   453 
   454     private void removeMenuItem_Click(object sender, EventArgs e) {
   455       MenuItem item = sender as MenuItem;
   456       if (item == null)
   457         return;
   458 
   459       ISensor sensor = item.Parent.Tag as ISensor;
   460       if (sensor == null)
   461         return;
   462 
   463       systemTray.Remove(sensor);
   464     }
   465 
   466     private void ShowParameterForm(ISensor sensor) {
   467       ParameterForm form = new ParameterForm();
   468       form.Parameters = sensor.Parameters;
   469       form.captionLabel.Text = sensor.Name;
   470       form.ShowDialog();
   471     }
   472 
   473     private void treeView_NodeMouseDoubleClick(object sender, 
   474       TreeNodeAdvMouseEventArgs e) {
   475       SensorNode node = e.Node.Tag as SensorNode;
   476       if (node != null && node.Sensor != null && 
   477         node.Sensor.Parameters.Length > 0) {
   478         ShowParameterForm(node.Sensor);
   479       }
   480     }
   481 
   482     private void celciusMenuItem_Click(object sender, EventArgs e) {
   483       celciusMenuItem.Checked = true;
   484       fahrenheitMenuItem.Checked = false;
   485       unitManager.TemperatureUnit = TemperatureUnit.Celcius;
   486     }
   487 
   488     private void fahrenheitMenuItem_Click(object sender, EventArgs e) {
   489       celciusMenuItem.Checked = false;
   490       fahrenheitMenuItem.Checked = true;
   491       unitManager.TemperatureUnit = TemperatureUnit.Fahrenheit;
   492     }
   493 
   494     private void sumbitReportMenuItem_Click(object sender, EventArgs e) 
   495     {
   496       ReportForm form = new ReportForm();
   497       form.Report = computer.GetReport();
   498       form.ShowDialog();      
   499     }
   500 
   501     private void resetMinMaxMenuItem_Click(object sender, EventArgs e) {
   502       computer.Accept(new SensorVisitor(delegate(ISensor sensor) {
   503         sensor.ResetMin();
   504         sensor.ResetMax();
   505       }));
   506     }
   507   }
   508 }