GUI/MainForm.cs
author moel.mich
Sun, 10 Apr 2011 20:22:20 +0000
changeset 267 c26ff31e7b54
parent 265 961c07a3bd78
child 269 38cd90779aad
permissions -rw-r--r--
Fixed the tree view row height on Linux.
     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): Paul Werelds
    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.Drawing;
    42 using System.IO;
    43 using System.Windows.Forms;
    44 using Aga.Controls.Tree;
    45 using Aga.Controls.Tree.NodeControls;
    46 using OpenHardwareMonitor.Hardware;
    47 using OpenHardwareMonitor.WMI;
    48 
    49 namespace OpenHardwareMonitor.GUI {
    50   public partial class MainForm : Form {
    51 
    52     private PersistentSettings settings;
    53     private UnitManager unitManager;
    54     private Computer 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 SystemTray systemTray;    
    61     private StartupManager startupManager = new StartupManager();
    62     private UpdateVisitor updateVisitor = new UpdateVisitor();
    63     private SensorGadget gadget;
    64 
    65     private UserOption showHiddenSensors;
    66     private UserOption showPlot;
    67     private UserOption showValue;
    68     private UserOption showMin;
    69     private UserOption showMax;
    70     private UserOption startMinimized;
    71     private UserOption minimizeToTray;
    72     private UserOption minimizeOnClose;
    73     private UserOption autoStart;
    74     private UserOption readHddSensors;
    75     private UserOption showGadget;
    76 
    77     private WmiProvider wmiProvider;
    78 
    79     public MainForm() {      
    80       InitializeComponent();
    81 
    82       this.settings = new PersistentSettings();      
    83       this.settings.Load(Path.ChangeExtension(
    84         Application.ExecutablePath, ".config"));
    85 
    86       this.unitManager = new UnitManager(settings);
    87 
    88       // set the DockStyle here, to avoid conflicts with the MainMenu
    89       this.splitContainer.Dock = DockStyle.Fill;
    90             
    91       this.Font = SystemFonts.MessageBoxFont;
    92       treeView.Font = SystemFonts.MessageBoxFont;
    93       plotPanel.Font = SystemFonts.MessageBoxFont;           
    94       
    95       nodeCheckBox.IsVisibleValueNeeded += nodeCheckBox_IsVisibleValueNeeded;
    96       nodeCheckBox.CheckStateChanged += UpdatePlotSelection;
    97       nodeTextBoxText.DrawText += nodeTextBoxText_DrawText;
    98       nodeTextBoxValue.DrawText += nodeTextBoxText_DrawText;
    99       nodeTextBoxMin.DrawText += nodeTextBoxText_DrawText;
   100       nodeTextBoxMax.DrawText += nodeTextBoxText_DrawText;
   101       nodeTextBoxText.EditorShowing += nodeTextBoxText_EditorShowing;
   102 
   103       foreach (TreeColumn column in treeView.Columns) 
   104         column.Width = Math.Max(20, Math.Min(400,
   105           settings.GetValue("treeView.Columns." + column.Header + ".Width",
   106           column.Width)));
   107 
   108       treeModel = new TreeModel();
   109       root = new Node(System.Environment.MachineName);
   110       root.Image = Utilities.EmbeddedResources.GetImage("computer.png");
   111       
   112       treeModel.Nodes.Add(root);
   113       treeView.Model = treeModel;
   114 
   115       this.computer = new Computer(settings);
   116 
   117       systemTray = new SystemTray(computer, settings);
   118       systemTray.HideShowCommand += hideShowClick;
   119       systemTray.ExitCommand += exitClick;
   120 
   121       int p = (int)Environment.OSVersion.Platform;
   122       if ((p == 4) || (p == 128)) { // Unix
   123         treeView.RowHeight = Math.Max(treeView.RowHeight, 17); 
   124         splitContainer.BorderStyle = BorderStyle.None;
   125         splitContainer.Border3DStyle = Border3DStyle.Adjust;
   126         splitContainer.SplitterWidth = 4;
   127         treeView.BorderStyle = BorderStyle.Fixed3D;
   128         plotPanel.BorderStyle = BorderStyle.Fixed3D;
   129         gadgetMenuItem.Visible = false;
   130         minCloseMenuItem.Visible = false;
   131       } else { // Windows
   132         treeView.RowHeight = Math.Max(treeView.Font.Height + 1, 17); 
   133 
   134         gadget = new SensorGadget(computer, settings, unitManager);
   135         gadget.HideShowCommand += hideShowClick;
   136 
   137         wmiProvider = new WmiProvider(computer);
   138       }          
   139 
   140       computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
   141       computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);        
   142 
   143       computer.Open();
   144 
   145       timer.Enabled = true;
   146 
   147       plotColorPalette = new Color[13];
   148       plotColorPalette[0] = Color.Blue;
   149       plotColorPalette[1] = Color.OrangeRed;
   150       plotColorPalette[2] = Color.Green;
   151       plotColorPalette[3] = Color.LightSeaGreen;
   152       plotColorPalette[4] = Color.Goldenrod;
   153       plotColorPalette[5] = Color.DarkViolet;
   154       plotColorPalette[6] = Color.YellowGreen;
   155       plotColorPalette[7] = Color.SaddleBrown;
   156       plotColorPalette[8] = Color.RoyalBlue;
   157       plotColorPalette[9] = Color.DeepPink;
   158       plotColorPalette[10] = Color.MediumSeaGreen;
   159       plotColorPalette[11] = Color.Olive;
   160       plotColorPalette[12] = Color.Firebrick;
   161 
   162       showHiddenSensors = new UserOption("hiddenMenuItem", false,
   163         hiddenMenuItem, settings);
   164       showHiddenSensors.Changed += delegate(object sender, EventArgs e) {
   165         treeModel.ForceVisible = showHiddenSensors.Value;
   166       };
   167 
   168       showPlot = new UserOption("plotMenuItem", false, plotMenuItem, settings);
   169       showPlot.Changed += delegate(object sender, EventArgs e) {
   170         splitContainer.Panel2Collapsed = !showPlot.Value;
   171         treeView.Invalidate();
   172       };
   173 
   174       showValue = new UserOption("valueMenuItem", true, valueMenuItem,
   175         settings);
   176       showValue.Changed += delegate(object sender, EventArgs e) {
   177         treeView.Columns[1].IsVisible = showValue.Value;
   178       };
   179 
   180       showMin = new UserOption("minMenuItem", false, minMenuItem, settings);
   181       showMin.Changed += delegate(object sender, EventArgs e) {
   182         treeView.Columns[2].IsVisible = showMin.Value;
   183       };
   184 
   185       showMax = new UserOption("maxMenuItem", true, maxMenuItem, settings);
   186       showMax.Changed += delegate(object sender, EventArgs e) {
   187         treeView.Columns[3].IsVisible = showMax.Value;
   188       };
   189 
   190       startMinimized = new UserOption("startMinMenuItem", false,
   191         startMinMenuItem, settings);
   192 
   193       minimizeToTray = new UserOption("minTrayMenuItem", true,
   194         minTrayMenuItem, settings);
   195       minimizeToTray.Changed += delegate(object sender, EventArgs e) {
   196         systemTray.IsMainIconEnabled = minimizeToTray.Value;
   197       };
   198 
   199       minimizeOnClose = new UserOption("minCloseMenuItem", false,
   200         minCloseMenuItem, settings);
   201 
   202       autoStart = new UserOption(null, startupManager.Startup,
   203         startupMenuItem, settings);
   204       autoStart.Changed += delegate(object sender, EventArgs e) {
   205         try {
   206           startupManager.Startup = autoStart.Value;
   207         } catch (InvalidOperationException) {
   208           MessageBox.Show("Updating the auto-startup option failed.", "Error", 
   209             MessageBoxButtons.OK, MessageBoxIcon.Error);
   210           autoStart.Value = startupManager.Startup;
   211         }
   212       };
   213 
   214       readHddSensors = new UserOption("hddMenuItem", true, hddMenuItem,
   215         settings);
   216       readHddSensors.Changed += delegate(object sender, EventArgs e) {
   217         computer.HDDEnabled = readHddSensors.Value;
   218         UpdatePlotSelection(null, null);
   219       };
   220 
   221       showGadget = new UserOption("gadgetMenuItem", false, gadgetMenuItem,
   222         settings);
   223       showGadget.Changed += delegate(object sender, EventArgs e) {
   224         if (gadget != null) 
   225           gadget.Visible = showGadget.Value;
   226       };
   227 
   228       celciusMenuItem.Checked = 
   229         unitManager.TemperatureUnit == TemperatureUnit.Celcius;
   230       fahrenheitMenuItem.Checked = !celciusMenuItem.Checked;
   231 
   232       startupMenuItem.Visible = startupManager.IsAvailable;
   233       
   234       if (startMinMenuItem.Checked) {
   235         if (!minTrayMenuItem.Checked) {
   236           WindowState = FormWindowState.Minimized;
   237           Show();
   238         }
   239       } else {
   240         Show();
   241       }
   242 
   243       // Create a handle, otherwise calling Close() does not fire FormClosed     
   244       IntPtr handle = Handle;
   245 
   246       // Make sure the settings are saved when the user logs off
   247       Microsoft.Win32.SystemEvents.SessionEnded += delegate {
   248         SaveConfiguration();
   249       };  
   250     }
   251     
   252     private void SubHardwareAdded(IHardware hardware, Node node) {
   253       Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
   254       node.Nodes.Add(hardwareNode);
   255       foreach (IHardware subHardware in hardware.SubHardware)
   256         SubHardwareAdded(subHardware, hardwareNode);  
   257     }
   258 
   259     private void HardwareAdded(IHardware hardware) {
   260       Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
   261       root.Nodes.Add(hardwareNode);
   262       foreach (IHardware subHardware in hardware.SubHardware)
   263         SubHardwareAdded(subHardware, hardwareNode);     
   264     }
   265 
   266     private void HardwareRemoved(IHardware hardware) {      
   267       List<Node> nodesToRemove = new List<Node>();
   268       foreach (Node node in root.Nodes) {
   269         HardwareNode hardwareNode = node as HardwareNode;
   270         if (hardwareNode != null && hardwareNode.Hardware == hardware)
   271           nodesToRemove.Add(node);
   272       }
   273       foreach (Node node in nodesToRemove)
   274         root.Nodes.Remove(node);
   275     }
   276 
   277     private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {       
   278       Node node = e.Node.Tag as Node;
   279       if (node != null) {
   280         Color color;
   281         if (node.IsVisible) {
   282           SensorNode sensorNode = node as SensorNode;
   283           if (plotMenuItem.Checked && sensorNode != null &&
   284             sensorPlotColors.TryGetValue(sensorNode.Sensor, out color))
   285             e.TextColor = color;
   286         } else {
   287           e.TextColor = Color.DarkGray;
   288         }
   289       }
   290     }
   291 
   292     private void UpdatePlotSelection(object sender, 
   293       TreePathEventArgs e) 
   294     {
   295       List<ISensor> selected = new List<ISensor>();
   296       IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
   297       int colorIndex = 0;
   298       foreach (TreeNodeAdv node in treeView.AllNodes) {
   299         SensorNode sensorNode = node.Tag as SensorNode;
   300         if (sensorNode != null && 
   301           sensorNode.Sensor.SensorType == SensorType.Temperature) {
   302           if (sensorNode.Plot) {
   303             colors.Add(sensorNode.Sensor,
   304               plotColorPalette[colorIndex % plotColorPalette.Length]);
   305             selected.Add(sensorNode.Sensor);
   306           }
   307           colorIndex++;
   308         }
   309       }
   310       sensorPlotColors = colors;
   311       plotPanel.SetSensors(selected, colors);
   312     }
   313 
   314     private void nodeTextBoxText_EditorShowing(object sender,
   315       CancelEventArgs e) 
   316     {
   317       e.Cancel = !(treeView.CurrentNode != null &&
   318         treeView.CurrentNode.Tag is SensorNode);
   319     }
   320 
   321     private void nodeCheckBox_IsVisibleValueNeeded(object sender, 
   322       NodeControlValueEventArgs e) {
   323       SensorNode node = e.Node.Tag as SensorNode;
   324       e.Value = (node != null) && 
   325         (node.Sensor.SensorType == SensorType.Temperature) && 
   326         plotMenuItem.Checked;
   327     }
   328 
   329     private void exitClick(object sender, EventArgs e) {
   330       Close();
   331     }
   332 
   333     private void timer_Tick(object sender, EventArgs e) {
   334       computer.Accept(updateVisitor);
   335       treeView.Invalidate();
   336       plotPanel.Invalidate();
   337       systemTray.Redraw();
   338       if (gadget != null)
   339         gadget.Redraw();
   340 
   341       if (wmiProvider != null)
   342         wmiProvider.Update();
   343     }
   344 
   345     private void SaveConfiguration() {
   346       foreach (TreeColumn column in treeView.Columns)
   347         settings.SetValue("treeView.Columns." + column.Header + ".Width",
   348           column.Width);
   349 
   350       string fileName = Path.ChangeExtension(
   351           System.Windows.Forms.Application.ExecutablePath, ".config");
   352       try {
   353         settings.Save(fileName);
   354       } catch (UnauthorizedAccessException) {
   355         MessageBox.Show("Access to the path '" + fileName + "' is denied. " +
   356           "The current seetings could not be saved.", 
   357           "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
   358       }
   359     }
   360 
   361     private void MainForm_Load(object sender, EventArgs e) {
   362       Rectangle newBounds = new Rectangle {
   363         X = settings.GetValue("mainForm.Location.X", Location.X),
   364         Y = settings.GetValue("mainForm.Location.Y", Location.Y),
   365         Width = settings.GetValue("mainForm.Width", 470),
   366         Height = settings.GetValue("mainForm.Height", 640)
   367       };
   368 
   369       Rectangle fullWorkingArea = new Rectangle(int.MaxValue, int.MaxValue,
   370         int.MinValue, int.MinValue);
   371 
   372       foreach (Screen screen in Screen.AllScreens)
   373         fullWorkingArea = Rectangle.Union(fullWorkingArea, screen.Bounds);
   374 
   375       Rectangle intersection = Rectangle.Intersect(fullWorkingArea, newBounds);
   376       if (intersection.Width < 20 || intersection.Height < 20 ||
   377         !settings.Contains("mainForm.Location.X")
   378       ) {
   379         newBounds.X = (Screen.PrimaryScreen.WorkingArea.Width / 2) -
   380                       (newBounds.Width/2);
   381 
   382         newBounds.Y = (Screen.PrimaryScreen.WorkingArea.Height / 2) -
   383                       (newBounds.Height / 2);
   384       }
   385 
   386       this.Bounds = newBounds;
   387     }
   388     
   389     private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
   390       Visible = false;
   391       SaveConfiguration();
   392 
   393       systemTray.IsMainIconEnabled = false;
   394       timer.Enabled = false;            
   395       computer.Close();
   396       systemTray.Dispose();
   397     }
   398 
   399     private void aboutMenuItem_Click(object sender, EventArgs e) {
   400       new AboutBox().ShowDialog();
   401     }
   402 
   403     private void treeView_Click(object sender, EventArgs e) {
   404       
   405       MouseEventArgs m = e as MouseEventArgs;
   406       if (m == null || m.Button != MouseButtons.Right)
   407         return;
   408 
   409       NodeControlInfo info = treeView.GetNodeControlInfoAt(
   410         new Point(m.X, m.Y)
   411       );
   412       treeView.SelectedNode = info.Node;
   413       if (info.Node != null) {
   414         SensorNode node = info.Node.Tag as SensorNode;
   415         if (node != null && node.Sensor != null) {
   416           sensorContextMenu.MenuItems.Clear();
   417           if (node.Sensor.Parameters.Length > 0) {
   418             MenuItem item = new MenuItem("Parameters...");
   419             item.Click += delegate(object obj, EventArgs args) {
   420               ShowParameterForm(node.Sensor);
   421             };
   422             sensorContextMenu.MenuItems.Add(item);
   423           }
   424           if (nodeTextBoxText.EditEnabled) {
   425             MenuItem item = new MenuItem("Rename");
   426             item.Click += delegate(object obj, EventArgs args) {
   427               nodeTextBoxText.BeginEdit();
   428             };
   429             sensorContextMenu.MenuItems.Add(item);
   430           }
   431           if (node.IsVisible) {
   432             MenuItem item = new MenuItem("Hide");
   433             item.Click += delegate(object obj, EventArgs args) {
   434               node.IsVisible = false;
   435             };
   436             sensorContextMenu.MenuItems.Add(item);
   437           } else {
   438             MenuItem item = new MenuItem("Unhide");
   439             item.Click += delegate(object obj, EventArgs args) {
   440               node.IsVisible = true;
   441             };
   442             sensorContextMenu.MenuItems.Add(item);
   443           }
   444           sensorContextMenu.MenuItems.Add(new MenuItem("-"));
   445           {
   446             MenuItem item = new MenuItem("Show in Tray");
   447             item.Checked = systemTray.Contains(node.Sensor);
   448             item.Click += delegate(object obj, EventArgs args) {
   449               if (item.Checked)
   450                 systemTray.Remove(node.Sensor);
   451               else
   452                 systemTray.Add(node.Sensor, true);
   453             };
   454             sensorContextMenu.MenuItems.Add(item);
   455           }
   456           if (gadget != null) {
   457             MenuItem item = new MenuItem("Show in Gadget");
   458             item.Checked = gadget.Contains(node.Sensor);
   459             item.Click += delegate(object obj, EventArgs args) {
   460               if (item.Checked) {
   461                 gadget.Remove(node.Sensor);
   462               } else {
   463                 gadget.Add(node.Sensor);
   464               }
   465             };
   466             sensorContextMenu.MenuItems.Add(item);
   467           }
   468           if (node.Sensor.Control != null) {
   469             sensorContextMenu.MenuItems.Add(new MenuItem("-"));
   470             IControl control = node.Sensor.Control;
   471             MenuItem controlItem = new MenuItem("Control");
   472             MenuItem defaultItem = new MenuItem("Default");
   473             defaultItem.Checked = control.ControlMode == ControlMode.Default;
   474             controlItem.MenuItems.Add(defaultItem);
   475             defaultItem.Click += delegate(object obj, EventArgs args) {
   476               control.SetDefault();
   477             };
   478             MenuItem manualItem = new MenuItem("Manual");            
   479             controlItem.MenuItems.Add(manualItem);
   480             manualItem.Checked = control.ControlMode == ControlMode.Software;
   481             for (int i = 0; i <= 100; i += 5) {
   482               if (i <= control.MaxSoftwareValue &&
   483                   i >= control.MinSoftwareValue) 
   484               {
   485                 MenuItem item = new MenuItem(i + " %");
   486                 manualItem.MenuItems.Add(item);
   487                 item.Checked = control.ControlMode == ControlMode.Software &&
   488                   Math.Round(control.SoftwareValue) == i;
   489                 int softwareValue = i;
   490                 item.Click += delegate(object obj, EventArgs args) {
   491                   control.SetSoftware(softwareValue);
   492                 };
   493               }
   494             }
   495             sensorContextMenu.MenuItems.Add(controlItem);
   496           }
   497 
   498           sensorContextMenu.Show(treeView, new Point(m.X, m.Y));
   499         }
   500       }
   501     }
   502 
   503     private void saveReportMenuItem_Click(object sender, EventArgs e) {
   504       string report = computer.GetReport();
   505       if (saveFileDialog.ShowDialog() == DialogResult.OK) {
   506         using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
   507           w.Write(report);
   508         }
   509       }
   510     }
   511 
   512     private void SysTrayHideShow() {
   513       Visible = !Visible;
   514       if (Visible)
   515         Activate();    
   516     }
   517 
   518     protected override void WndProc(ref Message m) {
   519       const int WM_SYSCOMMAND = 0x112;
   520       const int SC_MINIMIZE = 0xF020;
   521       const int SC_CLOSE = 0xF060;
   522 
   523       if (minimizeToTray.Value && 
   524         m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
   525         SysTrayHideShow();
   526       } else if(minimizeOnClose.Value && 
   527         m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_CLOSE) {
   528         /*
   529          * Apparently the user wants to minimize rather than close
   530          * Now we still need to check if we're going to the tray or not
   531          * 
   532          * Note: the correct way to do this would be to send out SC_MINIMIZE,
   533          * but since the code here is so simple,
   534          * that would just be a waste of time.
   535          */
   536         if (minimizeToTray.Value)
   537           SysTrayHideShow();
   538         else
   539           WindowState = FormWindowState.Minimized;
   540       } else {      
   541         base.WndProc(ref m);
   542       }
   543     }
   544 
   545     private void hideShowClick(object sender, EventArgs e) {
   546       SysTrayHideShow();
   547     }
   548 
   549     private void ShowParameterForm(ISensor sensor) {
   550       ParameterForm form = new ParameterForm();
   551       form.Parameters = sensor.Parameters;
   552       form.captionLabel.Text = sensor.Name;
   553       form.ShowDialog();
   554     }
   555 
   556     private void treeView_NodeMouseDoubleClick(object sender, 
   557       TreeNodeAdvMouseEventArgs e) {
   558       SensorNode node = e.Node.Tag as SensorNode;
   559       if (node != null && node.Sensor != null && 
   560         node.Sensor.Parameters.Length > 0) {
   561         ShowParameterForm(node.Sensor);
   562       }
   563     }
   564 
   565     private void celciusMenuItem_Click(object sender, EventArgs e) {
   566       celciusMenuItem.Checked = true;
   567       fahrenheitMenuItem.Checked = false;
   568       unitManager.TemperatureUnit = TemperatureUnit.Celcius;
   569     }
   570 
   571     private void fahrenheitMenuItem_Click(object sender, EventArgs e) {
   572       celciusMenuItem.Checked = false;
   573       fahrenheitMenuItem.Checked = true;
   574       unitManager.TemperatureUnit = TemperatureUnit.Fahrenheit;
   575     }
   576 
   577     private void sumbitReportMenuItem_Click(object sender, EventArgs e) 
   578     {
   579       ReportForm form = new ReportForm();
   580       form.Report = computer.GetReport();
   581       form.ShowDialog();      
   582     }
   583 
   584     private void resetMinMaxMenuItem_Click(object sender, EventArgs e) {
   585       computer.Accept(new SensorVisitor(delegate(ISensor sensor) {
   586         sensor.ResetMin();
   587         sensor.ResetMax();
   588       }));
   589     }
   590 
   591     private void MainForm_MoveOrResize(object sender, EventArgs e) {
   592       if (WindowState != FormWindowState.Minimized) {
   593         settings.SetValue("mainForm.Location.X", Bounds.X);
   594         settings.SetValue("mainForm.Location.Y", Bounds.Y);
   595         settings.SetValue("mainForm.Width", Bounds.Width);
   596         settings.SetValue("mainForm.Height", Bounds.Height);
   597       }
   598     }
   599 
   600     private void resetClick(object sender, EventArgs e) {
   601       // disable the fallback MainIcon during reset, otherwise icon visibility
   602       // might be lost 
   603       systemTray.IsMainIconEnabled = false;
   604       computer.Close();
   605       computer.Open();
   606       // restore the MainIcon setting
   607       systemTray.IsMainIconEnabled = minimizeToTray.Value;
   608     }
   609   }
   610 }