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