moel@1: /* moel@344: moel@344: This Source Code Form is subject to the terms of the Mozilla Public moel@344: License, v. 2.0. If a copy of the MPL was not distributed with this moel@344: file, You can obtain one at http://mozilla.org/MPL/2.0/. moel@344: moel@344: Copyright (C) 2009-2012 Michael Möller moel@344: Copyright (C) 2010 Paul Werelds moel@348: Copyright (C) 2012 Prince Samuel moel@1: moel@1: */ moel@1: moel@1: using System; moel@1: using System.Collections.Generic; moel@360: using System.Collections.ObjectModel; moel@1: using System.ComponentModel; moel@1: using System.Drawing; moel@83: using System.IO; moel@291: using System.Reflection; moel@1: using System.Windows.Forms; moel@1: using Aga.Controls.Tree; moel@1: using Aga.Controls.Tree.NodeControls; moel@1: using OpenHardwareMonitor.Hardware; paulwerelds@227: using OpenHardwareMonitor.WMI; moel@348: using OpenHardwareMonitor.Utilities; moel@1: moel@1: namespace OpenHardwareMonitor.GUI { moel@1: public partial class MainForm : Form { moel@1: moel@165: private PersistentSettings settings; moel@165: private UnitManager unitManager; moel@165: private Computer computer; moel@1: private Node root; moel@1: private TreeModel treeModel; moel@1: private IDictionary sensorPlotColors = moel@1: new Dictionary(); moel@1: private Color[] plotColorPalette; moel@133: private SystemTray systemTray; moel@82: private StartupManager startupManager = new StartupManager(); moel@110: private UpdateVisitor updateVisitor = new UpdateVisitor(); moel@176: private SensorGadget gadget; moel@295: private Form plotForm; moel@326: private PlotPanel plotPanel; moel@1: moel@156: private UserOption showHiddenSensors; moel@156: private UserOption showPlot; moel@156: private UserOption showValue; moel@156: private UserOption showMin; moel@156: private UserOption showMax; moel@156: private UserOption startMinimized; moel@156: private UserOption minimizeToTray; paulwerelds@198: private UserOption minimizeOnClose; moel@156: private UserOption autoStart; moel@360: moel@360: private UserOption readMainboardSensors; moel@360: private UserOption readCpuSensors; moel@370: private UserOption readRamSensors; moel@360: private UserOption readGpuSensors; moel@360: private UserOption readFanControllersSensors; moel@156: private UserOption readHddSensors; moel@360: moel@176: private UserOption showGadget; moel@295: private UserRadioGroup plotLocation; moel@348: private WmiProvider wmiProvider; paulwerelds@223: moel@348: private UserOption runWebServer; moel@348: private HttpServer server; moel@156: moel@288: private bool selectionDragging = false; moel@288: moel@28: public MainForm() { moel@1: InitializeComponent(); moel@156: moel@291: // check if the OpenHardwareMonitorLib assembly has the correct version moel@291: if (Assembly.GetAssembly(typeof(Computer)).GetName().Version != moel@291: Assembly.GetExecutingAssembly().GetName().Version) { moel@291: MessageBox.Show( moel@291: "The version of the file OpenHardwareMonitorLib.dll is incompatible.", moel@291: "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); moel@291: Environment.Exit(0); moel@291: } moel@291: moel@165: this.settings = new PersistentSettings(); moel@165: this.settings.Load(Path.ChangeExtension( paulwerelds@198: Application.ExecutablePath, ".config")); moel@165: moel@165: this.unitManager = new UnitManager(settings); moel@165: moel@304: // make sure the buffers used for double buffering are not disposed moel@304: // after each draw call moel@304: BufferedGraphicsManager.Current.MaximumBuffer = moel@304: Screen.PrimaryScreen.Bounds.Size; moel@304: moel@156: // set the DockStyle here, to avoid conflicts with the MainMenu moel@156: this.splitContainer.Dock = DockStyle.Fill; moel@202: moel@1: this.Font = SystemFonts.MessageBoxFont; moel@1: treeView.Font = SystemFonts.MessageBoxFont; moel@326: moel@326: plotPanel = new PlotPanel(settings); moel@326: plotPanel.Font = SystemFonts.MessageBoxFont; moel@326: plotPanel.Dock = DockStyle.Fill; moel@1: moel@133: nodeCheckBox.IsVisibleValueNeeded += nodeCheckBox_IsVisibleValueNeeded; moel@133: nodeTextBoxText.DrawText += nodeTextBoxText_DrawText; moel@133: nodeTextBoxValue.DrawText += nodeTextBoxText_DrawText; moel@133: nodeTextBoxMin.DrawText += nodeTextBoxText_DrawText; moel@133: nodeTextBoxMax.DrawText += nodeTextBoxText_DrawText; moel@141: nodeTextBoxText.EditorShowing += nodeTextBoxText_EditorShowing; moel@1: moel@113: foreach (TreeColumn column in treeView.Columns) moel@165: column.Width = Math.Max(20, Math.Min(400, moel@166: settings.GetValue("treeView.Columns." + column.Header + ".Width", moel@113: column.Width))); moel@113: moel@1: treeModel = new TreeModel(); moel@1: root = new Node(System.Environment.MachineName); moel@1: root.Image = Utilities.EmbeddedResources.GetImage("computer.png"); moel@1: moel@1: treeModel.Nodes.Add(root); moel@165: treeView.Model = treeModel; moel@40: moel@165: this.computer = new Computer(settings); moel@165: moel@362: systemTray = new SystemTray(computer, settings, unitManager); moel@133: systemTray.HideShowCommand += hideShowClick; moel@133: systemTray.ExitCommand += exitClick; moel@1: moel@202: int p = (int)Environment.OSVersion.Platform; moel@202: if ((p == 4) || (p == 128)) { // Unix moel@287: treeView.RowHeight = Math.Max(treeView.RowHeight, 18); moel@202: splitContainer.BorderStyle = BorderStyle.None; moel@202: splitContainer.Border3DStyle = Border3DStyle.Adjust; moel@202: splitContainer.SplitterWidth = 4; moel@202: treeView.BorderStyle = BorderStyle.Fixed3D; moel@202: plotPanel.BorderStyle = BorderStyle.Fixed3D; moel@202: gadgetMenuItem.Visible = false; moel@202: minCloseMenuItem.Visible = false; moel@269: minTrayMenuItem.Visible = false; moel@269: startMinMenuItem.Visible = false; moel@202: } else { // Windows moel@287: treeView.RowHeight = Math.Max(treeView.Font.Height + 1, 18); moel@267: moel@202: gadget = new SensorGadget(computer, settings, unitManager); moel@244: gadget.HideShowCommand += hideShowClick; moel@244: moel@232: wmiProvider = new WmiProvider(computer); moel@327: } moel@86: moel@111: plotColorPalette = new Color[13]; moel@1: plotColorPalette[0] = Color.Blue; moel@1: plotColorPalette[1] = Color.OrangeRed; moel@1: plotColorPalette[2] = Color.Green; moel@1: plotColorPalette[3] = Color.LightSeaGreen; moel@1: plotColorPalette[4] = Color.Goldenrod; moel@1: plotColorPalette[5] = Color.DarkViolet; moel@1: plotColorPalette[6] = Color.YellowGreen; moel@1: plotColorPalette[7] = Color.SaddleBrown; moel@111: plotColorPalette[8] = Color.RoyalBlue; moel@111: plotColorPalette[9] = Color.DeepPink; moel@111: plotColorPalette[10] = Color.MediumSeaGreen; moel@111: plotColorPalette[11] = Color.Olive; moel@111: plotColorPalette[12] = Color.Firebrick; moel@327: moel@327: computer.HardwareAdded += new HardwareEventHandler(HardwareAdded); moel@327: computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved); moel@327: moel@327: computer.Open(); moel@327: moel@327: timer.Enabled = true; moel@1: paulwerelds@223: showHiddenSensors = new UserOption("hiddenMenuItem", false, paulwerelds@223: hiddenMenuItem, settings); moel@156: showHiddenSensors.Changed += delegate(object sender, EventArgs e) { moel@156: treeModel.ForceVisible = showHiddenSensors.Value; moel@156: }; moel@111: paulwerelds@223: showValue = new UserOption("valueMenuItem", true, valueMenuItem, paulwerelds@223: settings); moel@156: showValue.Changed += delegate(object sender, EventArgs e) { moel@156: treeView.Columns[1].IsVisible = showValue.Value; moel@156: }; moel@122: moel@165: showMin = new UserOption("minMenuItem", false, minMenuItem, settings); moel@156: showMin.Changed += delegate(object sender, EventArgs e) { moel@156: treeView.Columns[2].IsVisible = showMin.Value; moel@156: }; moel@156: moel@165: showMax = new UserOption("maxMenuItem", true, maxMenuItem, settings); moel@156: showMax.Changed += delegate(object sender, EventArgs e) { moel@156: treeView.Columns[3].IsVisible = showMax.Value; moel@156: }; moel@156: paulwerelds@223: startMinimized = new UserOption("startMinMenuItem", false, paulwerelds@223: startMinMenuItem, settings); moel@156: paulwerelds@223: minimizeToTray = new UserOption("minTrayMenuItem", true, paulwerelds@223: minTrayMenuItem, settings); moel@156: minimizeToTray.Changed += delegate(object sender, EventArgs e) { moel@156: systemTray.IsMainIconEnabled = minimizeToTray.Value; moel@156: }; moel@156: paulwerelds@223: minimizeOnClose = new UserOption("minCloseMenuItem", false, paulwerelds@223: minCloseMenuItem, settings); paulwerelds@198: paulwerelds@223: autoStart = new UserOption(null, startupManager.Startup, paulwerelds@223: startupMenuItem, settings); moel@156: autoStart.Changed += delegate(object sender, EventArgs e) { moel@185: try { moel@185: startupManager.Startup = autoStart.Value; moel@185: } catch (InvalidOperationException) { moel@185: MessageBox.Show("Updating the auto-startup option failed.", "Error", moel@185: MessageBoxButtons.OK, MessageBoxIcon.Error); moel@185: autoStart.Value = startupManager.Startup; moel@185: } moel@156: }; moel@156: moel@360: readMainboardSensors = new UserOption("mainboardMenuItem", true, moel@360: mainboardMenuItem, settings); moel@360: readMainboardSensors.Changed += delegate(object sender, EventArgs e) { moel@360: computer.MainboardEnabled = readMainboardSensors.Value; moel@360: }; moel@360: moel@360: readCpuSensors = new UserOption("cpuMenuItem", true, moel@360: cpuMenuItem, settings); moel@360: readCpuSensors.Changed += delegate(object sender, EventArgs e) { moel@360: computer.CPUEnabled = readCpuSensors.Value; moel@360: }; moel@360: moel@370: readRamSensors = new UserOption("ramMenuItem", true, moel@370: ramMenuItem, settings); moel@370: readRamSensors.Changed += delegate(object sender, EventArgs e) { moel@370: computer.RAMEnabled = readRamSensors.Value; moel@370: }; moel@370: moel@360: readGpuSensors = new UserOption("gpuMenuItem", true, moel@360: gpuMenuItem, settings); moel@360: readGpuSensors.Changed += delegate(object sender, EventArgs e) { moel@360: computer.GPUEnabled = readGpuSensors.Value; moel@360: }; moel@360: moel@360: readFanControllersSensors = new UserOption("fanControllerMenuItem", true, moel@360: fanControllerMenuItem, settings); moel@360: readFanControllersSensors.Changed += delegate(object sender, EventArgs e) { moel@360: computer.FanControllerEnabled = readFanControllersSensors.Value; moel@360: }; moel@360: paulwerelds@223: readHddSensors = new UserOption("hddMenuItem", true, hddMenuItem, paulwerelds@223: settings); moel@156: readHddSensors.Changed += delegate(object sender, EventArgs e) { moel@156: computer.HDDEnabled = readHddSensors.Value; moel@156: }; moel@156: paulwerelds@223: showGadget = new UserOption("gadgetMenuItem", false, gadgetMenuItem, paulwerelds@223: settings); moel@176: showGadget.Changed += delegate(object sender, EventArgs e) { moel@202: if (gadget != null) moel@202: gadget.Visible = showGadget.Value; moel@176: }; moel@176: moel@299: celsiusMenuItem.Checked = moel@299: unitManager.TemperatureUnit == TemperatureUnit.Celsius; moel@299: fahrenheitMenuItem.Checked = !celsiusMenuItem.Checked; moel@55: moel@348: server = new HttpServer(root, this.settings.GetValue("listenerPort", 8085)); moel@348: runWebServer = new UserOption("runWebServerMenuItem", false, moel@348: runWebServerMenuItem, settings); moel@360: runWebServer.Changed += delegate(object sender, EventArgs e) { moel@360: if (runWebServer.Value) moel@360: runWebServer.Value = server.startHTTPListener(); moel@360: else moel@360: server.stopHTTPListener(); moel@348: }; moel@348: moel@295: InitializePlotForm(); moel@295: moel@142: startupMenuItem.Visible = startupManager.IsAvailable; moel@125: moel@55: if (startMinMenuItem.Checked) { moel@82: if (!minTrayMenuItem.Checked) { moel@55: WindowState = FormWindowState.Minimized; moel@55: Show(); moel@55: } moel@55: } else { moel@55: Show(); moel@55: } moel@70: moel@71: // Create a handle, otherwise calling Close() does not fire FormClosed moel@71: IntPtr handle = Handle; moel@128: moel@128: // Make sure the settings are saved when the user logs off paulwerelds@223: Microsoft.Win32.SystemEvents.SessionEnded += delegate { moel@380: computer.Close(); paulwerelds@223: SaveConfiguration(); moel@348: if (runWebServer.Value) moel@348: server.Quit(); moel@348: moel@304: }; moel@1: } moel@295: moel@295: private void InitializePlotForm() { moel@295: plotForm = new Form(); moel@295: plotForm.FormBorderStyle = FormBorderStyle.SizableToolWindow; moel@295: plotForm.ShowInTaskbar = false; moel@295: plotForm.StartPosition = FormStartPosition.Manual; moel@295: this.AddOwnedForm(plotForm); moel@295: plotForm.Bounds = new Rectangle { moel@295: X = settings.GetValue("plotForm.Location.X", -100000), moel@295: Y = settings.GetValue("plotForm.Location.Y", 100), moel@295: Width = settings.GetValue("plotForm.Width", 600), moel@295: Height = settings.GetValue("plotForm.Height", 400) moel@295: }; moel@295: moel@295: showPlot = new UserOption("plotMenuItem", false, plotMenuItem, settings); moel@295: plotLocation = new UserRadioGroup("plotLocation", 0, moel@295: new[] { plotWindowMenuItem, plotBottomMenuItem, plotRightMenuItem }, moel@295: settings); moel@295: moel@295: showPlot.Changed += delegate(object sender, EventArgs e) { moel@295: if (plotLocation.Value == 0) { moel@295: if (showPlot.Value && this.Visible) moel@295: plotForm.Show(); moel@295: else moel@295: plotForm.Hide(); moel@295: } else { moel@295: splitContainer.Panel2Collapsed = !showPlot.Value; moel@295: } moel@295: treeView.Invalidate(); moel@295: }; moel@295: plotLocation.Changed += delegate(object sender, EventArgs e) { moel@295: switch (plotLocation.Value) { moel@295: case 0: moel@295: splitContainer.Panel2.Controls.Clear(); moel@295: splitContainer.Panel2Collapsed = true; moel@295: plotForm.Controls.Add(plotPanel); moel@295: if (showPlot.Value && this.Visible) moel@295: plotForm.Show(); moel@295: break; moel@295: case 1: moel@295: plotForm.Controls.Clear(); moel@295: plotForm.Hide(); moel@295: splitContainer.Orientation = Orientation.Horizontal; moel@295: splitContainer.Panel2.Controls.Add(plotPanel); moel@295: splitContainer.Panel2Collapsed = !showPlot.Value; moel@295: break; moel@295: case 2: moel@295: plotForm.Controls.Clear(); moel@295: plotForm.Hide(); moel@295: splitContainer.Orientation = Orientation.Vertical; moel@295: splitContainer.Panel2.Controls.Add(plotPanel); moel@295: splitContainer.Panel2Collapsed = !showPlot.Value; moel@295: break; moel@295: } moel@295: }; moel@297: moel@297: plotForm.FormClosing += delegate(object sender, FormClosingEventArgs e) { moel@297: if (e.CloseReason == CloseReason.UserClosing) { moel@297: // just switch off the plotting when the user closes the form moel@297: if (plotLocation.Value == 0) { moel@297: showPlot.Value = false; moel@297: } moel@297: e.Cancel = true; moel@295: } moel@295: }; moel@297: moel@295: EventHandler moveOrResizePlotForm = delegate(object sender, EventArgs e) { moel@295: if (plotForm.WindowState != FormWindowState.Minimized) { moel@295: settings.SetValue("plotForm.Location.X", plotForm.Bounds.X); moel@295: settings.SetValue("plotForm.Location.Y", plotForm.Bounds.Y); moel@295: settings.SetValue("plotForm.Width", plotForm.Bounds.Width); moel@295: settings.SetValue("plotForm.Height", plotForm.Bounds.Height); moel@295: } moel@295: }; moel@295: plotForm.Move += moveOrResizePlotForm; moel@295: plotForm.Resize += moveOrResizePlotForm; moel@295: moel@295: plotForm.VisibleChanged += delegate(object sender, EventArgs e) { moel@295: Rectangle bounds = new Rectangle(plotForm.Location, plotForm.Size); moel@295: Screen screen = Screen.FromRectangle(bounds); moel@295: Rectangle intersection = moel@295: Rectangle.Intersect(screen.WorkingArea, bounds); moel@295: if (intersection.Width < Math.Min(16, bounds.Width) || moel@295: intersection.Height < Math.Min(16, bounds.Height)) { moel@295: plotForm.Location = new Point( moel@295: screen.WorkingArea.Width / 2 - bounds.Width / 2, moel@295: screen.WorkingArea.Height / 2 - bounds.Height / 2); moel@295: } moel@295: }; moel@295: moel@295: this.VisibleChanged += delegate(object sender, EventArgs e) { moel@295: if (this.Visible && showPlot.Value && plotLocation.Value == 0) moel@295: plotForm.Show(); moel@295: else moel@295: plotForm.Hide(); moel@295: }; moel@295: } moel@360: moel@360: private void InsertSorted(Collection nodes, HardwareNode node) { moel@360: int i = 0; moel@360: while (i < nodes.Count && nodes[i] is HardwareNode && moel@360: ((HardwareNode)nodes[i]).Hardware.HardwareType < moel@360: node.Hardware.HardwareType) moel@360: i++; moel@360: nodes.Insert(i, node); moel@360: } moel@128: moel@64: private void SubHardwareAdded(IHardware hardware, Node node) { moel@327: HardwareNode hardwareNode = moel@327: new HardwareNode(hardware, settings, unitManager); moel@327: hardwareNode.PlotSelectionChanged += PlotSelectionChanged; moel@327: moel@360: InsertSorted(node.Nodes, hardwareNode); moel@360: moel@64: foreach (IHardware subHardware in hardware.SubHardware) moel@64: SubHardwareAdded(subHardware, hardwareNode); moel@64: } moel@64: moel@327: private void HardwareAdded(IHardware hardware) { moel@327: SubHardwareAdded(hardware, root); moel@327: PlotSelectionChanged(this, null); moel@1: } moel@1: moel@327: private void HardwareRemoved(IHardware hardware) { moel@327: List nodesToRemove = new List(); moel@28: foreach (Node node in root.Nodes) { moel@28: HardwareNode hardwareNode = node as HardwareNode; moel@28: if (hardwareNode != null && hardwareNode.Hardware == hardware) moel@327: nodesToRemove.Add(hardwareNode); moel@28: } moel@327: foreach (HardwareNode hardwareNode in nodesToRemove) { moel@327: root.Nodes.Remove(hardwareNode); moel@327: hardwareNode.PlotSelectionChanged -= PlotSelectionChanged; moel@327: } moel@327: PlotSelectionChanged(this, null); moel@1: } moel@1: moel@111: private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) { moel@111: Node node = e.Node.Tag as Node; moel@111: if (node != null) { moel@1: Color color; moel@111: if (node.IsVisible) { moel@111: SensorNode sensorNode = node as SensorNode; moel@111: if (plotMenuItem.Checked && sensorNode != null && moel@111: sensorPlotColors.TryGetValue(sensorNode.Sensor, out color)) moel@111: e.TextColor = color; moel@111: } else { moel@111: e.TextColor = Color.DarkGray; moel@111: } moel@1: } moel@1: } moel@1: moel@327: private void PlotSelectionChanged(object sender, EventArgs e) { moel@1: List selected = new List(); moel@1: IDictionary colors = new Dictionary(); moel@1: int colorIndex = 0; moel@1: foreach (TreeNodeAdv node in treeView.AllNodes) { moel@1: SensorNode sensorNode = node.Tag as SensorNode; moel@327: if (sensorNode != null && moel@1: sensorNode.Sensor.SensorType == SensorType.Temperature) { moel@1: if (sensorNode.Plot) { moel@1: colors.Add(sensorNode.Sensor, moel@1: plotColorPalette[colorIndex % plotColorPalette.Length]); moel@1: selected.Add(sensorNode.Sensor); moel@1: } moel@1: colorIndex++; moel@1: } moel@1: } moel@1: sensorPlotColors = colors; moel@1: plotPanel.SetSensors(selected, colors); moel@1: } moel@1: paulwerelds@223: private void nodeTextBoxText_EditorShowing(object sender, paulwerelds@223: CancelEventArgs e) moel@141: { moel@141: e.Cancel = !(treeView.CurrentNode != null && moel@275: (treeView.CurrentNode.Tag is SensorNode || moel@275: treeView.CurrentNode.Tag is HardwareNode)); moel@141: } moel@141: moel@1: private void nodeCheckBox_IsVisibleValueNeeded(object sender, moel@1: NodeControlValueEventArgs e) { moel@1: SensorNode node = e.Node.Tag as SensorNode; moel@1: e.Value = (node != null) && moel@1: (node.Sensor.SensorType == SensorType.Temperature) && moel@1: plotMenuItem.Checked; moel@1: } moel@1: moel@133: private void exitClick(object sender, EventArgs e) { paulwerelds@198: Close(); moel@1: } moel@1: moel@86: private void timer_Tick(object sender, EventArgs e) { moel@110: computer.Accept(updateVisitor); moel@1: treeView.Invalidate(); moel@1: plotPanel.Invalidate(); paulwerelds@223: systemTray.Redraw(); moel@202: if (gadget != null) moel@202: gadget.Redraw(); paulwerelds@223: paulwerelds@223: if (wmiProvider != null) paulwerelds@223: wmiProvider.Update(); moel@1: } moel@1: moel@128: private void SaveConfiguration() { moel@128: foreach (TreeColumn column in treeView.Columns) moel@166: settings.SetValue("treeView.Columns." + column.Header + ".Width", moel@113: column.Width); moel@113: moel@348: this.settings.SetValue("listenerPort", server.ListenerPort); moel@348: moel@212: string fileName = Path.ChangeExtension( moel@212: System.Windows.Forms.Application.ExecutablePath, ".config"); moel@212: try { moel@212: settings.Save(fileName); moel@212: } catch (UnauthorizedAccessException) { paulwerelds@214: MessageBox.Show("Access to the path '" + fileName + "' is denied. " + moel@284: "The current settings could not be saved.", moel@284: "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); moel@284: } catch (IOException) { moel@284: MessageBox.Show("The path '" + fileName + "' is not writeable. " + moel@284: "The current settings could not be saved.", moel@212: "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); moel@212: } moel@128: } moel@128: paulwerelds@214: private void MainForm_Load(object sender, EventArgs e) { paulwerelds@214: Rectangle newBounds = new Rectangle { paulwerelds@214: X = settings.GetValue("mainForm.Location.X", Location.X), paulwerelds@214: Y = settings.GetValue("mainForm.Location.Y", Location.Y), paulwerelds@214: Width = settings.GetValue("mainForm.Width", 470), paulwerelds@214: Height = settings.GetValue("mainForm.Height", 640) paulwerelds@214: }; paulwerelds@214: paulwerelds@223: Rectangle fullWorkingArea = new Rectangle(int.MaxValue, int.MaxValue, paulwerelds@214: int.MinValue, int.MinValue); paulwerelds@214: paulwerelds@214: foreach (Screen screen in Screen.AllScreens) paulwerelds@223: fullWorkingArea = Rectangle.Union(fullWorkingArea, screen.Bounds); paulwerelds@214: paulwerelds@223: Rectangle intersection = Rectangle.Intersect(fullWorkingArea, newBounds); paulwerelds@214: if (intersection.Width < 20 || intersection.Height < 20 || paulwerelds@214: !settings.Contains("mainForm.Location.X") paulwerelds@214: ) { paulwerelds@214: newBounds.X = (Screen.PrimaryScreen.WorkingArea.Width / 2) - paulwerelds@214: (newBounds.Width/2); paulwerelds@214: paulwerelds@214: newBounds.Y = (Screen.PrimaryScreen.WorkingArea.Height / 2) - paulwerelds@214: (newBounds.Height / 2); paulwerelds@214: } paulwerelds@214: paulwerelds@214: this.Bounds = newBounds; paulwerelds@214: } paulwerelds@214: paulwerelds@214: private void MainForm_FormClosed(object sender, FormClosedEventArgs e) { moel@298: Visible = false; moel@262: systemTray.IsMainIconEnabled = false; moel@262: timer.Enabled = false; moel@28: computer.Close(); moel@298: SaveConfiguration(); moel@348: if (runWebServer.Value) moel@348: server.Quit(); moel@262: systemTray.Dispose(); moel@1: } moel@1: moel@156: private void aboutMenuItem_Click(object sender, EventArgs e) { moel@1: new AboutBox().ShowDialog(); moel@1: } moel@1: moel@1: private void treeView_Click(object sender, EventArgs e) { moel@275: moel@1: MouseEventArgs m = e as MouseEventArgs; moel@1: if (m == null || m.Button != MouseButtons.Right) moel@1: return; moel@1: paulwerelds@223: NodeControlInfo info = treeView.GetNodeControlInfoAt( paulwerelds@223: new Point(m.X, m.Y) paulwerelds@223: ); moel@156: treeView.SelectedNode = info.Node; moel@156: if (info.Node != null) { moel@40: SensorNode node = info.Node.Tag as SensorNode; moel@40: if (node != null && node.Sensor != null) { moel@275: treeContextMenu.MenuItems.Clear(); moel@63: if (node.Sensor.Parameters.Length > 0) { moel@156: MenuItem item = new MenuItem("Parameters..."); moel@63: item.Click += delegate(object obj, EventArgs args) { moel@63: ShowParameterForm(node.Sensor); moel@63: }; moel@275: treeContextMenu.MenuItems.Add(item); moel@63: } moel@156: if (nodeTextBoxText.EditEnabled) { moel@156: MenuItem item = new MenuItem("Rename"); moel@141: item.Click += delegate(object obj, EventArgs args) { moel@156: nodeTextBoxText.BeginEdit(); moel@141: }; moel@275: treeContextMenu.MenuItems.Add(item); moel@176: } moel@111: if (node.IsVisible) { moel@156: MenuItem item = new MenuItem("Hide"); moel@111: item.Click += delegate(object obj, EventArgs args) { moel@111: node.IsVisible = false; moel@111: }; moel@275: treeContextMenu.MenuItems.Add(item); moel@111: } else { moel@156: MenuItem item = new MenuItem("Unhide"); moel@111: item.Click += delegate(object obj, EventArgs args) { moel@111: node.IsVisible = true; moel@111: }; moel@275: treeContextMenu.MenuItems.Add(item); moel@176: } moel@275: treeContextMenu.MenuItems.Add(new MenuItem("-")); moel@178: { moel@178: MenuItem item = new MenuItem("Show in Tray"); moel@178: item.Checked = systemTray.Contains(node.Sensor); moel@178: item.Click += delegate(object obj, EventArgs args) { moel@178: if (item.Checked) moel@178: systemTray.Remove(node.Sensor); moel@178: else moel@178: systemTray.Add(node.Sensor, true); moel@178: }; moel@275: treeContextMenu.MenuItems.Add(item); moel@178: } moel@211: if (gadget != null) { moel@178: MenuItem item = new MenuItem("Show in Gadget"); moel@178: item.Checked = gadget.Contains(node.Sensor); moel@178: item.Click += delegate(object obj, EventArgs args) { moel@178: if (item.Checked) { moel@178: gadget.Remove(node.Sensor); moel@178: } else { moel@178: gadget.Add(node.Sensor); moel@178: } moel@178: }; moel@275: treeContextMenu.MenuItems.Add(item); moel@178: } moel@247: if (node.Sensor.Control != null) { moel@275: treeContextMenu.MenuItems.Add(new MenuItem("-")); moel@247: IControl control = node.Sensor.Control; moel@247: MenuItem controlItem = new MenuItem("Control"); moel@247: MenuItem defaultItem = new MenuItem("Default"); moel@247: defaultItem.Checked = control.ControlMode == ControlMode.Default; moel@247: controlItem.MenuItems.Add(defaultItem); moel@247: defaultItem.Click += delegate(object obj, EventArgs args) { moel@247: control.SetDefault(); moel@247: }; moel@275: MenuItem manualItem = new MenuItem("Manual"); moel@247: controlItem.MenuItems.Add(manualItem); moel@247: manualItem.Checked = control.ControlMode == ControlMode.Software; moel@247: for (int i = 0; i <= 100; i += 5) { moel@247: if (i <= control.MaxSoftwareValue && moel@275: i >= control.MinSoftwareValue) { moel@247: MenuItem item = new MenuItem(i + " %"); moel@378: item.RadioCheck = true; moel@247: manualItem.MenuItems.Add(item); moel@247: item.Checked = control.ControlMode == ControlMode.Software && moel@247: Math.Round(control.SoftwareValue) == i; moel@247: int softwareValue = i; moel@247: item.Click += delegate(object obj, EventArgs args) { moel@247: control.SetSoftware(softwareValue); moel@247: }; moel@247: } moel@247: } moel@275: treeContextMenu.MenuItems.Add(controlItem); moel@247: } moel@176: moel@275: treeContextMenu.Show(treeView, new Point(m.X, m.Y)); moel@275: } moel@275: moel@275: HardwareNode hardwareNode = info.Node.Tag as HardwareNode; moel@275: if (hardwareNode != null && hardwareNode.Hardware != null) { moel@275: treeContextMenu.MenuItems.Clear(); moel@275: moel@275: if (nodeTextBoxText.EditEnabled) { moel@275: MenuItem item = new MenuItem("Rename"); moel@275: item.Click += delegate(object obj, EventArgs args) { moel@275: nodeTextBoxText.BeginEdit(); moel@275: }; moel@275: treeContextMenu.MenuItems.Add(item); moel@275: } moel@275: moel@275: treeContextMenu.Show(treeView, new Point(m.X, m.Y)); moel@40: } moel@40: } moel@1: } moel@1: moel@156: private void saveReportMenuItem_Click(object sender, EventArgs e) { moel@83: string report = computer.GetReport(); moel@83: if (saveFileDialog.ShowDialog() == DialogResult.OK) { moel@83: using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) { moel@83: w.Write(report); moel@83: } moel@83: } moel@1: } moel@1: moel@82: private void SysTrayHideShow() { moel@82: Visible = !Visible; moel@82: if (Visible) moel@82: Activate(); moel@27: } moel@27: moel@27: protected override void WndProc(ref Message m) { moel@27: const int WM_SYSCOMMAND = 0x112; moel@27: const int SC_MINIMIZE = 0xF020; paulwerelds@198: const int SC_CLOSE = 0xF060; paulwerelds@198: moel@156: if (minimizeToTray.Value && moel@335: m.Msg == WM_SYSCOMMAND && m.WParam.ToInt64() == SC_MINIMIZE) { moel@82: SysTrayHideShow(); moel@335: } else if (minimizeOnClose.Value && moel@335: m.Msg == WM_SYSCOMMAND && m.WParam.ToInt64() == SC_CLOSE) { paulwerelds@198: /* paulwerelds@198: * Apparently the user wants to minimize rather than close paulwerelds@198: * Now we still need to check if we're going to the tray or not paulwerelds@198: * paulwerelds@198: * Note: the correct way to do this would be to send out SC_MINIMIZE, paulwerelds@198: * but since the code here is so simple, paulwerelds@198: * that would just be a waste of time. paulwerelds@198: */ paulwerelds@198: if (minimizeToTray.Value) paulwerelds@198: SysTrayHideShow(); paulwerelds@198: else paulwerelds@198: WindowState = FormWindowState.Minimized; moel@27: } else { moel@27: base.WndProc(ref m); moel@27: } moel@27: } moel@27: moel@82: private void hideShowClick(object sender, EventArgs e) { moel@82: SysTrayHideShow(); moel@27: } moel@27: moel@63: private void ShowParameterForm(ISensor sensor) { moel@63: ParameterForm form = new ParameterForm(); moel@63: form.Parameters = sensor.Parameters; moel@63: form.captionLabel.Text = sensor.Name; moel@63: form.ShowDialog(); moel@63: } moel@63: moel@63: private void treeView_NodeMouseDoubleClick(object sender, moel@63: TreeNodeAdvMouseEventArgs e) { moel@63: SensorNode node = e.Node.Tag as SensorNode; moel@63: if (node != null && node.Sensor != null && moel@63: node.Sensor.Parameters.Length > 0) { moel@63: ShowParameterForm(node.Sensor); moel@63: } moel@63: } moel@82: moel@299: private void celsiusMenuItem_Click(object sender, EventArgs e) { moel@299: celsiusMenuItem.Checked = true; moel@156: fahrenheitMenuItem.Checked = false; moel@299: unitManager.TemperatureUnit = TemperatureUnit.Celsius; moel@122: } moel@122: moel@156: private void fahrenheitMenuItem_Click(object sender, EventArgs e) { moel@299: celsiusMenuItem.Checked = false; moel@156: fahrenheitMenuItem.Checked = true; moel@165: unitManager.TemperatureUnit = TemperatureUnit.Fahrenheit; moel@122: } moel@150: moel@156: private void sumbitReportMenuItem_Click(object sender, EventArgs e) moel@150: { moel@150: ReportForm form = new ReportForm(); moel@150: form.Report = computer.GetReport(); moel@150: form.ShowDialog(); moel@150: } moel@151: moel@151: private void resetMinMaxMenuItem_Click(object sender, EventArgs e) { moel@159: computer.Accept(new SensorVisitor(delegate(ISensor sensor) { moel@159: sensor.ResetMin(); moel@159: sensor.ResetMax(); moel@159: })); moel@151: } moel@241: moel@241: private void MainForm_MoveOrResize(object sender, EventArgs e) { moel@241: if (WindowState != FormWindowState.Minimized) { moel@241: settings.SetValue("mainForm.Location.X", Bounds.X); moel@241: settings.SetValue("mainForm.Location.Y", Bounds.Y); moel@241: settings.SetValue("mainForm.Width", Bounds.Width); moel@241: settings.SetValue("mainForm.Height", Bounds.Height); moel@241: } moel@241: } moel@262: moel@262: private void resetClick(object sender, EventArgs e) { moel@262: // disable the fallback MainIcon during reset, otherwise icon visibility moel@262: // might be lost moel@262: systemTray.IsMainIconEnabled = false; moel@262: computer.Close(); moel@262: computer.Open(); moel@262: // restore the MainIcon setting moel@262: systemTray.IsMainIconEnabled = minimizeToTray.Value; moel@262: } moel@287: moel@287: private void treeView_MouseMove(object sender, MouseEventArgs e) { moel@288: selectionDragging = selectionDragging & moel@288: (e.Button & (MouseButtons.Left | MouseButtons.Right)) > 0; moel@288: moel@288: if (selectionDragging) moel@288: treeView.SelectedNode = treeView.GetNodeAt(e.Location); moel@288: } moel@288: moel@288: private void treeView_MouseDown(object sender, MouseEventArgs e) { moel@288: selectionDragging = true; moel@288: } moel@288: moel@288: private void treeView_MouseUp(object sender, MouseEventArgs e) { moel@288: selectionDragging = false; moel@287: } moel@348: moel@348: private void serverPortMenuItem_Click(object sender, EventArgs e) { moel@348: new PortForm(this).ShowDialog(); moel@348: } moel@348: moel@348: public HttpServer Server { moel@348: get { return server; } moel@348: } moel@348: moel@1: } moel@1: }