using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; namespace TeslaConsole; public class PodActionDialog : Form { private delegate void ActionCompleted(); private class ActionItem { private readonly PodInfo mPodInfo; private readonly Action mAction; private readonly ActionCompleted mActionCompleted; private readonly ListViewItem rListViewItem; private bool mDone; private bool mCanceled; private bool mError; public ListViewItem ListViewItem => rListViewItem; public bool Done { get { return mDone; } set { if (!mDone && value) { mDone = true; mActionCompleted(); } } } public bool Canceled { get { return mCanceled; } set { if (!mDone && !mCanceled && value) { mCanceled = true; Done = true; } } } public bool Error => mError; public ActionItem(PodInfo podInfo, Action action, ActionCompleted complete) { mPodInfo = podInfo; mAction = action; mActionCompleted = complete; rListViewItem = new ListViewItem(new string[2] { mPodInfo.Pod.Name, "Connecting..." }); } public void Begin() { mPodInfo.EnqueueConnectAction(DoAction); } private void DoAction(PodInfo pod) { if (!mCanceled) { try { mAction(pod); } catch (Exception ex) { rListViewItem.SubItems[1].Text = ex.Message; mError = true; } if (!mError) { rListViewItem.SubItems[1].Text = "Complete"; } Done = true; } } } private IContainer components; private Button mCancel; private ListView mActionList; private ColumnHeader mPodColumn; private ColumnHeader mStatusColumn; private readonly List mActionItems = new List(); private bool mDone; private bool mError; protected override void Dispose(bool disposing) { if (disposing && components != null) { components.Dispose(); } base.Dispose(disposing); } private void InitializeComponent() { this.mCancel = new System.Windows.Forms.Button(); this.mActionList = new System.Windows.Forms.ListView(); this.mPodColumn = new System.Windows.Forms.ColumnHeader(); this.mStatusColumn = new System.Windows.Forms.ColumnHeader(); base.SuspendLayout(); this.mCancel.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right; this.mCancel.Location = new System.Drawing.Point(377, 247); this.mCancel.Name = "mCancel"; this.mCancel.Size = new System.Drawing.Size(75, 23); this.mCancel.TabIndex = 0; this.mCancel.Text = "Cancel"; this.mCancel.UseVisualStyleBackColor = true; this.mCancel.Click += new System.EventHandler(mCancel_Click); this.mActionList.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; this.mActionList.Columns.AddRange(new System.Windows.Forms.ColumnHeader[2] { this.mPodColumn, this.mStatusColumn }); this.mActionList.GridLines = true; this.mActionList.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; this.mActionList.Location = new System.Drawing.Point(12, 12); this.mActionList.MultiSelect = false; this.mActionList.Name = "mActionList"; this.mActionList.Size = new System.Drawing.Size(440, 229); this.mActionList.TabIndex = 1; this.mActionList.UseCompatibleStateImageBehavior = false; this.mActionList.View = System.Windows.Forms.View.Details; this.mPodColumn.Text = "Pod"; this.mPodColumn.Width = 300; this.mStatusColumn.Text = "Status"; this.mStatusColumn.Width = 120; base.AutoScaleDimensions = new System.Drawing.SizeF(6f, 13f); base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; base.ClientSize = new System.Drawing.Size(464, 282); base.Controls.Add(this.mActionList); base.Controls.Add(this.mCancel); base.Name = "PodActionDialog"; this.Text = "Performing Action..."; base.ResumeLayout(false); } public static void Show(ICollection pods, Action action, string title) { if (pods.Count > 0) { PodActionDialog podActionDialog = new PodActionDialog(pods, action, title); if (!podActionDialog.IsDisposed) { podActionDialog.Show(); } } } private PodActionDialog() { InitializeComponent(); } private PodActionDialog(IEnumerable pods, Action action, string title) : this() { Text = title; foreach (PodInfo pod in pods) { ActionItem actionItem = new ActionItem(pod, action, ItemDone); mActionItems.Add(actionItem); mActionList.Items.Add(actionItem.ListViewItem); } foreach (ActionItem mActionItem in mActionItems) { mActionItem.Begin(); } if (mActionItems.Count < 1) { ItemDone(); } } private void ItemDone() { if (mDone) { return; } foreach (ActionItem mActionItem in mActionItems) { if (!mActionItem.Done) { return; } if (mActionItem.Error) { mError = true; } } mDone = true; if (!mError) { Close(); } else { mCancel.Text = "OK"; } } private void mCancel_Click(object sender, EventArgs e) { Close(); } protected override void OnClosing(CancelEventArgs e) { if (!mDone) { if (MessageBox.Show("Are you sure you wish to cancel this action?", "Cancel?", MessageBoxButtons.YesNoCancel) == DialogResult.Yes) { foreach (ActionItem mActionItem in mActionItems) { mActionItem.Canceled = true; } } e.Cancel = true; } else { base.OnClosing(e); } } }