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