GUI/MainForm.cs
author moel.mich
Tue, 14 Feb 2012 23:07:55 +0000
changeset 340 600962f8a298
parent 327 e837e1e4b282
child 344 3145aadca3d2
permissions -rw-r--r--
Added a new sensor type "Factor" for dimensionless values (and similar) that are not to be shown as percent ("Level" type). Changed the write amplification sensor to use the new "Factor" sensor type. Added the temperature SMART attribute for Sandforce SSDs as hidden sensor (as it may show fake results on some hardware).
moel@1
     1
/*
moel@1
     2
  
moel@1
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@1
     4
moel@1
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@1
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@1
     7
  the License. You may obtain a copy of the License at
moel@1
     8
 
moel@1
     9
  http://www.mozilla.org/MPL/
moel@1
    10
moel@1
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@1
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@1
    13
  for the specific language governing rights and limitations under the License.
moel@1
    14
moel@1
    15
  The Original Code is the Open Hardware Monitor code.
moel@1
    16
moel@1
    17
  The Initial Developer of the Original Code is 
moel@1
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@335
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2012
moel@1
    20
  the Initial Developer. All Rights Reserved.
moel@1
    21
paulwerelds@223
    22
  Contributor(s): Paul Werelds
moel@1
    23
moel@1
    24
  Alternatively, the contents of this file may be used under the terms of
moel@1
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@1
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@1
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@1
    28
  of those above. If you wish to allow use of your version of this file only
moel@1
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@1
    30
  use your version of this file under the terms of the MPL, indicate your
moel@1
    31
  decision by deleting the provisions above and replace them with the notice
moel@1
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@1
    33
  the provisions above, a recipient may use your version of this file under
moel@1
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@1
    35
 
moel@1
    36
*/
moel@1
    37
moel@1
    38
using System;
moel@1
    39
using System.Collections.Generic;
moel@1
    40
using System.ComponentModel;
moel@1
    41
using System.Drawing;
moel@83
    42
using System.IO;
moel@291
    43
using System.Reflection;
moel@1
    44
using System.Windows.Forms;
moel@1
    45
using Aga.Controls.Tree;
moel@1
    46
using Aga.Controls.Tree.NodeControls;
moel@1
    47
using OpenHardwareMonitor.Hardware;
paulwerelds@227
    48
using OpenHardwareMonitor.WMI;
moel@1
    49
moel@1
    50
namespace OpenHardwareMonitor.GUI {
moel@1
    51
  public partial class MainForm : Form {
moel@1
    52
moel@165
    53
    private PersistentSettings settings;
moel@165
    54
    private UnitManager unitManager;
moel@165
    55
    private Computer computer;
moel@1
    56
    private Node root;
moel@1
    57
    private TreeModel treeModel;
moel@1
    58
    private IDictionary<ISensor, Color> sensorPlotColors = 
moel@1
    59
      new Dictionary<ISensor, Color>();
moel@1
    60
    private Color[] plotColorPalette;
moel@133
    61
    private SystemTray systemTray;    
moel@82
    62
    private StartupManager startupManager = new StartupManager();
moel@110
    63
    private UpdateVisitor updateVisitor = new UpdateVisitor();
moel@176
    64
    private SensorGadget gadget;
moel@295
    65
    private Form plotForm;
moel@326
    66
    private PlotPanel plotPanel;
moel@1
    67
moel@156
    68
    private UserOption showHiddenSensors;
moel@156
    69
    private UserOption showPlot;
moel@156
    70
    private UserOption showValue;
moel@156
    71
    private UserOption showMin;
moel@156
    72
    private UserOption showMax;
moel@156
    73
    private UserOption startMinimized;
moel@156
    74
    private UserOption minimizeToTray;
paulwerelds@198
    75
    private UserOption minimizeOnClose;
moel@156
    76
    private UserOption autoStart;
moel@156
    77
    private UserOption readHddSensors;
moel@176
    78
    private UserOption showGadget;
moel@295
    79
    private UserRadioGroup plotLocation;
paulwerelds@223
    80
paulwerelds@223
    81
    private WmiProvider wmiProvider;
moel@156
    82
moel@288
    83
    private bool selectionDragging = false;
moel@288
    84
moel@28
    85
    public MainForm() {      
moel@1
    86
      InitializeComponent();
moel@156
    87
moel@291
    88
      // check if the OpenHardwareMonitorLib assembly has the correct version
moel@291
    89
      if (Assembly.GetAssembly(typeof(Computer)).GetName().Version !=
moel@291
    90
        Assembly.GetExecutingAssembly().GetName().Version) {
moel@291
    91
        MessageBox.Show(
moel@291
    92
          "The version of the file OpenHardwareMonitorLib.dll is incompatible.",
moel@291
    93
          "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
moel@291
    94
        Environment.Exit(0);
moel@291
    95
      }
moel@291
    96
moel@165
    97
      this.settings = new PersistentSettings();      
moel@165
    98
      this.settings.Load(Path.ChangeExtension(
paulwerelds@198
    99
        Application.ExecutablePath, ".config"));
moel@165
   100
moel@165
   101
      this.unitManager = new UnitManager(settings);
moel@165
   102
moel@304
   103
      // make sure the buffers used for double buffering are not disposed 
moel@304
   104
      // after each draw call
moel@304
   105
      BufferedGraphicsManager.Current.MaximumBuffer =
moel@304
   106
        Screen.PrimaryScreen.Bounds.Size;  
moel@304
   107
moel@156
   108
      // set the DockStyle here, to avoid conflicts with the MainMenu
moel@156
   109
      this.splitContainer.Dock = DockStyle.Fill;
moel@202
   110
            
moel@1
   111
      this.Font = SystemFonts.MessageBoxFont;
moel@1
   112
      treeView.Font = SystemFonts.MessageBoxFont;
moel@326
   113
moel@326
   114
      plotPanel = new PlotPanel(settings);
moel@326
   115
      plotPanel.Font = SystemFonts.MessageBoxFont;
moel@326
   116
      plotPanel.Dock = DockStyle.Fill;
moel@1
   117
      
moel@133
   118
      nodeCheckBox.IsVisibleValueNeeded += nodeCheckBox_IsVisibleValueNeeded;
moel@133
   119
      nodeTextBoxText.DrawText += nodeTextBoxText_DrawText;
moel@133
   120
      nodeTextBoxValue.DrawText += nodeTextBoxText_DrawText;
moel@133
   121
      nodeTextBoxMin.DrawText += nodeTextBoxText_DrawText;
moel@133
   122
      nodeTextBoxMax.DrawText += nodeTextBoxText_DrawText;
moel@141
   123
      nodeTextBoxText.EditorShowing += nodeTextBoxText_EditorShowing;
moel@1
   124
moel@113
   125
      foreach (TreeColumn column in treeView.Columns) 
moel@165
   126
        column.Width = Math.Max(20, Math.Min(400,
moel@166
   127
          settings.GetValue("treeView.Columns." + column.Header + ".Width",
moel@113
   128
          column.Width)));
moel@113
   129
moel@1
   130
      treeModel = new TreeModel();
moel@1
   131
      root = new Node(System.Environment.MachineName);
moel@1
   132
      root.Image = Utilities.EmbeddedResources.GetImage("computer.png");
moel@1
   133
      
moel@1
   134
      treeModel.Nodes.Add(root);
moel@165
   135
      treeView.Model = treeModel;
moel@40
   136
moel@165
   137
      this.computer = new Computer(settings);
moel@165
   138
moel@165
   139
      systemTray = new SystemTray(computer, settings);
moel@133
   140
      systemTray.HideShowCommand += hideShowClick;
moel@133
   141
      systemTray.ExitCommand += exitClick;
moel@1
   142
moel@202
   143
      int p = (int)Environment.OSVersion.Platform;
moel@202
   144
      if ((p == 4) || (p == 128)) { // Unix
moel@287
   145
        treeView.RowHeight = Math.Max(treeView.RowHeight, 18); 
moel@202
   146
        splitContainer.BorderStyle = BorderStyle.None;
moel@202
   147
        splitContainer.Border3DStyle = Border3DStyle.Adjust;
moel@202
   148
        splitContainer.SplitterWidth = 4;
moel@202
   149
        treeView.BorderStyle = BorderStyle.Fixed3D;
moel@202
   150
        plotPanel.BorderStyle = BorderStyle.Fixed3D;
moel@202
   151
        gadgetMenuItem.Visible = false;
moel@202
   152
        minCloseMenuItem.Visible = false;
moel@269
   153
        minTrayMenuItem.Visible = false;
moel@269
   154
        startMinMenuItem.Visible = false;
moel@202
   155
      } else { // Windows
moel@287
   156
        treeView.RowHeight = Math.Max(treeView.Font.Height + 1, 18); 
moel@267
   157
moel@202
   158
        gadget = new SensorGadget(computer, settings, unitManager);
moel@244
   159
        gadget.HideShowCommand += hideShowClick;
moel@244
   160
moel@232
   161
        wmiProvider = new WmiProvider(computer);
moel@327
   162
      }
moel@86
   163
moel@111
   164
      plotColorPalette = new Color[13];
moel@1
   165
      plotColorPalette[0] = Color.Blue;
moel@1
   166
      plotColorPalette[1] = Color.OrangeRed;
moel@1
   167
      plotColorPalette[2] = Color.Green;
moel@1
   168
      plotColorPalette[3] = Color.LightSeaGreen;
moel@1
   169
      plotColorPalette[4] = Color.Goldenrod;
moel@1
   170
      plotColorPalette[5] = Color.DarkViolet;
moel@1
   171
      plotColorPalette[6] = Color.YellowGreen;
moel@1
   172
      plotColorPalette[7] = Color.SaddleBrown;
moel@111
   173
      plotColorPalette[8] = Color.RoyalBlue;
moel@111
   174
      plotColorPalette[9] = Color.DeepPink;
moel@111
   175
      plotColorPalette[10] = Color.MediumSeaGreen;
moel@111
   176
      plotColorPalette[11] = Color.Olive;
moel@111
   177
      plotColorPalette[12] = Color.Firebrick;
moel@327
   178
      
moel@327
   179
      computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
moel@327
   180
      computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);        
moel@327
   181
moel@327
   182
      computer.Open();
moel@327
   183
moel@327
   184
      timer.Enabled = true;
moel@1
   185
paulwerelds@223
   186
      showHiddenSensors = new UserOption("hiddenMenuItem", false,
paulwerelds@223
   187
        hiddenMenuItem, settings);
moel@156
   188
      showHiddenSensors.Changed += delegate(object sender, EventArgs e) {
moel@156
   189
        treeModel.ForceVisible = showHiddenSensors.Value;
moel@156
   190
      };
moel@111
   191
paulwerelds@223
   192
      showValue = new UserOption("valueMenuItem", true, valueMenuItem,
paulwerelds@223
   193
        settings);
moel@156
   194
      showValue.Changed += delegate(object sender, EventArgs e) {
moel@156
   195
        treeView.Columns[1].IsVisible = showValue.Value;
moel@156
   196
      };
moel@122
   197
moel@165
   198
      showMin = new UserOption("minMenuItem", false, minMenuItem, settings);
moel@156
   199
      showMin.Changed += delegate(object sender, EventArgs e) {
moel@156
   200
        treeView.Columns[2].IsVisible = showMin.Value;
moel@156
   201
      };
moel@156
   202
moel@165
   203
      showMax = new UserOption("maxMenuItem", true, maxMenuItem, settings);
moel@156
   204
      showMax.Changed += delegate(object sender, EventArgs e) {
moel@156
   205
        treeView.Columns[3].IsVisible = showMax.Value;
moel@156
   206
      };
moel@156
   207
paulwerelds@223
   208
      startMinimized = new UserOption("startMinMenuItem", false,
paulwerelds@223
   209
        startMinMenuItem, settings);
moel@156
   210
paulwerelds@223
   211
      minimizeToTray = new UserOption("minTrayMenuItem", true,
paulwerelds@223
   212
        minTrayMenuItem, settings);
moel@156
   213
      minimizeToTray.Changed += delegate(object sender, EventArgs e) {
moel@156
   214
        systemTray.IsMainIconEnabled = minimizeToTray.Value;
moel@156
   215
      };
moel@156
   216
paulwerelds@223
   217
      minimizeOnClose = new UserOption("minCloseMenuItem", false,
paulwerelds@223
   218
        minCloseMenuItem, settings);
paulwerelds@198
   219
paulwerelds@223
   220
      autoStart = new UserOption(null, startupManager.Startup,
paulwerelds@223
   221
        startupMenuItem, settings);
moel@156
   222
      autoStart.Changed += delegate(object sender, EventArgs e) {
moel@185
   223
        try {
moel@185
   224
          startupManager.Startup = autoStart.Value;
moel@185
   225
        } catch (InvalidOperationException) {
moel@185
   226
          MessageBox.Show("Updating the auto-startup option failed.", "Error", 
moel@185
   227
            MessageBoxButtons.OK, MessageBoxIcon.Error);
moel@185
   228
          autoStart.Value = startupManager.Startup;
moel@185
   229
        }
moel@156
   230
      };
moel@156
   231
paulwerelds@223
   232
      readHddSensors = new UserOption("hddMenuItem", true, hddMenuItem,
paulwerelds@223
   233
        settings);
moel@156
   234
      readHddSensors.Changed += delegate(object sender, EventArgs e) {
moel@156
   235
        computer.HDDEnabled = readHddSensors.Value;
moel@156
   236
      };
moel@156
   237
paulwerelds@223
   238
      showGadget = new UserOption("gadgetMenuItem", false, gadgetMenuItem,
paulwerelds@223
   239
        settings);
moel@176
   240
      showGadget.Changed += delegate(object sender, EventArgs e) {
moel@202
   241
        if (gadget != null) 
moel@202
   242
          gadget.Visible = showGadget.Value;
moel@176
   243
      };
moel@176
   244
moel@299
   245
      celsiusMenuItem.Checked = 
moel@299
   246
        unitManager.TemperatureUnit == TemperatureUnit.Celsius;
moel@299
   247
      fahrenheitMenuItem.Checked = !celsiusMenuItem.Checked;
moel@55
   248
moel@295
   249
      InitializePlotForm();
moel@295
   250
moel@142
   251
      startupMenuItem.Visible = startupManager.IsAvailable;
moel@125
   252
      
moel@55
   253
      if (startMinMenuItem.Checked) {
moel@82
   254
        if (!minTrayMenuItem.Checked) {
moel@55
   255
          WindowState = FormWindowState.Minimized;
moel@55
   256
          Show();
moel@55
   257
        }
moel@55
   258
      } else {
moel@55
   259
        Show();
moel@55
   260
      }
moel@70
   261
moel@71
   262
      // Create a handle, otherwise calling Close() does not fire FormClosed     
moel@71
   263
      IntPtr handle = Handle;
moel@128
   264
moel@128
   265
      // Make sure the settings are saved when the user logs off
paulwerelds@223
   266
      Microsoft.Win32.SystemEvents.SessionEnded += delegate {
paulwerelds@223
   267
        SaveConfiguration();
moel@304
   268
      };
moel@1
   269
    }
moel@295
   270
moel@295
   271
    private void InitializePlotForm() {
moel@295
   272
      plotForm = new Form();
moel@295
   273
      plotForm.FormBorderStyle = FormBorderStyle.SizableToolWindow;
moel@295
   274
      plotForm.ShowInTaskbar = false;
moel@295
   275
      plotForm.StartPosition = FormStartPosition.Manual;
moel@295
   276
      this.AddOwnedForm(plotForm);
moel@295
   277
      plotForm.Bounds = new Rectangle {
moel@295
   278
        X = settings.GetValue("plotForm.Location.X", -100000),
moel@295
   279
        Y = settings.GetValue("plotForm.Location.Y", 100),
moel@295
   280
        Width = settings.GetValue("plotForm.Width", 600),
moel@295
   281
        Height = settings.GetValue("plotForm.Height", 400)
moel@295
   282
      };
moel@295
   283
moel@295
   284
      showPlot = new UserOption("plotMenuItem", false, plotMenuItem, settings);
moel@295
   285
      plotLocation = new UserRadioGroup("plotLocation", 0,
moel@295
   286
        new[] { plotWindowMenuItem, plotBottomMenuItem, plotRightMenuItem },
moel@295
   287
        settings);
moel@295
   288
moel@295
   289
      showPlot.Changed += delegate(object sender, EventArgs e) {
moel@295
   290
        if (plotLocation.Value == 0) {
moel@295
   291
          if (showPlot.Value && this.Visible)
moel@295
   292
            plotForm.Show();
moel@295
   293
          else
moel@295
   294
            plotForm.Hide();
moel@295
   295
        } else {
moel@295
   296
          splitContainer.Panel2Collapsed = !showPlot.Value;
moel@295
   297
        }
moel@295
   298
        treeView.Invalidate();
moel@295
   299
      };
moel@295
   300
      plotLocation.Changed += delegate(object sender, EventArgs e) {
moel@295
   301
        switch (plotLocation.Value) {
moel@295
   302
          case 0:
moel@295
   303
            splitContainer.Panel2.Controls.Clear();
moel@295
   304
            splitContainer.Panel2Collapsed = true;
moel@295
   305
            plotForm.Controls.Add(plotPanel);
moel@295
   306
            if (showPlot.Value && this.Visible)
moel@295
   307
              plotForm.Show();
moel@295
   308
            break;
moel@295
   309
          case 1:
moel@295
   310
            plotForm.Controls.Clear();
moel@295
   311
            plotForm.Hide();
moel@295
   312
            splitContainer.Orientation = Orientation.Horizontal;
moel@295
   313
            splitContainer.Panel2.Controls.Add(plotPanel);
moel@295
   314
            splitContainer.Panel2Collapsed = !showPlot.Value;
moel@295
   315
            break;
moel@295
   316
          case 2:
moel@295
   317
            plotForm.Controls.Clear();
moel@295
   318
            plotForm.Hide();
moel@295
   319
            splitContainer.Orientation = Orientation.Vertical;
moel@295
   320
            splitContainer.Panel2.Controls.Add(plotPanel);
moel@295
   321
            splitContainer.Panel2Collapsed = !showPlot.Value;
moel@295
   322
            break;
moel@295
   323
        }
moel@295
   324
      };
moel@297
   325
moel@297
   326
      plotForm.FormClosing += delegate(object sender, FormClosingEventArgs e) {
moel@297
   327
        if (e.CloseReason == CloseReason.UserClosing) {
moel@297
   328
          // just switch off the plotting when the user closes the form
moel@297
   329
          if (plotLocation.Value == 0) {
moel@297
   330
            showPlot.Value = false;
moel@297
   331
          }
moel@297
   332
          e.Cancel = true;
moel@295
   333
        }
moel@295
   334
      };
moel@297
   335
moel@295
   336
      EventHandler moveOrResizePlotForm = delegate(object sender, EventArgs e) {
moel@295
   337
        if (plotForm.WindowState != FormWindowState.Minimized) {
moel@295
   338
          settings.SetValue("plotForm.Location.X", plotForm.Bounds.X);
moel@295
   339
          settings.SetValue("plotForm.Location.Y", plotForm.Bounds.Y);
moel@295
   340
          settings.SetValue("plotForm.Width", plotForm.Bounds.Width);
moel@295
   341
          settings.SetValue("plotForm.Height", plotForm.Bounds.Height);
moel@295
   342
        }
moel@295
   343
      };
moel@295
   344
      plotForm.Move += moveOrResizePlotForm;
moel@295
   345
      plotForm.Resize += moveOrResizePlotForm;
moel@295
   346
moel@295
   347
      plotForm.VisibleChanged += delegate(object sender, EventArgs e) {
moel@295
   348
        Rectangle bounds = new Rectangle(plotForm.Location, plotForm.Size);
moel@295
   349
        Screen screen = Screen.FromRectangle(bounds);
moel@295
   350
        Rectangle intersection =
moel@295
   351
          Rectangle.Intersect(screen.WorkingArea, bounds);
moel@295
   352
        if (intersection.Width < Math.Min(16, bounds.Width) ||
moel@295
   353
            intersection.Height < Math.Min(16, bounds.Height)) {
moel@295
   354
          plotForm.Location = new Point(
moel@295
   355
            screen.WorkingArea.Width / 2 - bounds.Width / 2,
moel@295
   356
            screen.WorkingArea.Height / 2 - bounds.Height / 2);
moel@295
   357
        }
moel@295
   358
      };
moel@295
   359
moel@295
   360
      this.VisibleChanged += delegate(object sender, EventArgs e) {
moel@295
   361
        if (this.Visible && showPlot.Value && plotLocation.Value == 0)
moel@295
   362
          plotForm.Show();
moel@295
   363
        else
moel@295
   364
          plotForm.Hide();
moel@295
   365
      };
moel@295
   366
    }
moel@128
   367
    
moel@64
   368
    private void SubHardwareAdded(IHardware hardware, Node node) {
moel@327
   369
      HardwareNode hardwareNode = 
moel@327
   370
        new HardwareNode(hardware, settings, unitManager);
moel@327
   371
      hardwareNode.PlotSelectionChanged += PlotSelectionChanged;
moel@327
   372
moel@64
   373
      node.Nodes.Add(hardwareNode);
moel@64
   374
      foreach (IHardware subHardware in hardware.SubHardware)
moel@64
   375
        SubHardwareAdded(subHardware, hardwareNode);  
moel@64
   376
    }
moel@64
   377
moel@327
   378
    private void HardwareAdded(IHardware hardware) {      
moel@327
   379
      SubHardwareAdded(hardware, root);
moel@327
   380
      PlotSelectionChanged(this, null);
moel@1
   381
    }
moel@1
   382
moel@327
   383
    private void HardwareRemoved(IHardware hardware) {
moel@327
   384
      List<HardwareNode> nodesToRemove = new List<HardwareNode>();
moel@28
   385
      foreach (Node node in root.Nodes) {
moel@28
   386
        HardwareNode hardwareNode = node as HardwareNode;
moel@28
   387
        if (hardwareNode != null && hardwareNode.Hardware == hardware)
moel@327
   388
          nodesToRemove.Add(hardwareNode);
moel@28
   389
      }
moel@327
   390
      foreach (HardwareNode hardwareNode in nodesToRemove) {
moel@327
   391
        root.Nodes.Remove(hardwareNode);
moel@327
   392
        hardwareNode.PlotSelectionChanged -= PlotSelectionChanged;
moel@327
   393
      }
moel@327
   394
      PlotSelectionChanged(this, null);
moel@1
   395
    }
moel@1
   396
moel@111
   397
    private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {       
moel@111
   398
      Node node = e.Node.Tag as Node;
moel@111
   399
      if (node != null) {
moel@1
   400
        Color color;
moel@111
   401
        if (node.IsVisible) {
moel@111
   402
          SensorNode sensorNode = node as SensorNode;
moel@111
   403
          if (plotMenuItem.Checked && sensorNode != null &&
moel@111
   404
            sensorPlotColors.TryGetValue(sensorNode.Sensor, out color))
moel@111
   405
            e.TextColor = color;
moel@111
   406
        } else {
moel@111
   407
          e.TextColor = Color.DarkGray;
moel@111
   408
        }
moel@1
   409
      }
moel@1
   410
    }
moel@1
   411
moel@327
   412
    private void PlotSelectionChanged(object sender, EventArgs e) {
moel@1
   413
      List<ISensor> selected = new List<ISensor>();
moel@1
   414
      IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
moel@1
   415
      int colorIndex = 0;
moel@1
   416
      foreach (TreeNodeAdv node in treeView.AllNodes) {
moel@1
   417
        SensorNode sensorNode = node.Tag as SensorNode;
moel@327
   418
        if (sensorNode != null &&
moel@1
   419
          sensorNode.Sensor.SensorType == SensorType.Temperature) {
moel@1
   420
          if (sensorNode.Plot) {
moel@1
   421
            colors.Add(sensorNode.Sensor,
moel@1
   422
              plotColorPalette[colorIndex % plotColorPalette.Length]);
moel@1
   423
            selected.Add(sensorNode.Sensor);
moel@1
   424
          }
moel@1
   425
          colorIndex++;
moel@1
   426
        }
moel@1
   427
      }
moel@1
   428
      sensorPlotColors = colors;
moel@1
   429
      plotPanel.SetSensors(selected, colors);
moel@1
   430
    }
moel@1
   431
paulwerelds@223
   432
    private void nodeTextBoxText_EditorShowing(object sender,
paulwerelds@223
   433
      CancelEventArgs e) 
moel@141
   434
    {
moel@141
   435
      e.Cancel = !(treeView.CurrentNode != null &&
moel@275
   436
        (treeView.CurrentNode.Tag is SensorNode || 
moel@275
   437
         treeView.CurrentNode.Tag is HardwareNode));
moel@141
   438
    }
moel@141
   439
moel@1
   440
    private void nodeCheckBox_IsVisibleValueNeeded(object sender, 
moel@1
   441
      NodeControlValueEventArgs e) {
moel@1
   442
      SensorNode node = e.Node.Tag as SensorNode;
moel@1
   443
      e.Value = (node != null) && 
moel@1
   444
        (node.Sensor.SensorType == SensorType.Temperature) && 
moel@1
   445
        plotMenuItem.Checked;
moel@1
   446
    }
moel@1
   447
moel@133
   448
    private void exitClick(object sender, EventArgs e) {
paulwerelds@198
   449
      Close();
moel@1
   450
    }
moel@1
   451
moel@86
   452
    private void timer_Tick(object sender, EventArgs e) {
moel@110
   453
      computer.Accept(updateVisitor);
moel@1
   454
      treeView.Invalidate();
moel@1
   455
      plotPanel.Invalidate();
paulwerelds@223
   456
      systemTray.Redraw();
moel@202
   457
      if (gadget != null)
moel@202
   458
        gadget.Redraw();
paulwerelds@223
   459
paulwerelds@223
   460
      if (wmiProvider != null)
paulwerelds@223
   461
        wmiProvider.Update();
moel@1
   462
    }
moel@1
   463
moel@128
   464
    private void SaveConfiguration() {
moel@128
   465
      foreach (TreeColumn column in treeView.Columns)
moel@166
   466
        settings.SetValue("treeView.Columns." + column.Header + ".Width",
moel@113
   467
          column.Width);
moel@113
   468
moel@212
   469
      string fileName = Path.ChangeExtension(
moel@212
   470
          System.Windows.Forms.Application.ExecutablePath, ".config");
moel@212
   471
      try {
moel@212
   472
        settings.Save(fileName);
moel@212
   473
      } catch (UnauthorizedAccessException) {
paulwerelds@214
   474
        MessageBox.Show("Access to the path '" + fileName + "' is denied. " +
moel@284
   475
          "The current settings could not be saved.",
moel@284
   476
          "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
moel@284
   477
      } catch (IOException) {
moel@284
   478
        MessageBox.Show("The path '" + fileName + "' is not writeable. " +
moel@284
   479
          "The current settings could not be saved.",
moel@212
   480
          "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
moel@212
   481
      }
moel@128
   482
    }
moel@128
   483
paulwerelds@214
   484
    private void MainForm_Load(object sender, EventArgs e) {
paulwerelds@214
   485
      Rectangle newBounds = new Rectangle {
paulwerelds@214
   486
        X = settings.GetValue("mainForm.Location.X", Location.X),
paulwerelds@214
   487
        Y = settings.GetValue("mainForm.Location.Y", Location.Y),
paulwerelds@214
   488
        Width = settings.GetValue("mainForm.Width", 470),
paulwerelds@214
   489
        Height = settings.GetValue("mainForm.Height", 640)
paulwerelds@214
   490
      };
paulwerelds@214
   491
paulwerelds@223
   492
      Rectangle fullWorkingArea = new Rectangle(int.MaxValue, int.MaxValue,
paulwerelds@214
   493
        int.MinValue, int.MinValue);
paulwerelds@214
   494
paulwerelds@214
   495
      foreach (Screen screen in Screen.AllScreens)
paulwerelds@223
   496
        fullWorkingArea = Rectangle.Union(fullWorkingArea, screen.Bounds);
paulwerelds@214
   497
paulwerelds@223
   498
      Rectangle intersection = Rectangle.Intersect(fullWorkingArea, newBounds);
paulwerelds@214
   499
      if (intersection.Width < 20 || intersection.Height < 20 ||
paulwerelds@214
   500
        !settings.Contains("mainForm.Location.X")
paulwerelds@214
   501
      ) {
paulwerelds@214
   502
        newBounds.X = (Screen.PrimaryScreen.WorkingArea.Width / 2) -
paulwerelds@214
   503
                      (newBounds.Width/2);
paulwerelds@214
   504
paulwerelds@214
   505
        newBounds.Y = (Screen.PrimaryScreen.WorkingArea.Height / 2) -
paulwerelds@214
   506
                      (newBounds.Height / 2);
paulwerelds@214
   507
      }
paulwerelds@214
   508
paulwerelds@214
   509
      this.Bounds = newBounds;
paulwerelds@214
   510
    }
paulwerelds@214
   511
    
paulwerelds@214
   512
    private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
moel@298
   513
      Visible = false;      
moel@262
   514
      systemTray.IsMainIconEnabled = false;
moel@262
   515
      timer.Enabled = false;            
moel@28
   516
      computer.Close();
moel@298
   517
      SaveConfiguration();
moel@262
   518
      systemTray.Dispose();
moel@1
   519
    }
moel@1
   520
moel@156
   521
    private void aboutMenuItem_Click(object sender, EventArgs e) {
moel@1
   522
      new AboutBox().ShowDialog();
moel@1
   523
    }
moel@1
   524
moel@1
   525
    private void treeView_Click(object sender, EventArgs e) {
moel@275
   526
moel@1
   527
      MouseEventArgs m = e as MouseEventArgs;
moel@1
   528
      if (m == null || m.Button != MouseButtons.Right)
moel@1
   529
        return;
moel@1
   530
paulwerelds@223
   531
      NodeControlInfo info = treeView.GetNodeControlInfoAt(
paulwerelds@223
   532
        new Point(m.X, m.Y)
paulwerelds@223
   533
      );
moel@156
   534
      treeView.SelectedNode = info.Node;
moel@156
   535
      if (info.Node != null) {
moel@40
   536
        SensorNode node = info.Node.Tag as SensorNode;
moel@40
   537
        if (node != null && node.Sensor != null) {
moel@275
   538
          treeContextMenu.MenuItems.Clear();
moel@63
   539
          if (node.Sensor.Parameters.Length > 0) {
moel@156
   540
            MenuItem item = new MenuItem("Parameters...");
moel@63
   541
            item.Click += delegate(object obj, EventArgs args) {
moel@63
   542
              ShowParameterForm(node.Sensor);
moel@63
   543
            };
moel@275
   544
            treeContextMenu.MenuItems.Add(item);
moel@63
   545
          }
moel@156
   546
          if (nodeTextBoxText.EditEnabled) {
moel@156
   547
            MenuItem item = new MenuItem("Rename");
moel@141
   548
            item.Click += delegate(object obj, EventArgs args) {
moel@156
   549
              nodeTextBoxText.BeginEdit();
moel@141
   550
            };
moel@275
   551
            treeContextMenu.MenuItems.Add(item);
moel@176
   552
          }
moel@111
   553
          if (node.IsVisible) {
moel@156
   554
            MenuItem item = new MenuItem("Hide");
moel@111
   555
            item.Click += delegate(object obj, EventArgs args) {
moel@111
   556
              node.IsVisible = false;
moel@111
   557
            };
moel@275
   558
            treeContextMenu.MenuItems.Add(item);
moel@111
   559
          } else {
moel@156
   560
            MenuItem item = new MenuItem("Unhide");
moel@111
   561
            item.Click += delegate(object obj, EventArgs args) {
moel@111
   562
              node.IsVisible = true;
moel@111
   563
            };
moel@275
   564
            treeContextMenu.MenuItems.Add(item);
moel@176
   565
          }
moel@275
   566
          treeContextMenu.MenuItems.Add(new MenuItem("-"));
moel@178
   567
          {
moel@178
   568
            MenuItem item = new MenuItem("Show in Tray");
moel@178
   569
            item.Checked = systemTray.Contains(node.Sensor);
moel@178
   570
            item.Click += delegate(object obj, EventArgs args) {
moel@178
   571
              if (item.Checked)
moel@178
   572
                systemTray.Remove(node.Sensor);
moel@178
   573
              else
moel@178
   574
                systemTray.Add(node.Sensor, true);
moel@178
   575
            };
moel@275
   576
            treeContextMenu.MenuItems.Add(item);
moel@178
   577
          }
moel@211
   578
          if (gadget != null) {
moel@178
   579
            MenuItem item = new MenuItem("Show in Gadget");
moel@178
   580
            item.Checked = gadget.Contains(node.Sensor);
moel@178
   581
            item.Click += delegate(object obj, EventArgs args) {
moel@178
   582
              if (item.Checked) {
moel@178
   583
                gadget.Remove(node.Sensor);
moel@178
   584
              } else {
moel@178
   585
                gadget.Add(node.Sensor);
moel@178
   586
              }
moel@178
   587
            };
moel@275
   588
            treeContextMenu.MenuItems.Add(item);
moel@178
   589
          }
moel@247
   590
          if (node.Sensor.Control != null) {
moel@275
   591
            treeContextMenu.MenuItems.Add(new MenuItem("-"));
moel@247
   592
            IControl control = node.Sensor.Control;
moel@247
   593
            MenuItem controlItem = new MenuItem("Control");
moel@247
   594
            MenuItem defaultItem = new MenuItem("Default");
moel@247
   595
            defaultItem.Checked = control.ControlMode == ControlMode.Default;
moel@247
   596
            controlItem.MenuItems.Add(defaultItem);
moel@247
   597
            defaultItem.Click += delegate(object obj, EventArgs args) {
moel@247
   598
              control.SetDefault();
moel@247
   599
            };
moel@275
   600
            MenuItem manualItem = new MenuItem("Manual");
moel@247
   601
            controlItem.MenuItems.Add(manualItem);
moel@247
   602
            manualItem.Checked = control.ControlMode == ControlMode.Software;
moel@247
   603
            for (int i = 0; i <= 100; i += 5) {
moel@247
   604
              if (i <= control.MaxSoftwareValue &&
moel@275
   605
                  i >= control.MinSoftwareValue) {
moel@247
   606
                MenuItem item = new MenuItem(i + " %");
moel@247
   607
                manualItem.MenuItems.Add(item);
moel@247
   608
                item.Checked = control.ControlMode == ControlMode.Software &&
moel@247
   609
                  Math.Round(control.SoftwareValue) == i;
moel@247
   610
                int softwareValue = i;
moel@247
   611
                item.Click += delegate(object obj, EventArgs args) {
moel@247
   612
                  control.SetSoftware(softwareValue);
moel@247
   613
                };
moel@247
   614
              }
moel@247
   615
            }
moel@275
   616
            treeContextMenu.MenuItems.Add(controlItem);
moel@247
   617
          }
moel@176
   618
moel@275
   619
          treeContextMenu.Show(treeView, new Point(m.X, m.Y));
moel@275
   620
        }
moel@275
   621
moel@275
   622
        HardwareNode hardwareNode = info.Node.Tag as HardwareNode;
moel@275
   623
        if (hardwareNode != null && hardwareNode.Hardware != null) {
moel@275
   624
          treeContextMenu.MenuItems.Clear();
moel@275
   625
moel@275
   626
          if (nodeTextBoxText.EditEnabled) {
moel@275
   627
            MenuItem item = new MenuItem("Rename");
moel@275
   628
            item.Click += delegate(object obj, EventArgs args) {
moel@275
   629
              nodeTextBoxText.BeginEdit();
moel@275
   630
            };
moel@275
   631
            treeContextMenu.MenuItems.Add(item);
moel@275
   632
          }
moel@275
   633
moel@275
   634
          treeContextMenu.Show(treeView, new Point(m.X, m.Y));
moel@40
   635
        }
moel@40
   636
      }
moel@1
   637
    }
moel@1
   638
moel@156
   639
    private void saveReportMenuItem_Click(object sender, EventArgs e) {
moel@83
   640
      string report = computer.GetReport();
moel@83
   641
      if (saveFileDialog.ShowDialog() == DialogResult.OK) {
moel@83
   642
        using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
moel@83
   643
          w.Write(report);
moel@83
   644
        }
moel@83
   645
      }
moel@1
   646
    }
moel@1
   647
moel@82
   648
    private void SysTrayHideShow() {
moel@82
   649
      Visible = !Visible;
moel@82
   650
      if (Visible)
moel@82
   651
        Activate();    
moel@27
   652
    }
moel@27
   653
moel@27
   654
    protected override void WndProc(ref Message m) {
moel@27
   655
      const int WM_SYSCOMMAND = 0x112;
moel@27
   656
      const int SC_MINIMIZE = 0xF020;
paulwerelds@198
   657
      const int SC_CLOSE = 0xF060;
paulwerelds@198
   658
moel@156
   659
      if (minimizeToTray.Value && 
moel@335
   660
        m.Msg == WM_SYSCOMMAND && m.WParam.ToInt64() == SC_MINIMIZE) {
moel@82
   661
        SysTrayHideShow();
moel@335
   662
      } else if (minimizeOnClose.Value &&
moel@335
   663
        m.Msg == WM_SYSCOMMAND && m.WParam.ToInt64() == SC_CLOSE) {
paulwerelds@198
   664
        /*
paulwerelds@198
   665
         * Apparently the user wants to minimize rather than close
paulwerelds@198
   666
         * Now we still need to check if we're going to the tray or not
paulwerelds@198
   667
         * 
paulwerelds@198
   668
         * Note: the correct way to do this would be to send out SC_MINIMIZE,
paulwerelds@198
   669
         * but since the code here is so simple,
paulwerelds@198
   670
         * that would just be a waste of time.
paulwerelds@198
   671
         */
paulwerelds@198
   672
        if (minimizeToTray.Value)
paulwerelds@198
   673
          SysTrayHideShow();
paulwerelds@198
   674
        else
paulwerelds@198
   675
          WindowState = FormWindowState.Minimized;
moel@27
   676
      } else {      
moel@27
   677
        base.WndProc(ref m);
moel@27
   678
      }
moel@27
   679
    }
moel@27
   680
moel@82
   681
    private void hideShowClick(object sender, EventArgs e) {
moel@82
   682
      SysTrayHideShow();
moel@27
   683
    }
moel@27
   684
moel@63
   685
    private void ShowParameterForm(ISensor sensor) {
moel@63
   686
      ParameterForm form = new ParameterForm();
moel@63
   687
      form.Parameters = sensor.Parameters;
moel@63
   688
      form.captionLabel.Text = sensor.Name;
moel@63
   689
      form.ShowDialog();
moel@63
   690
    }
moel@63
   691
moel@63
   692
    private void treeView_NodeMouseDoubleClick(object sender, 
moel@63
   693
      TreeNodeAdvMouseEventArgs e) {
moel@63
   694
      SensorNode node = e.Node.Tag as SensorNode;
moel@63
   695
      if (node != null && node.Sensor != null && 
moel@63
   696
        node.Sensor.Parameters.Length > 0) {
moel@63
   697
        ShowParameterForm(node.Sensor);
moel@63
   698
      }
moel@63
   699
    }
moel@82
   700
moel@299
   701
    private void celsiusMenuItem_Click(object sender, EventArgs e) {
moel@299
   702
      celsiusMenuItem.Checked = true;
moel@156
   703
      fahrenheitMenuItem.Checked = false;
moel@299
   704
      unitManager.TemperatureUnit = TemperatureUnit.Celsius;
moel@122
   705
    }
moel@122
   706
moel@156
   707
    private void fahrenheitMenuItem_Click(object sender, EventArgs e) {
moel@299
   708
      celsiusMenuItem.Checked = false;
moel@156
   709
      fahrenheitMenuItem.Checked = true;
moel@165
   710
      unitManager.TemperatureUnit = TemperatureUnit.Fahrenheit;
moel@122
   711
    }
moel@150
   712
moel@156
   713
    private void sumbitReportMenuItem_Click(object sender, EventArgs e) 
moel@150
   714
    {
moel@150
   715
      ReportForm form = new ReportForm();
moel@150
   716
      form.Report = computer.GetReport();
moel@150
   717
      form.ShowDialog();      
moel@150
   718
    }
moel@151
   719
moel@151
   720
    private void resetMinMaxMenuItem_Click(object sender, EventArgs e) {
moel@159
   721
      computer.Accept(new SensorVisitor(delegate(ISensor sensor) {
moel@159
   722
        sensor.ResetMin();
moel@159
   723
        sensor.ResetMax();
moel@159
   724
      }));
moel@151
   725
    }
moel@241
   726
moel@241
   727
    private void MainForm_MoveOrResize(object sender, EventArgs e) {
moel@241
   728
      if (WindowState != FormWindowState.Minimized) {
moel@241
   729
        settings.SetValue("mainForm.Location.X", Bounds.X);
moel@241
   730
        settings.SetValue("mainForm.Location.Y", Bounds.Y);
moel@241
   731
        settings.SetValue("mainForm.Width", Bounds.Width);
moel@241
   732
        settings.SetValue("mainForm.Height", Bounds.Height);
moel@241
   733
      }
moel@241
   734
    }
moel@262
   735
moel@262
   736
    private void resetClick(object sender, EventArgs e) {
moel@262
   737
      // disable the fallback MainIcon during reset, otherwise icon visibility
moel@262
   738
      // might be lost 
moel@262
   739
      systemTray.IsMainIconEnabled = false;
moel@262
   740
      computer.Close();
moel@262
   741
      computer.Open();
moel@262
   742
      // restore the MainIcon setting
moel@262
   743
      systemTray.IsMainIconEnabled = minimizeToTray.Value;
moel@262
   744
    }
moel@287
   745
moel@287
   746
    private void treeView_MouseMove(object sender, MouseEventArgs e) {
moel@288
   747
      selectionDragging = selectionDragging &
moel@288
   748
        (e.Button & (MouseButtons.Left | MouseButtons.Right)) > 0; 
moel@288
   749
moel@288
   750
      if (selectionDragging)
moel@288
   751
        treeView.SelectedNode = treeView.GetNodeAt(e.Location);     
moel@288
   752
    }
moel@288
   753
moel@288
   754
    private void treeView_MouseDown(object sender, MouseEventArgs e) {
moel@288
   755
      selectionDragging = true;
moel@288
   756
    }
moel@288
   757
moel@288
   758
    private void treeView_MouseUp(object sender, MouseEventArgs e) {
moel@288
   759
      selectionDragging = false;
moel@287
   760
    }
moel@1
   761
  }
moel@1
   762
}