Fixed Issue 112.
3 Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 The contents of this file are subject to the Mozilla Public License Version
6 1.1 (the "License"); you may not use this file except in compliance with
7 the License. You may obtain a copy of the License at
9 http://www.mozilla.org/MPL/
11 Software distributed under the License is distributed on an "AS IS" basis,
12 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 for the specific language governing rights and limitations under the License.
15 The Original Code is the Open Hardware Monitor code.
17 The Initial Developer of the Original Code is
18 Michael Möller <m.moeller@gmx.ch>.
19 Portions created by the Initial Developer are Copyright (C) 2009-2010
20 the Initial Developer. All Rights Reserved.
24 Alternatively, the contents of this file may be used under the terms of
25 either the GNU General Public License Version 2 or later (the "GPL"), or
26 the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 in which case the provisions of the GPL or the LGPL are applicable instead
28 of those above. If you wish to allow use of your version of this file only
29 under the terms of either the GPL or the LGPL, and not to allow others to
30 use your version of this file under the terms of the MPL, indicate your
31 decision by deleting the provisions above and replace them with the notice
32 and other provisions required by the GPL or the LGPL. If you do not delete
33 the provisions above, a recipient may use your version of this file under
34 the terms of any one of the MPL, the GPL or the LGPL.
39 using System.Collections.Generic;
40 using System.ComponentModel;
41 using System.Configuration;
45 using System.Windows.Forms;
46 using Aga.Controls.Tree;
47 using Aga.Controls.Tree.NodeControls;
48 using OpenHardwareMonitor.Hardware;
49 using OpenHardwareMonitor.Utilities;
51 namespace OpenHardwareMonitor.GUI {
52 public partial class MainForm : Form {
54 private PersistentSettings settings;
55 private UnitManager unitManager;
56 private Computer computer;
58 private TreeModel treeModel;
59 private IDictionary<ISensor, Color> sensorPlotColors =
60 new Dictionary<ISensor, Color>();
61 private Color[] plotColorPalette;
62 private SystemTray systemTray;
63 private StartupManager startupManager = new StartupManager();
64 private UpdateVisitor updateVisitor = new UpdateVisitor();
65 private SensorGadget gadget;
67 private UserOption showHiddenSensors;
68 private UserOption showPlot;
69 private UserOption showValue;
70 private UserOption showMin;
71 private UserOption showMax;
72 private UserOption startMinimized;
73 private UserOption minimizeToTray;
74 private UserOption autoStart;
75 private UserOption readHddSensors;
76 private UserOption showGadget;
79 InitializeComponent();
81 this.settings = new PersistentSettings();
82 this.settings.Load(Path.ChangeExtension(
83 System.Windows.Forms.Application.ExecutablePath, ".config"));
85 this.unitManager = new UnitManager(settings);
87 // set the DockStyle here, to avoid conflicts with the MainMenu
88 this.splitContainer.Dock = DockStyle.Fill;
90 int p = (int)System.Environment.OSVersion.Platform;
91 if ((p == 4) || (p == 128)) {
92 splitContainer.BorderStyle = BorderStyle.None;
93 splitContainer.Border3DStyle = Border3DStyle.Adjust;
94 splitContainer.SplitterWidth = 4;
95 treeView.BorderStyle = BorderStyle.Fixed3D;
96 plotPanel.BorderStyle = BorderStyle.Fixed3D;
99 this.Font = SystemFonts.MessageBoxFont;
100 treeView.Font = SystemFonts.MessageBoxFont;
101 plotPanel.Font = SystemFonts.MessageBoxFont;
103 nodeCheckBox.IsVisibleValueNeeded += nodeCheckBox_IsVisibleValueNeeded;
104 nodeCheckBox.CheckStateChanged += UpdatePlotSelection;
105 nodeTextBoxText.DrawText += nodeTextBoxText_DrawText;
106 nodeTextBoxValue.DrawText += nodeTextBoxText_DrawText;
107 nodeTextBoxMin.DrawText += nodeTextBoxText_DrawText;
108 nodeTextBoxMax.DrawText += nodeTextBoxText_DrawText;
109 nodeTextBoxText.EditorShowing += nodeTextBoxText_EditorShowing;
111 if (settings.Contains("mainForm.Location.X")) {
112 int x = settings.GetValue("mainForm.Location.X", Location.X);
114 int y = settings.GetValue("mainForm.Location.Y", Location.Y);
116 this.Location = new Point(x, y);
118 StartPosition = FormStartPosition.CenterScreen;
121 ClientSize = new Size(
122 settings.GetValue("mainForm.Width", 470),
123 settings.GetValue("mainForm.Height", 640));
125 foreach (TreeColumn column in treeView.Columns)
126 column.Width = Math.Max(20, Math.Min(400,
127 settings.GetValue("treeView.Columns." + column.Header + ".Width",
130 treeModel = new TreeModel();
131 root = new Node(System.Environment.MachineName);
132 root.Image = Utilities.EmbeddedResources.GetImage("computer.png");
134 treeModel.Nodes.Add(root);
135 treeView.Model = treeModel;
137 this.computer = new Computer(settings);
139 systemTray = new SystemTray(computer, settings);
140 systemTray.HideShowCommand += hideShowClick;
141 systemTray.ExitCommand += exitClick;
143 gadget = new SensorGadget(computer, settings, unitManager);
145 computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
146 computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
149 timer.Enabled = true;
151 plotColorPalette = new Color[13];
152 plotColorPalette[0] = Color.Blue;
153 plotColorPalette[1] = Color.OrangeRed;
154 plotColorPalette[2] = Color.Green;
155 plotColorPalette[3] = Color.LightSeaGreen;
156 plotColorPalette[4] = Color.Goldenrod;
157 plotColorPalette[5] = Color.DarkViolet;
158 plotColorPalette[6] = Color.YellowGreen;
159 plotColorPalette[7] = Color.SaddleBrown;
160 plotColorPalette[8] = Color.RoyalBlue;
161 plotColorPalette[9] = Color.DeepPink;
162 plotColorPalette[10] = Color.MediumSeaGreen;
163 plotColorPalette[11] = Color.Olive;
164 plotColorPalette[12] = Color.Firebrick;
166 showHiddenSensors = new UserOption("hiddenMenuItem", false, hiddenMenuItem, settings);
167 showHiddenSensors.Changed += delegate(object sender, EventArgs e) {
168 treeModel.ForceVisible = showHiddenSensors.Value;
171 showPlot = new UserOption("plotMenuItem", false, plotMenuItem, settings);
172 showPlot.Changed += delegate(object sender, EventArgs e) {
173 splitContainer.Panel2Collapsed = !showPlot.Value;
174 treeView.Invalidate();
177 showValue = new UserOption("valueMenuItem", true, valueMenuItem, settings);
178 showValue.Changed += delegate(object sender, EventArgs e) {
179 treeView.Columns[1].IsVisible = showValue.Value;
182 showMin = new UserOption("minMenuItem", false, minMenuItem, settings);
183 showMin.Changed += delegate(object sender, EventArgs e) {
184 treeView.Columns[2].IsVisible = showMin.Value;
187 showMax = new UserOption("maxMenuItem", true, maxMenuItem, settings);
188 showMax.Changed += delegate(object sender, EventArgs e) {
189 treeView.Columns[3].IsVisible = showMax.Value;
192 startMinimized = new UserOption("startMinMenuItem", false, startMinMenuItem, settings);
194 minimizeToTray = new UserOption("minTrayMenuItem", true, minTrayMenuItem, settings);
195 minimizeToTray.Changed += delegate(object sender, EventArgs e) {
196 systemTray.IsMainIconEnabled = minimizeToTray.Value;
199 autoStart = new UserOption(null, startupManager.Startup, startupMenuItem, settings);
200 autoStart.Changed += delegate(object sender, EventArgs e) {
202 startupManager.Startup = autoStart.Value;
203 } catch (InvalidOperationException) {
204 MessageBox.Show("Updating the auto-startup option failed.", "Error",
205 MessageBoxButtons.OK, MessageBoxIcon.Error);
206 autoStart.Value = startupManager.Startup;
210 readHddSensors = new UserOption("hddMenuItem", true, hddMenuItem, settings);
211 readHddSensors.Changed += delegate(object sender, EventArgs e) {
212 computer.HDDEnabled = readHddSensors.Value;
213 UpdatePlotSelection(null, null);
216 showGadget = new UserOption("gadgetMenuItem", false, gadgetMenuItem, settings);
217 showGadget.Changed += delegate(object sender, EventArgs e) {
218 gadget.Visible = showGadget.Value;
221 celciusMenuItem.Checked =
222 unitManager.TemperatureUnit == TemperatureUnit.Celcius;
223 fahrenheitMenuItem.Checked = !celciusMenuItem.Checked;
225 startupMenuItem.Visible = startupManager.IsAvailable;
227 if (startMinMenuItem.Checked) {
228 if (!minTrayMenuItem.Checked) {
229 WindowState = FormWindowState.Minimized;
236 // Create a handle, otherwise calling Close() does not fire FormClosed
237 IntPtr handle = Handle;
239 // Make sure the settings are saved when the user logs off
240 Microsoft.Win32.SystemEvents.SessionEnded +=
241 delegate(object sender, Microsoft.Win32.SessionEndedEventArgs e) {
246 private void SubHardwareAdded(IHardware hardware, Node node) {
247 Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
248 node.Nodes.Add(hardwareNode);
249 foreach (IHardware subHardware in hardware.SubHardware)
250 SubHardwareAdded(subHardware, hardwareNode);
253 private void HardwareAdded(IHardware hardware) {
254 Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
255 root.Nodes.Add(hardwareNode);
256 foreach (IHardware subHardware in hardware.SubHardware)
257 SubHardwareAdded(subHardware, hardwareNode);
260 private void HardwareRemoved(IHardware hardware) {
261 List<Node> nodesToRemove = new List<Node>();
262 foreach (Node node in root.Nodes) {
263 HardwareNode hardwareNode = node as HardwareNode;
264 if (hardwareNode != null && hardwareNode.Hardware == hardware)
265 nodesToRemove.Add(node);
267 foreach (Node node in nodesToRemove)
268 root.Nodes.Remove(node);
271 private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {
272 Node node = e.Node.Tag as Node;
275 if (node.IsVisible) {
276 SensorNode sensorNode = node as SensorNode;
277 if (plotMenuItem.Checked && sensorNode != null &&
278 sensorPlotColors.TryGetValue(sensorNode.Sensor, out color))
281 e.TextColor = Color.DarkGray;
286 private void UpdatePlotSelection(object sender,
289 List<ISensor> selected = new List<ISensor>();
290 IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
292 foreach (TreeNodeAdv node in treeView.AllNodes) {
293 SensorNode sensorNode = node.Tag as SensorNode;
294 if (sensorNode != null &&
295 sensorNode.Sensor.SensorType == SensorType.Temperature) {
296 if (sensorNode.Plot) {
297 colors.Add(sensorNode.Sensor,
298 plotColorPalette[colorIndex % plotColorPalette.Length]);
299 selected.Add(sensorNode.Sensor);
304 sensorPlotColors = colors;
305 plotPanel.SetSensors(selected, colors);
308 private void nodeTextBoxText_EditorShowing(object sender, CancelEventArgs e)
310 e.Cancel = !(treeView.CurrentNode != null &&
311 treeView.CurrentNode.Tag is SensorNode);
314 private void nodeCheckBox_IsVisibleValueNeeded(object sender,
315 NodeControlValueEventArgs e) {
316 SensorNode node = e.Node.Tag as SensorNode;
317 e.Value = (node != null) &&
318 (node.Sensor.SensorType == SensorType.Temperature) &&
319 plotMenuItem.Checked;
322 private void exitClick(object sender, EventArgs e) {
326 private void timer_Tick(object sender, EventArgs e) {
327 computer.Accept(updateVisitor);
328 treeView.Invalidate();
329 plotPanel.Invalidate();
334 private void SaveConfiguration() {
335 if (WindowState != FormWindowState.Minimized) {
336 settings.SetValue("mainForm.Location.X", Location.X);
337 settings.SetValue("mainForm.Location.Y", Location.Y);
338 settings.SetValue("mainForm.Width", ClientSize.Width);
339 settings.SetValue("mainForm.Height", ClientSize.Height);
342 foreach (TreeColumn column in treeView.Columns)
343 settings.SetValue("treeView.Columns." + column.Header + ".Width",
346 settings.Save(Path.ChangeExtension(
347 System.Windows.Forms.Application.ExecutablePath, ".config"));
350 private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
354 timer.Enabled = false;
355 systemTray.Dispose();
359 private void aboutMenuItem_Click(object sender, EventArgs e) {
360 new AboutBox().ShowDialog();
363 private void treeView_Click(object sender, EventArgs e) {
365 MouseEventArgs m = e as MouseEventArgs;
366 if (m == null || m.Button != MouseButtons.Right)
369 NodeControlInfo info = treeView.GetNodeControlInfoAt(new Point(m.X, m.Y));
370 treeView.SelectedNode = info.Node;
371 if (info.Node != null) {
372 SensorNode node = info.Node.Tag as SensorNode;
373 if (node != null && node.Sensor != null) {
374 sensorContextMenu.MenuItems.Clear();
375 if (node.Sensor.Parameters.Length > 0) {
376 MenuItem item = new MenuItem("Parameters...");
377 item.Click += delegate(object obj, EventArgs args) {
378 ShowParameterForm(node.Sensor);
380 sensorContextMenu.MenuItems.Add(item);
382 if (nodeTextBoxText.EditEnabled) {
383 MenuItem item = new MenuItem("Rename");
384 item.Click += delegate(object obj, EventArgs args) {
385 nodeTextBoxText.BeginEdit();
387 sensorContextMenu.MenuItems.Add(item);
389 if (node.IsVisible) {
390 MenuItem item = new MenuItem("Hide");
391 item.Click += delegate(object obj, EventArgs args) {
392 node.IsVisible = false;
394 sensorContextMenu.MenuItems.Add(item);
396 MenuItem item = new MenuItem("Unhide");
397 item.Click += delegate(object obj, EventArgs args) {
398 node.IsVisible = true;
400 sensorContextMenu.MenuItems.Add(item);
402 sensorContextMenu.MenuItems.Add(new MenuItem("-"));
404 MenuItem item = new MenuItem("Show in Tray");
405 item.Checked = systemTray.Contains(node.Sensor);
406 item.Click += delegate(object obj, EventArgs args) {
408 systemTray.Remove(node.Sensor);
410 systemTray.Add(node.Sensor, true);
412 sensorContextMenu.MenuItems.Add(item);
415 MenuItem item = new MenuItem("Show in Gadget");
416 item.Checked = gadget.Contains(node.Sensor);
417 item.Click += delegate(object obj, EventArgs args) {
419 gadget.Remove(node.Sensor);
421 gadget.Add(node.Sensor);
424 sensorContextMenu.MenuItems.Add(item);
427 sensorContextMenu.Show(treeView, new Point(m.X, m.Y));
432 private void saveReportMenuItem_Click(object sender, EventArgs e) {
433 string report = computer.GetReport();
434 if (saveFileDialog.ShowDialog() == DialogResult.OK) {
435 using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
441 private void SysTrayHideShow() {
447 protected override void WndProc(ref Message m) {
448 const int WM_SYSCOMMAND = 0x112;
449 const int SC_MINIMIZE = 0xF020;
450 if (minimizeToTray.Value &&
451 m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
458 private void hideShowClick(object sender, EventArgs e) {
462 private void removeMenuItem_Click(object sender, EventArgs e) {
463 MenuItem item = sender as MenuItem;
467 ISensor sensor = item.Parent.Tag as ISensor;
471 systemTray.Remove(sensor);
474 private void ShowParameterForm(ISensor sensor) {
475 ParameterForm form = new ParameterForm();
476 form.Parameters = sensor.Parameters;
477 form.captionLabel.Text = sensor.Name;
481 private void treeView_NodeMouseDoubleClick(object sender,
482 TreeNodeAdvMouseEventArgs e) {
483 SensorNode node = e.Node.Tag as SensorNode;
484 if (node != null && node.Sensor != null &&
485 node.Sensor.Parameters.Length > 0) {
486 ShowParameterForm(node.Sensor);
490 private void celciusMenuItem_Click(object sender, EventArgs e) {
491 celciusMenuItem.Checked = true;
492 fahrenheitMenuItem.Checked = false;
493 unitManager.TemperatureUnit = TemperatureUnit.Celcius;
496 private void fahrenheitMenuItem_Click(object sender, EventArgs e) {
497 celciusMenuItem.Checked = false;
498 fahrenheitMenuItem.Checked = true;
499 unitManager.TemperatureUnit = TemperatureUnit.Fahrenheit;
502 private void sumbitReportMenuItem_Click(object sender, EventArgs e)
504 ReportForm form = new ReportForm();
505 form.Report = computer.GetReport();
509 private void resetMinMaxMenuItem_Click(object sender, EventArgs e) {
510 computer.Accept(new SensorVisitor(delegate(ISensor sensor) {