using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using SmartInstitute.Client.Automation.Documents;
using SmartInstitute.ObjectModel;
using SmartInstitute.Automation.Commands.Framework;
using SmartInstitute.Client.Automation.Commands.Students;
using SmartInstitute.Automation.Commands.Students;
namespace SmartInstitute.Automation.Documents.MiscDocuments
{
public partial class SendReceiveUI : DocumentUIBase
{
/// <summary>
/// Return the students list from the document
/// </summary>
private IList<StudentModel> _Students
{
get { return (base.Document as SendReceiveDocument).Students; }
set { (base.Document as SendReceiveDocument).Students = value; }
}
public SendReceiveUI()
{
InitializeComponent();
}
internal override bool AcceptData(object data)
{
this._Students = data as IList<StudentModel>;
this.StartSendReceive();
return true;
}
private void StartSendReceive()
{
// Populate the listview with students
this.tasksListView.Items.Clear();
foreach (StudentModel student in this._Students)
{
ListViewItem item = new StudentListViewItem(student);
this.tasksListView.Items.Add(item);
}
// Initialize progress bar
this.progressBarControl.Maximum = this._Students.Count;
this.progressBarControl.Value = 0;
this.UpdateProgressStatus();
// Start background synchronization
worker.RunWorkerAsync();
}
private void SendReceiveUI_Load(object sender, EventArgs e)
{
this.StartSendReceive();
}
private void errorsListBox_DrawItem(object sender, DrawItemEventArgs e)
{
Rectangle bounds = e.Bounds;
bounds.Inflate(-4, -2);
float left = bounds.Left;
e.Graphics.FillRectangle(Brushes.White, e.Bounds);
if (e.State == DrawItemState.Focus
|| e.State == DrawItemState.Selected)
ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds);
e.Graphics.DrawImage(this.imageList1.Images[3], new PointF(left, bounds.Top));
left += this.imageList1.Images[3].Width;
RectangleF textBounds = new RectangleF( left, bounds.Top, bounds.Width, bounds.Height);
e.Graphics.DrawString(this.errorsListBox.Items[e.Index] as string,
this.errorsListBox.Font, Brushes.Black, textBounds);
e.Graphics.DrawLine(Pens.LightGray, e.Bounds.Left, e.Bounds.Bottom,
e.Bounds.Right, e.Bounds.Bottom);
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
// This method will run on a thread other than the UI thread.
// Be sure not to manipulate any Windows Forms controls created
// on the UI thread from this method.
this.BackgroundThreadWork();
}
/// <summary>
/// This method performs the background synchronization by synchronizing
/// each queued model for sending to the web service.
///
/// No UI Update from this function.
/// </summary>
private void BackgroundThreadWork()
{
foreach (StudentModel model in this._Students)
{
// Do the synchronization
try
{
// 1. Send changes
worker.ReportProgress((int)StudentListViewItem.StatusEnum.Sending, model);
ICommand saveCommand = new SaveStudentCommand(model.Profile);
saveCommand.Execute();
// 2. Receive changes
worker.ReportProgress((int)StudentListViewItem.StatusEnum.Receiving, model);
ICommand loadCommand = new LoadStudentDetailCommand(model.Profile.ID);
loadCommand.Execute();
// 3. Complete
model.IsDirty = false;
model.NotifyChange("Reloaded");
model.LastErrorInSave = string.Empty;
worker.ReportProgress((int)StudentListViewItem.StatusEnum.Completed, model);
}
catch (Exception x)
{
model.LastErrorInSave = x.Message;
worker.ReportProgress((int)StudentListViewItem.StatusEnum.Error, model);
}
}
}
private class StudentListViewItem : ListViewItem
{
public enum StatusEnum
{
Sending,
Receiving,
Completed,
Error
}
public StudentListViewItem.StatusEnum Status = StatusEnum.Sending;
public StudentModel Model;
public StudentListViewItem(StudentModel model)
: base(model.ToString(), 0)
{
this.Model = model;
this.Refresh();
base.SubItems.Add(new ListViewSubItem(this, model.ToString()));
base.SubItems.Add(new ListViewSubItem(this, ""));
}
public void Refresh()
{
if (this.Status == StatusEnum.Sending)
this.Sending();
else if (this.Status == StatusEnum.Receiving)
this.Receiving();
else if (this.Status == StatusEnum.Error)
this.Error();
else if (this.Status == StatusEnum.Completed)
this.Done();
}
public void Done()
{
base.ImageIndex = 1;
base.SubItems[1].Text = "Completed";
}
public void Error()
{
base.ImageIndex = 2;
base.SubItems[1].Text = "Error: " + this.Model.LastErrorInSave;
base.ToolTipText = base.SubItems[1].Text;
}
public void Sending()
{
if (base.SubItems.Count < 2)
base.SubItems.Add(new ListViewSubItem(this, "Sending..."));
else
base.SubItems[1].Text = "Sending...";
}
public void Receiving()
{
base.SubItems[1].Text = "Receiving...";
}
}
private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Find the list view item which is hosting the specified model
foreach (StudentListViewItem item in this.tasksListView.Items)
{
if (Object.ReferenceEquals(item.Model, e.UserState))
{
StudentModel model = e.UserState as StudentModel;
if ( null != model.LastErrorInSave && model.LastErrorInSave.Length > 0)
{
this.AddError(model.LastErrorInSave);
}
item.Status = (StudentListViewItem.StatusEnum)e.ProgressPercentage;
item.Refresh();
}
}
// Increase progress bar upon success/failure, but not for intermediate progress
if( (int)StudentListViewItem.StatusEnum.Completed == e.ProgressPercentage
|| (int)StudentListViewItem.StatusEnum.Error == e.ProgressPercentage )
this.progressBarControl.Increment(1);
this.UpdateProgressStatus();
}
private void UpdateProgressStatus()
{
this.statusLabel.Text = string.Format(this.statusLabel.Tag as string,
this.progressBarControl.Value, this.progressBarControl.Maximum);
}
private void AddError(string errorMsg)
{
this.errorsListBox.Items.Add(errorMsg);
}
}
}