diff --git a/VAR.Toolbox/UI/Tools/FrmWorkLog.Designer.cs b/VAR.Toolbox/UI/Tools/FrmWorkLog.Designer.cs new file mode 100644 index 0000000..1866127 --- /dev/null +++ b/VAR.Toolbox/UI/Tools/FrmWorkLog.Designer.cs @@ -0,0 +1,213 @@ +namespace VAR.Toolbox.UI.Tools +{ + partial class FrmWorkLog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.splitWindow = new System.Windows.Forms.SplitContainer(); + this.btnNextDay = new System.Windows.Forms.Button(); + this.btnPreviousDay = new System.Windows.Forms.Button(); + this.dtToday = new System.Windows.Forms.DateTimePicker(); + this.lsbWorkLog = new System.Windows.Forms.ListBox(); + this.dtEnd = new System.Windows.Forms.DateTimePicker(); + this.dtStart = new System.Windows.Forms.DateTimePicker(); + this.txtDescription = new System.Windows.Forms.TextBox(); + this.txtActivity = new System.Windows.Forms.TextBox(); + this.btnDelete = new System.Windows.Forms.Button(); + this.btnAdd = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.splitWindow)).BeginInit(); + this.splitWindow.Panel1.SuspendLayout(); + this.splitWindow.Panel2.SuspendLayout(); + this.splitWindow.SuspendLayout(); + this.SuspendLayout(); + // + // splitWindow + // + this.splitWindow.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitWindow.Location = new System.Drawing.Point(0, 0); + this.splitWindow.Name = "splitWindow"; + // + // splitWindow.Panel1 + // + this.splitWindow.Panel1.Controls.Add(this.btnNextDay); + this.splitWindow.Panel1.Controls.Add(this.btnPreviousDay); + this.splitWindow.Panel1.Controls.Add(this.dtToday); + this.splitWindow.Panel1.Controls.Add(this.lsbWorkLog); + // + // splitWindow.Panel2 + // + this.splitWindow.Panel2.Controls.Add(this.dtEnd); + this.splitWindow.Panel2.Controls.Add(this.dtStart); + this.splitWindow.Panel2.Controls.Add(this.txtDescription); + this.splitWindow.Panel2.Controls.Add(this.txtActivity); + this.splitWindow.Panel2.Controls.Add(this.btnDelete); + this.splitWindow.Panel2.Controls.Add(this.btnAdd); + this.splitWindow.Size = new System.Drawing.Size(721, 603); + this.splitWindow.SplitterDistance = 442; + this.splitWindow.TabIndex = 0; + // + // btnNextDay + // + this.btnNextDay.Location = new System.Drawing.Point(154, 33); + this.btnNextDay.Name = "btnNextDay"; + this.btnNextDay.Size = new System.Drawing.Size(33, 20); + this.btnNextDay.TabIndex = 2; + this.btnNextDay.Text = "->"; + this.btnNextDay.UseVisualStyleBackColor = true; + this.btnNextDay.Click += new System.EventHandler(this.btnNextDay_Click); + // + // btnPreviousDay + // + this.btnPreviousDay.Location = new System.Drawing.Point(3, 33); + this.btnPreviousDay.Name = "btnPreviousDay"; + this.btnPreviousDay.Size = new System.Drawing.Size(33, 20); + this.btnPreviousDay.TabIndex = 1; + this.btnPreviousDay.Text = "<-"; + this.btnPreviousDay.UseVisualStyleBackColor = true; + this.btnPreviousDay.Click += new System.EventHandler(this.btnPreviousDay_Click); + // + // dtToday + // + this.dtToday.CustomFormat = "yyyy/MM/dd"; + this.dtToday.Format = System.Windows.Forms.DateTimePickerFormat.Custom; + this.dtToday.Location = new System.Drawing.Point(42, 33); + this.dtToday.Name = "dtToday"; + this.dtToday.Size = new System.Drawing.Size(106, 20); + this.dtToday.TabIndex = 0; + this.dtToday.ValueChanged += new System.EventHandler(this.dtToday_ValueChanged); + // + // lsbWorkLog + // + this.lsbWorkLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lsbWorkLog.BackColor = System.Drawing.Color.Black; + this.lsbWorkLog.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lsbWorkLog.ForeColor = System.Drawing.Color.Gray; + this.lsbWorkLog.FormattingEnabled = true; + this.lsbWorkLog.Location = new System.Drawing.Point(3, 60); + this.lsbWorkLog.Name = "lsbWorkLog"; + this.lsbWorkLog.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; + this.lsbWorkLog.Size = new System.Drawing.Size(436, 537); + this.lsbWorkLog.TabIndex = 0; + this.lsbWorkLog.SelectedIndexChanged += new System.EventHandler(this.lsbWorkLog_SelectedIndexChanged); + // + // dtEnd + // + this.dtEnd.CustomFormat = "yyyy/MM/ddThh:mm:ss"; + this.dtEnd.Format = System.Windows.Forms.DateTimePickerFormat.Custom; + this.dtEnd.Location = new System.Drawing.Point(4, 60); + this.dtEnd.Name = "dtEnd"; + this.dtEnd.Size = new System.Drawing.Size(155, 20); + this.dtEnd.TabIndex = 5; + this.dtEnd.ValueChanged += new System.EventHandler(this.dtEnd_ValueChanged); + // + // dtStart + // + this.dtStart.CustomFormat = "yyyy/MM/ddThh:mm:ss"; + this.dtStart.Format = System.Windows.Forms.DateTimePickerFormat.Custom; + this.dtStart.Location = new System.Drawing.Point(4, 33); + this.dtStart.Name = "dtStart"; + this.dtStart.Size = new System.Drawing.Size(155, 20); + this.dtStart.TabIndex = 4; + this.dtStart.ValueChanged += new System.EventHandler(this.dtStart_ValueChanged); + // + // txtDescription + // + this.txtDescription.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtDescription.Location = new System.Drawing.Point(4, 119); + this.txtDescription.Multiline = true; + this.txtDescription.Name = "txtDescription"; + this.txtDescription.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this.txtDescription.Size = new System.Drawing.Size(259, 472); + this.txtDescription.TabIndex = 3; + this.txtDescription.TextChanged += new System.EventHandler(this.txtDescription_TextChanged); + // + // txtActivity + // + this.txtActivity.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtActivity.Location = new System.Drawing.Point(3, 93); + this.txtActivity.Name = "txtActivity"; + this.txtActivity.Size = new System.Drawing.Size(259, 20); + this.txtActivity.TabIndex = 2; + this.txtActivity.TextChanged += new System.EventHandler(this.txtActivity_TextChanged); + // + // btnDelete + // + this.btnDelete.Location = new System.Drawing.Point(84, 3); + this.btnDelete.Name = "btnDelete"; + this.btnDelete.Size = new System.Drawing.Size(75, 23); + this.btnDelete.TabIndex = 1; + this.btnDelete.Text = "Delete"; + this.btnDelete.UseVisualStyleBackColor = true; + this.btnDelete.Click += new System.EventHandler(this.btnDelete_Click); + // + // btnAdd + // + this.btnAdd.Location = new System.Drawing.Point(3, 3); + this.btnAdd.Name = "btnAdd"; + this.btnAdd.Size = new System.Drawing.Size(75, 23); + this.btnAdd.TabIndex = 0; + this.btnAdd.Text = "Add"; + this.btnAdd.UseVisualStyleBackColor = true; + this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click); + // + // FrmWorkLog + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(721, 603); + this.Controls.Add(this.splitWindow); + this.Name = "FrmWorkLog"; + this.Text = "WorkLog"; + this.splitWindow.Panel1.ResumeLayout(false); + this.splitWindow.Panel2.ResumeLayout(false); + this.splitWindow.Panel2.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitWindow)).EndInit(); + this.splitWindow.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.SplitContainer splitWindow; + private System.Windows.Forms.DateTimePicker dtToday; + private System.Windows.Forms.ListBox lsbWorkLog; + private System.Windows.Forms.TextBox txtDescription; + private System.Windows.Forms.TextBox txtActivity; + private System.Windows.Forms.Button btnDelete; + private System.Windows.Forms.Button btnAdd; + private System.Windows.Forms.DateTimePicker dtEnd; + private System.Windows.Forms.DateTimePicker dtStart; + private System.Windows.Forms.Button btnNextDay; + private System.Windows.Forms.Button btnPreviousDay; + } +} \ No newline at end of file diff --git a/VAR.Toolbox/UI/Tools/FrmWorkLog.cs b/VAR.Toolbox/UI/Tools/FrmWorkLog.cs new file mode 100644 index 0000000..dba4461 --- /dev/null +++ b/VAR.Toolbox/UI/Tools/FrmWorkLog.cs @@ -0,0 +1,322 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; + +namespace VAR.Toolbox.UI.Tools +{ + public partial class FrmWorkLog : Form, IToolForm + { + #region IToolForm + + public string ToolName { get { return "WorkLog"; } } + + public bool HasIcon { get { return false; } } + + #endregion IToolForm + + #region Form life cycle + + public FrmWorkLog() + { + InitializeComponent(); + WorkLog_LoadData(); + } + + #endregion Form life cycle + + #region UI events + + private bool _selecting = false; + + private void lsbWorkLog_SelectedIndexChanged(object sender, System.EventArgs e) + { + if (_selecting) { return; } + _selecting = true; + WorkLogRow row = lsbWorkLog.SelectedItem as WorkLogRow; + if (row == null) + { + lsbWorkLog.ClearSelected(); + _selecting = false; + return; + } + if (row.Item == null) + { + WorkLogItem_Show(null); + DateTime dateStart = DateTime.MaxValue; + DateTime dateEnd = DateTime.MinValue; + foreach (WorkLogRow rowAux in lsbWorkLog.SelectedItems) + { + if (rowAux.DateStart < dateStart) { dateStart = rowAux.DateStart; } + if (rowAux.DateEnd > dateEnd) { dateEnd = rowAux.DateEnd; } + } + dtStart.Value = dateStart; + dtEnd.Value = dateEnd; + + _selecting = false; + return; + } + for (int i = 0; i < lsbWorkLog.Items.Count; i++) + { + WorkLogRow auxRow = lsbWorkLog.Items[i] as WorkLogRow; + lsbWorkLog.SetSelected(i, (row.Item == auxRow.Item)); + } + WorkLogItem_Show(row.Item); + _selecting = false; + } + + private void btnAdd_Click(object sender, System.EventArgs e) + { + WorkLogItem item = new WorkLogItem + { + DateStart = dtStart.Value, + DateEnd = dtEnd.Value, + Activity = txtActivity.Text, + Description = txtDescription.Text, + }; + _workLog.Add(item); + WorkLog_Refresh(); + WorkLog_SelectDate(item.DateStart); + WorkLogItem_Show(item); + } + + private void btnDelete_Click(object sender, System.EventArgs e) + { + if (_currentWorkLogItem == null) { return; } + if (MessageBox.Show("Delete Log?", "Delete Log?", MessageBoxButtons.YesNo) != DialogResult.Yes) + { + return; + } + + _workLog.Remove(_currentWorkLogItem); + WorkLog_Refresh(); + WorkLogItem_Show(null); + } + + private void dtStart_ValueChanged(object sender, EventArgs e) + { + WorkLogItem_Update(); + } + + private void dtEnd_ValueChanged(object sender, EventArgs e) + { + WorkLogItem_Update(); + } + + private void txtActivity_TextChanged(object sender, System.EventArgs e) + { + WorkLogItem_Update(); + } + + private void txtDescription_TextChanged(object sender, System.EventArgs e) + { + WorkLogItem_Update(refresh: false); + } + + private void dtToday_ValueChanged(object sender, System.EventArgs e) + { + WorkLog_Refresh(); + } + + private void btnPreviousDay_Click(object sender, System.EventArgs e) + { + dtToday.Value = dtToday.Value.Date.AddDays(-1); + } + + private void btnNextDay_Click(object sender, System.EventArgs e) + { + dtToday.Value = dtToday.Value.Date.AddDays(1); + } + + #endregion UI events + + #region Private methods + + private List _workLog = null; + + private void WorkLog_LoadData() + { + _workLog = new List(); + WorkLog_Refresh(); + WorkLog_SelectDate(DateTime.Now); + } + + private void WorkLog_SelectDate(DateTime date) + { + for (int i = 0; i < lsbWorkLog.Items.Count; i++) + { + WorkLogRow row = lsbWorkLog.Items[i] as WorkLogRow; + if (row.DateEnd > date) + { + lsbWorkLog.SetSelected(i, true); + break; + } + } + } + + private void WorkLog_Refresh() + { + DateTime today = dtToday.Value; + lsbWorkLog_BindData(_workLog, today.Year, today.Month, today.Day); + } + + private WorkLogItem _currentWorkLogItem = null; + + private void WorkLogItem_Show(WorkLogItem item) + { + _currentWorkLogItem = null; + if (item == null) + { + dtStart.Value = DateTime.UtcNow.Date; + dtEnd.Value = DateTime.UtcNow.Date; + txtActivity.Text = string.Empty; + txtDescription.Text = string.Empty; + btnAdd.Enabled = true; + btnDelete.Enabled = false; + return; + } + + dtStart.Value = item.DateStart; + dtEnd.Value = item.DateEnd; + txtActivity.Text = item.Activity; + txtDescription.Text = item.Description; + + btnAdd.Enabled = false; + btnDelete.Enabled = true; + _currentWorkLogItem = item; + } + + private void WorkLogItem_Update(bool refresh = true) + { + if (_currentWorkLogItem == null) { return; } + _currentWorkLogItem.DateStart = dtStart.Value; + _currentWorkLogItem.DateEnd = dtEnd.Value; + _currentWorkLogItem.Activity = txtActivity.Text; + _currentWorkLogItem.Description = txtDescription.Text; + if (refresh) + { + WorkLog_Refresh(); + WorkLog_SelectDate(_currentWorkLogItem.DateStart); + } + } + + public void lsbWorkLog_BindData(IEnumerable items, int year, int month, int day, int q = 15) + { + List rows = new List(); + for (int h = 0; h < 24; h++) + { + for (int m = 0; m < 60; m += q) + { + DateTime dateStart = new DateTime(year, month, day, h, m, 0); + DateTime dateEnd = dateStart.AddMinutes(q); + WorkLogRow row = new WorkLogRow { DateStart = dateStart, DateEnd = dateEnd, }; + if (items != null) + { + foreach (WorkLogItem item in items) + { + row.SetItem(item); + } + } + rows.Add(row); + } + } + lsbWorkLog.Items.Clear(); + lsbWorkLog.Items.AddRange(rows.ToArray()); + + EnableRepaint(new HandleRef(lsbWorkLog, lsbWorkLog.Handle), true); + lsbWorkLog.Invalidate(); + } + + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] + private static extern IntPtr SendMessage(HandleRef hWnd, Int32 Msg, IntPtr wParam, IntPtr lParam); + + private static void EnableRepaint(HandleRef handle, bool enable) + { + const int WM_SETREDRAW = 0x000B; + SendMessage(handle, WM_SETREDRAW, new IntPtr(enable ? 1 : 0), IntPtr.Zero); + } + + #endregion Private methods + + } + + public class WorkLogRow + { + public DateTime DateStart { get; set; } + public DateTime DateEnd { get; set; } + public WorkLogItem Item { get; set; } + + public override string ToString() + { + StringBuilder sbRow = new StringBuilder(); + + sbRow.AppendFormat("{0:00}:{1:00} ", DateStart.Hour, DateStart.Minute); + + if (Item == null) + { + return sbRow.ToString(); + } + + int rowLenght = 30; + int textLenght = Item.Activity.Length + 2; + if (textLenght > rowLenght) { rowLenght = textLenght; } + + if (Item.DateStart >= DateStart && Item.DateStart < DateEnd) + { + if (Item.DateEnd >= DateStart && Item.DateEnd <= DateEnd) + { + sbRow.Append("- "); + sbRow.Append(Item.Activity); + sbRow.Append(" "); + sbRow.Append(new string('-', (rowLenght - textLenght) + 1)); + } + else + { + sbRow.Append("┌ "); + sbRow.Append(Item.Activity); + sbRow.Append(" "); + sbRow.Append(new string('-', rowLenght - textLenght)); + sbRow.Append("┐"); + } + } + else if (Item.DateEnd >= DateStart && Item.DateEnd <= DateEnd) + { + sbRow.Append("└ "); + sbRow.Append(Item.Activity); + sbRow.Append(" "); + sbRow.Append(new string('-', rowLenght - textLenght)); + sbRow.Append("┘"); + } + else + { + sbRow.Append("│"); + sbRow.Append(new string('#', rowLenght)); + sbRow.Append("│"); + } + return sbRow.ToString(); + } + + public void SetItem(WorkLogItem item) + { + if (item == null) + { + Item = null; + return; + } + + if (item.DateStart >= DateEnd || item.DateEnd <= DateStart) { return; } + + Item = item; + } + } + + public class WorkLogItem + { + public DateTime DateStart { get; set; } + public DateTime DateEnd { get; set; } + public string Activity { get; set; } + public string Description { get; set; } + } +} diff --git a/VAR.Toolbox/VAR.Toolbox.csproj b/VAR.Toolbox/VAR.Toolbox.csproj index aca334a..e1e0db1 100644 --- a/VAR.Toolbox/VAR.Toolbox.csproj +++ b/VAR.Toolbox/VAR.Toolbox.csproj @@ -195,6 +195,12 @@ FrmWebcam.cs + + Form + + + FrmWorkLog.cs + UserControl