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