view ServerMonitor/Forms/ServerSummaryForm.cs @ 12:d92176c5398a

Better display of schedule name.
author Brad Greco <brad@bgreco.net>
date Mon, 15 Apr 2019 19:24:55 -0400
parents 75ca86e0862c
children 7626b099aefd
line wrap: on
line source

using NAppUpdate.Framework;
using NAppUpdate.Framework.Sources;
using NAppUpdate.Framework.Tasks;
using ServerMonitorApp.Properties;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ServerMonitorApp
{
    public partial class ServerSummaryForm : Form
    {
        private readonly Dictionary<Server, ServerForm> serverForms = new Dictionary<Server, ServerForm>();
        private ServerMonitor monitor;

        public ServerSummaryForm()
        {
            InitializeComponent();
        }

        public void AlertServerForm(Check check)
        {
            bool existingForm = serverForms.ContainsKey(check.Server);
            ServerForm form = ShowServerForm(check.Server, false);
            Win32Helpers.FlashWindowEx(form);
            if (!existingForm)
            {
                form.ShowLog(check);
            }
        }

        public void ShowBalloon(CheckResult result)
        {
            string title = string.Format("{0}: {1} failed", result.Check.Server.Name, result.Check.Name);
            NotifyIcon.Tag = result;
            NotifyIcon.ShowBalloonTip(30000, title, result.Message, GetToolTipIcon(result.CheckStatus));
        }

        private void ServerSummaryForm_Load(object sender, EventArgs e)
        {
            Size size = Settings.Default.SummaryFormSize;
            if (size.Height > 0 && size.Width > 0)
                Size = size;

            Helpers.FormatImageButton(NewServerButton);
            Helpers.FormatImageButton(SettingsButton);
            monitor = new ServerMonitor(this);
            while (true)
            {
                try
                {
                    monitor.LoadServers();
                    break;
                }
                catch (Exception ex)
                {
                    DialogResult result = MessageBox.Show("Could not load servers. Please fix or delete the file " + monitor.ConfigFile + Environment.NewLine + Environment.NewLine
                        + "Error details:" + Environment.NewLine + ex.GetAllMessages(),
                        "Error loading servers", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
                    if (result == DialogResult.Cancel)
                    {
                        Environment.Exit(1);
                    }
                }
            }
            monitor.CheckStatusChanged += Monitor_CheckStatusChanged;
            RefreshDisplay();
            CollectPrivateKeyPasswords();
            CheckForUpdate();
        }

        private ServerForm ShowServerForm(Server server, bool activate = true)
        {
            bool isNewServer = false;
            if (server == null)
            {
                server = new Server();
                monitor.AddServer(server);
                isNewServer = true;
            }
            if (serverForms.TryGetValue(server, out ServerForm form))
            {
                if (activate)
                    form.Activate();
            }
            else
            {
                form = new ServerForm(monitor, server, isNewServer);
                serverForms[server] = form;
                form.FormClosing += ServerForm_FormClosing;
                form.Show(activate);
            }
            return form;
        }

        private void RefreshDisplay()
        {
            ServerPanel.Controls.Clear();
            foreach (Server server in monitor.Servers)
            {
                server.EnabledChanged -= Server_EnabledChanged;
                server.EnabledChanged += Server_EnabledChanged;
                ServerSummaryControl control = new ServerSummaryControl(server);
                control.ContextMenuStrip = ServerContextMenu;
                control.Click += ServerSummaryControl_Click;
                ServerPanel.Controls.Add(control);
            }
            UpdateIcon();
        }

        private void RefreshServer(Server server)
        {
            ServerPanel.Controls.Cast<ServerSummaryControl>().FirstOrDefault(c => c.Server == server).Refresh();
            UpdateIcon();
        }

        private void UpdateIcon()
        {
            CheckStatus status = monitor.Servers
                .Select(s => s.Enabled
                    ? s.Status
                    : s.KeyStatus == KeyStatus.NeedPassword ? CheckStatus.Warning : CheckStatus.Success)
                .DefaultIfEmpty(CheckStatus.Success)
                .Max();
            Icon = status.GetIcon();
            NotifyIcon.Icon = Icon;
        }

        private void CollectPrivateKeyPasswords()
        {
            List<string> triedKeys = new List<string>();
            foreach (Server server in monitor.Servers)
            {
                if (triedKeys.Contains(server.KeyFile))
                    continue;
                ServerForm.OpenPrivateKey(monitor, server, this);
                triedKeys.Add(server.KeyFile);
            }
        }

        private void Server_EnabledChanged(object sender, EventArgs e)
        {
            RefreshServer((Server)sender);
        }

        private void Monitor_CheckStatusChanged(object sender, CheckStatusChangedEventArgs e)
        {
            if (e.CheckResult != null)
            {
                RefreshServer(e.Check.Server);
            }
        }

        private ToolTipIcon GetToolTipIcon(CheckStatus status)
        {
            switch (status)
            {
                case CheckStatus.Error: return ToolTipIcon.Error;
                case CheckStatus.Warning: return ToolTipIcon.Warning;
                case CheckStatus.Information: return ToolTipIcon.Info;
                default: return ToolTipIcon.None;
            }
        }

        private void ServerSummaryControl_Click(object sender, EventArgs e)
        {
            ShowServerForm(((ServerSummaryControl)sender).Server);
        }

        private void ServerForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            ServerForm form = (ServerForm)sender;
            form.FormClosing -= ServerForm_FormClosing;
            Server server = form.Server;
            serverForms.Remove(form.Server);
            if (server.IsEmpty())
            {
                monitor.DeleteServer(server);
            }
            RefreshDisplay();
        }

        private void NewServerButton_Click(object sender, EventArgs e)
        {
            ShowServerForm(null);
        }

        private void ServerSummaryForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if ((e.CloseReason == CloseReason.None || e.CloseReason == CloseReason.UserClosing) && Settings.Default.HideToNotificationArea)
            {
                Hide();
                e.Cancel = true;
            }
        }

        private void SettingsButton_Click(object sender, EventArgs e)
        {
            new SettingsForm().Show();
        }

        private void NotifyIcon_BalloonTipClicked(object sender, EventArgs e)
        {
            CheckResult result = (CheckResult)(sender as NotifyIcon).Tag;
            ServerForm form = ShowServerForm(result.Check.Server);
            form.ShowLog(result.Check);
            form.WindowState = FormWindowState.Normal;
        }

        private void ServerContextMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            Server server = GetClickedServer((ContextMenuStrip)e.ClickedItem.Owner);
            if (e.ClickedItem == DeleteServerMenuItem)
            {
                ServerContextMenu.Close();
                DialogResult result = MessageBox.Show(
                    string.Format("The server \"{0}\" and its {1} {2} will be deleted.", server.Name, server.Checks.Count, server.Checks.Count == 1 ? "check" : "checks"),
                    "Delete server",
                    MessageBoxButtons.OKCancel,
                    MessageBoxIcon.Warning  );
                if (result == DialogResult.OK)
                {
                    monitor.DeleteServer(server);
                    RefreshDisplay();
                }
            }
            else if (e.ClickedItem == ToggleEnableServerMenuItem)
            {
                bool enable = ToggleEnableServerMenuItem.Text == "Enable";
                if (enable)
                {
                    ServerContextMenu.Close();
                    ServerForm.OpenPrivateKey(monitor, server, this);
                }
                server.Enabled = enable;
                RefreshDisplay();
            }
        }

        private void ServerContextMenu_Opening(object sender, CancelEventArgs e)
        {
            Server server = GetClickedServer((ContextMenuStrip)sender);
            ToggleEnableServerMenuItem.Text = server.Enabled ? "Disable" : "Enable";
        }

        private Server GetClickedServer(ContextMenuStrip menu)
        {
            return ((ServerSummaryControl)menu.SourceControl).Server;
        }

        private void ServerSummaryForm_ResizeEnd(object sender, EventArgs e)
        {
            Settings.Default.SummaryFormSize = Size;
            Settings.Default.Save();
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == Win32Helpers.WM_SHOWMONITOR)
                ShowWindow();
            base.WndProc(ref m);
        }

        private void NotifyIcon_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
                ShowWindow();
            else if (e.Button == MouseButtons.Right)
                NotificationIconMenu.Show();
        }

        private void ShowWindow()
        {
            if (WindowState == FormWindowState.Minimized)
                WindowState = FormWindowState.Normal;
            Show();
            TopMost = true;
            TopMost = false;
            Activate();
        }

        private void NotificationIconMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (e.ClickedItem == ShowServerMonitorMenuItem)
                ShowWindow();
            else if (e.ClickedItem == ExitMenuItem)
                Application.Exit();
        }

        private void CheckForUpdate()
        {
            //System.Threading.Thread.Sleep(5000);
            UpdateManager manager = UpdateManager.Instance;
            manager.ReinstateIfRestarted();
            manager.UpdateSource = new SimpleWebSource("https://www.bgreco.net/test/servermonitor.xml");
            if (manager.State == UpdateManager.UpdateProcessState.NotChecked)
                manager.BeginCheckForUpdates(CheckForUpdatesCallback, null);
        }

        private void CheckForUpdatesCallback(IAsyncResult result)
        {
            UpdateManager manager = UpdateManager.Instance;
            if (manager.UpdatesAvailable > 0)
            {
                GetUpdateInfo(out string version, out string _);
                if (Settings.Default.IgnoreUpdate != version)
                    Invoke((MethodInvoker)(() => UpdatePanel.Show()));
            }
        }

        private void PrepareUpdatesCallback(IAsyncResult result)
        {
            UpdateManager manager = UpdateManager.Instance;
            manager.EndCheckForUpdates(result);
            manager.ApplyUpdates(true);
        }

        private void UpdateLabel_Click(object sender, EventArgs e)
        {
            GetUpdateInfo(out string version, out string changeMessage);
            string message = "Server Monitor version {0} is available for download." + Environment.NewLine
                + Environment.NewLine
                + "What's new:" + Environment.NewLine
                + "{1}" + Environment.NewLine
                + Environment.NewLine
                + "Would you like to download and apply the update now?";
            using (UpdateDialog dialog = new UpdateDialog { Message = string.Format(message, version, changeMessage) })
            {
                DialogResult result = dialog.ShowDialog();
                if (dialog.Checked && result == DialogResult.Cancel)
                {
                    Settings.Default.IgnoreUpdate = version;
                    Settings.Default.Save();
                    UpdatePanel.Hide();
                }
                if (result != DialogResult.OK)
                    return;
            }
            UpdateManager.Instance.BeginPrepareUpdates(PrepareUpdatesCallback, null);
        }

        private void GetUpdateInfo(out string version, out string changeMessage)
        {
            string[] parts = UpdateManager.Instance.Tasks.First().Description.Split(new char[] { ':' }, 2);
            version = parts[0];
            changeMessage = parts[1];
        }
    }
}