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