JD2022-TU1/main/tools/legacy/PluginCommon/Controls/LongOperationDialog.cs

165 lines
4.9 KiB
C#

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;
using System.Threading;
namespace PluginCommon
{
// This is a dialog running a function in a separate thread and displaying a log.
// It should be displayed as modal.
public partial class LongOperationDialog : Form
{
public delegate void OnFinishedCallback(int _result);
private readonly object m_longOpLock = new object();
private Thread m_longOpThread = null;
private ThreadStart m_threadFunction = null;
private OnFinishedCallback m_onFinished = null;
private bool m_longOpFinished = false;
private int m_longOpErrorCode = 0;
private string m_unflushedLog = "";
private readonly bool m_autoClose = true;
// _autoClose: Automatically close the dialog at the end.
// NB: The dialog won't be automatically closed if m_longOpResult is different from zero.
public LongOperationDialog(bool _autoClose = true)
{
InitializeComponent();
StartPosition = FormStartPosition.Manual;
m_autoClose = _autoClose;
}
public DialogResult ShowDialog(ThreadStart _func, OnFinishedCallback _afterCallback)
{
m_threadFunction = _func;
m_onFinished = _afterCallback;
return ShowDialog();
}
public DialogResult ShowDialog(IWin32Window _owner, ThreadStart _func, OnFinishedCallback _afterCallback)
{
m_threadFunction = _func;
m_onFinished = _afterCallback;
return ShowDialog(_owner);
}
private void LongOperationDialog_Shown(object sender, EventArgs e)
{
lock (m_longOpLock)
{
LogLine("======= Start ========");
UseWaitCursor = true;
Text = "Busy...";
m_longOpFinished = false;
Cursor.Current = Cursors.WaitCursor;
m_longOpThread = new Thread(m_threadFunction);
m_longOpThread.Start();
}
}
public void FinishLongOp()
{
lock (m_longOpLock)
{
m_longOpFinished = true;
}
}
private bool IsFinished()
{
lock (m_longOpLock)
{
return m_longOpFinished;
}
}
public void SetLongOpErrorCode(int _res)
{
lock (m_longOpLock)
{
m_longOpErrorCode = _res;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
lock (m_longOpLock)
{
FlushLog();
// CheckBox that the thread didn't crash
if (m_longOpThread != null && !m_longOpThread.IsAlive && !m_longOpFinished)
{
m_longOpFinished = true;
m_longOpErrorCode = (m_longOpErrorCode == 0) ? -1 : m_longOpErrorCode;
}
if (m_longOpFinished && m_longOpThread != null)
{
m_longOpThread = null;
if (m_onFinished != null)
m_onFinished(m_longOpErrorCode);
m_threadFunction = null;
m_onFinished = null;
if (m_longOpErrorCode == 0)
LogLine("====== Finished ======");
else
LogLine("======= ERROR ========");
FlushLog();
UseWaitCursor = false;
Text = "Operation finished";
if (m_autoClose && m_longOpErrorCode == 0)
Close();
}
}
}
public void LogLine(string _line)
{
lock (m_longOpLock)
{
m_unflushedLog += _line + "\r\n";
}
}
// Make sure m_longOpLock is locked before calling this
private void FlushLog()
{
logTextBox.Text += m_unflushedLog;
m_unflushedLog = "";
}
private void LongOperationDialog_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = !IsFinished();
}
private void LongOperationDialog_Load(object sender, EventArgs e)
{
Location = new Point(Owner.Location.X + (Owner.Width - Width) / 2, Owner.Location.Y + (Owner.Height- Height) / 2);
}
private void animTimer_Tick(object sender, EventArgs e)
{
if (!IsFinished())
{
int length = Text.Length;
if (length < 7)
Text += '.';
else
Text = "Busy";
}
}
}
}