Click here to Skip to main content
15,883,940 members
Articles / Programming Languages / C#

VSS – OnTime Bridge

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
27 Apr 2010CPOL7 min read 35.5K   217   11  
VSS add-in providing for VSS – OnTime bridge
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Drawing;
using System.Windows.Forms;

using System.Data;

namespace Scm2OtGui
{
	/// <summary>
	/// Gui component for any CSM to present and provide selection of OnTime action items.
	/// So far SCM == VSS
	/// </summary>

	public class Scm2OtForm : Form
	{
		private Label lblLink;
		private Label lblTo;
		private TextBox tbSpec;
		private Button btnSelect;
		private Button btnCancel;
		private Button btnRefresh;
		private System.Windows.Forms.ComboBox cbItemsType;
		private System.Windows.Forms.DataGrid dataGridOT;
		
		private int dataGridRightMargin;
		private int dataGridBottomMargin;

		private ToolTip _ttCancel;
		private ToolTip _ttSelect;
		private ToolTip _ttRefresh;
		private ToolTip _ttSpec;
		private ToolTip _ttItems;
		private ToolTip _ttGrid;

		private OnTimeAdapter.OTAdapter _otAdapter;
		private string _vssItemSpec = "VSS item spec";
		private int _vssVersion = 0;
		private string _linkLabel = "";		// {"D123" | "F234" | "T345"}
		private string _lastLabel = "";		// linkLabel previously used by CSM
		private int _nOtType = 0;			// currently selected {0: Defect; 1: Feature; 2: Task}
		private string _sOtType;
		private int _nIndex = 0;			// current item index in current table
		private int _nOtItem = 0;			// selected OtItem number

		// persist the size and layout
		// can not use Form.Size property, because setting the property for newly created dialog
		// causes Resize() event before the form was initialized - exceptions.
		private Size _dlgSize;
		private Point _gridMargins;

		// Public properties
		public string VssItemSpec
		{
			get { return _vssItemSpec; }
			set
			{
				if (_vssItemSpec == value)
					return;
				_vssItemSpec = value;
				tbSpec.Text = _vssItemSpec;
			}
		}
		public int VssVersion
		{
			get { return _vssVersion; }
			set
			{
				if (_vssVersion == value)
					return;
				_vssVersion = value;
			}
		}

		public Point GridMargins
		{
			get { return _gridMargins; }
			set
			{
				if (_gridMargins == value)
					return;
				_gridMargins = value;
			}
		}

		public Size DlgSize
		{
			get { return _dlgSize; }
			set
			{
				if (_dlgSize == value)
					return;
				_dlgSize = value;
			}
		}

		// Public setter: SCM may set the value to existing SCM item label
		public string LinkLabel
		{
			get { return _linkLabel; }
			set
			{
				if (_linkLabel == value)
					return;
				_linkLabel = value;
			}
		}

		// Public setter: SCM may set the value to last link label
		public string LastLabel
		{
			get { return _lastLabel; }
			set
			{
				if (_lastLabel == value)
					return;
				_lastLabel = value;
			}
		}

		public Scm2OtForm()
		{
			InitializeComponent();
		}

		private void InitializeComponent()
		{
			// margins
			int lMarg = 10;
			int tMarg = 6;

			// 
			// Vss2OtForm
			// 
			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			this.ClientSize = new System.Drawing.Size(400, 296);
			this.Name = "Scm2OtForm";
			this.Text = String.Format("OnTime Items: {0}", System.Security.Principal.WindowsIdentity.GetCurrent().Name);
			this.Load += new System.EventHandler(this.Scm2OtForm_Load);
			this.Resize += new System.EventHandler(Scm2OtForm_Resize);

			// 
			// btnCancel
			// 
			btnCancel = new Button();
			btnCancel.Text = "Cancel";
			btnCancel.Size = new System.Drawing.Size(80, 20);
			btnCancel.Location = new Point(lMarg, ClientSize.Height - btnCancel.Height - lMarg);
			btnCancel.TabIndex = 1;
			_ttCancel = new ToolTip();
			_ttCancel.SetToolTip(btnCancel, "Cancel linking.");
			this.Controls.Add(btnCancel);

			// 
			// btnSelect
			// 
			btnSelect = new Button();
			btnSelect.Text = "Select";
			btnSelect.Size = btnSelect.Size;
			btnSelect.Location = new Point(ClientSize.Width - btnSelect.Width - lMarg, btnCancel.Top);
			btnSelect.TabIndex = 2;
			_ttSelect = new ToolTip();
			_ttSelect.SetToolTip(btnSelect, "Link the source file to selected OnTime item.");
			this.Controls.Add(btnSelect);

			// 
			// btnRefresh
			// 
			btnRefresh = new Button();
			btnRefresh.Text = "Refresh";
			btnRefresh.Size = btnSelect.Size;
			// left-adjasent to btnSelect
			btnRefresh.Location = new Point(btnSelect.Left - lMarg - btnRefresh.Width, btnCancel.Top);
			btnRefresh.TabIndex = 3;
			_ttSelect = new ToolTip();
			_ttSelect.SetToolTip(btnRefresh, "Refresh the list of OnTime items.");
			this.Controls.Add(btnRefresh);

			// 
			// cbItemsType
			//
			this.cbItemsType = new ComboBox();
			cbItemsType.Size = new System.Drawing.Size(80, 24);
			cbItemsType.Location = new Point(ClientSize.Width - lMarg - cbItemsType.Width, tMarg - 2);
			cbItemsType.AllowDrop = false;
			cbItemsType.TabIndex = 4;
			cbItemsType.DropDownStyle = ComboBoxStyle.DropDownList;
			_ttItems = new ToolTip();
			_ttItems.SetToolTip(cbItemsType, "Select type of the OnTime items.");
			this.Controls.Add(cbItemsType);

			//
			// lblLink
			//
			this.lblLink = new Label();
			lblLink.Location = new Point(lMarg, tMarg + 2);
			lblLink.Width = 30;
			lblLink.Text = "Link";
			this.Controls.Add(lblLink);

			//
			// lblTo: adjasent to cbItemsType
			//
			this.lblTo = new Label();
			lblTo.Width = 24;
			lblTo.Location = new Point(cbItemsType.Left - lblTo.Width, tMarg + 2);
			lblTo.Text = "To";
			this.Controls.Add(lblTo);

			//
			// tbSpec: between lblLink and lblTo
			//
			this.tbSpec = new TextBox();
			tbSpec.Text = _vssItemSpec;
			tbSpec.AllowDrop = false;
			tbSpec.Location = new Point(lblLink.Right, tMarg);
			tbSpec.Width = lblTo.Left - lblLink.Right - 6;
			tbSpec.ReadOnly = true;
			tbSpec.TabStop = false;
			_ttSpec = new ToolTip();
			_ttSpec.SetToolTip(tbSpec, "Source file to check in.\nLink it to OnTime item.");
			this.Controls.Add(tbSpec);

			// 
			// dataGridOT
			// 
			this.dataGridOT = new DataGrid();
			this.dataGridOT.Location = new System.Drawing.Point(lMarg, 36);
			this.dataGridOT.Name = "dataGridOT";
			this.dataGridOT.ReadOnly = true;
			dataGridOT.AllowDrop = false;
			dataGridOT.AllowNavigation = true;
			dataGridOT.ColumnHeadersVisible = true;
			this.dataGridOT.Size = new System.Drawing.Size(376, 218);	// (368, 218) - (x, y)
			this.dataGridOT.TabIndex = 0;
			_ttGrid = new ToolTip();
			_ttGrid.SetToolTip(dataGridOT, 
				String.Format("OnTime Items assigned to {0}",
				System.Security.Principal.WindowsIdentity.GetCurrent().Name));
			this.Controls.Add(this.dataGridOT);

			// OnTimeAdapter
			this._otAdapter = new OnTimeAdapter.OTAdapter();
		}

		public bool Open()
		{
			// if label exist, try to select the table according to the item type
			// and select the OT item in the table.
			int nType = ValidateOtLabel(_linkLabel);

			// If the label is not OT label, try to get the latest OT item for the VSS item spec
			// from OT DB and generate (fake) initial label.
			if (nType < 0)
			{
				string otLabel = _otAdapter.GetLastItem(_vssItemSpec);
				nType = ValidateOtLabel(otLabel);
				if (0 <= nType)
					_linkLabel = otLabel;
			}

			// If no OT label available, try to use link label previously used by SCM
			if (nType < 0)
			{
				nType = ValidateOtLabel(_lastLabel);
				if (0 <= nType)
					_linkLabel = _lastLabel;
			}

			// If no label set type to default
			if (nType < 0)
				nType = 0;

			_nOtType = nType;
			_sOtType = _otAdapter.otItemTypes[_nOtType];	// will be using types returned by adapter			
			SetTable(_sOtType);								// show table of the "Defects" items
			cbItemsType.DataSource = _otAdapter.otItemTypes;
			cbItemsType.SelectedIndex = _nOtType;

			TopMost = true;
			DialogResult dr = ShowDialog();
			return true;

			//	return (DialogResult.Yes == ShowDialog());
			// ShowDialog() always returns Cancel; see if I can change it;
			// for now the caller will have to use LinkLabel != "" to identify success
		}

		public void CloseDialog()
		{
			_ttCancel.Dispose();
			_ttSelect.Dispose();
			_ttSpec.Dispose();
			_ttItems.Dispose();
			_ttGrid.Dispose();

			this.Close();
			this.Dispose();
		}

		private void Scm2OtForm_Load(object sender, EventArgs e)
		{
			// restore the size if saved in the class that creates this dialog
			if (null == _dlgSize || _dlgSize.IsEmpty)
				_dlgSize = this.Size;
			else
				this.Size = _dlgSize;

			if (this.MinimumSize.IsEmpty)
				this.MinimumSize = this.Size;

			if (null == _gridMargins || _gridMargins.IsEmpty)
			{
				_gridMargins.X = this.ClientSize.Width - dataGridOT.Right;
				_gridMargins.Y = this.ClientSize.Height - dataGridOT.Bottom;
			}

			AcceptButton = btnSelect;

			cbItemsType.SelectedIndexChanged += cbItemsType_SelectedIndexChanged;
			btnCancel.Click += btnCancel_Click;
			btnSelect.Click += btnSelect_Click;
			btnRefresh.Click += btnRefresh_Click;
		}

		private void Scm2OtForm_Resize(object sender, EventArgs e)
		{
			// margin
			int lMarg = 10;

			if (this.Width < this.MinimumSize.Width)
				this.Width = this.MinimumSize.Width;
			if (this.Height < this.MinimumSize.Height)
				this.Height = this.MinimumSize.Height;

			// move buttons
			btnCancel.Location = new Point(10, ClientSize.Height - btnSelect.Height - lMarg);
			btnSelect.Location = new Point(ClientSize.Width - btnSelect.Width - lMarg, btnCancel.Top);
			// left-adjasent to btnSelect
			btnRefresh.Location = new Point(btnSelect.Left - lMarg - btnRefresh.Width, btnCancel.Top);

			// resize datagrid
			int newRMargin = ClientSize.Width - dataGridOT.Right;
			int newBMargin = ClientSize.Height - dataGridOT.Bottom;
			int dX = newRMargin - _gridMargins.X;
			int dY = newBMargin - _gridMargins.Y;
			dataGridOT.Width += dX;
			dataGridOT.Height += dY;

			// resize <Name> column
			string tblName;
			if (null != cbItemsType && null != cbItemsType.SelectedValue)
				tblName = cbItemsType.SelectedValue.ToString();
			else
				tblName = this._otAdapter.otItemTypes[0];
			this.dataGridOT.TableStyles[tblName].GridColumnStyles[1].Width += dX;

			// move combobox, lblTo
			cbItemsType.Location = new Point(cbItemsType.Left + dX, cbItemsType.Top);
			lblTo.Location = new Point(lblTo.Left + dX, lblTo.Top);

			// resize textbox
			tbSpec.Width += dX;

			// save size
			_dlgSize = this.Size;
		}

		/// <summary>
		/// Sets the table to be shown in the datagrid
		/// </summary>
		/// <param name="tblName">"Defects"|"Features"|"Tasks"|"Incidents"</param>
		private void SetTable(string tblName)
		{
			// if label exist, table type should be already set by the caller
			// if label exist, try to select the item in the table according to the lable ("D123")
			string sNum = "";
			if ((null != _linkLabel) && (_linkLabel.Length > 0))
				sNum = _linkLabel.Substring(1);

			_nIndex = 0;		// reset the item index
			_linkLabel = "";	// reset the label
			System.Data.DataTable dt = _otAdapter.GetItemsTable(tblName, false);
			this.dataGridOT.DataSource = dt;	// (DataSource may be set to DataSet or DataTable)
			dataGridOT.CaptionText = tblName;

			DataRow theRow = null;
			try
			{
				theRow = dt.Rows.Find(sNum);
			}
			catch (Exception ex) { }

			if (null != theRow)
			{
				_nIndex = dt.Rows.IndexOf(theRow);
			}
			dataGridOT.CurrentRowIndex = _nIndex;
			if (0 < dt.Rows.Count)
			{
				dataGridOT.NavigateTo(_nIndex, tblName);
				this.btnSelect.Enabled = true;
			}
			else
				this.btnSelect.Enabled = false;

				// adjust column width
				// Create new Table Style
				using (DataGridTableStyle ts = new DataGridTableStyle { MappingName = tblName })
				{
					this.dataGridOT.TableStyles.Clear();
					this.dataGridOT.TableStyles.Add(ts);
				}

			// Adjust <Name> column so that the table covers the grid's width
			int dX = 0;		// total width of all columns but "Name" (1)
			for (int i = 0; i < dt.Columns.Count; i++)
			{
				if (1 != i)
					dX += dataGridOT.TableStyles[tblName].GridColumnStyles[i].Width;
			}
			dataGridOT.TableStyles[tblName].GridColumnStyles[1].Width = dataGridOT.Width - dataGridOT.TableStyles[tblName].RowHeaderWidth - dX;
		}

		/// <summary>
		/// Validates OT label
		/// </summary>
		/// <param name="label">'D123', 'F4567', etc.</param>
		/// <returns>0=Defects|1=Features|2=Tasks|3=Incidents|-1=error</returns>
		private int ValidateOtLabel(string label)
		{
			int nType = -1;
			if ((null != label) && (label.Length > 0))
			{
				char ch = label[0];
				for (int i = 0; i < _otAdapter.otItemTypes.Length; i++)
				{
					if (_otAdapter.otItemTypes[i][0] == ch)
					{
						nType = i;
						break;
					}
				}
			}
			return nType;
		}

		private void cbItemsType_SelectedIndexChanged(object sender, EventArgs e)
		{
			_nOtType = cbItemsType.SelectedIndex;
			_sOtType = _otAdapter.otItemTypes[_nOtType];
			SetTable(_sOtType);
		}

		private void btnCancel_Click(object sender, EventArgs e)
		{
			string theText = String.Format("Are you sure you want to cancel linking {0} to OnTime items?\nCanceling the link will prevent this file to be selected by auto-build tool!", _vssItemSpec);
			DialogResult dr = MessageBox.Show(theText, "Cancel Link?", MessageBoxButtons.YesNo, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button2);

			if (DialogResult.Yes == dr)
			{
				_linkLabel = "";
				CloseDialog();
			}
		}

		// OtItem is selected; link it with VssItem - call OnTime SP
		// On SCM side - caller will label VssItem using LinkLabel property
		private void btnSelect_Click(object sender, EventArgs e)
		{			
			_nIndex = dataGridOT.CurrentRowIndex;

			DataTable dt = (DataTable)dataGridOT.DataSource;
			object oItem = dt.Rows[_nIndex].ItemArray[0];
			_nOtItem = (int)oItem;
			_linkLabel = string.Format("{0}{1}", dt.TableName[0], oItem);

			CloseDialog();
		}

		private void btnRefresh_Click(object sender, EventArgs e)
		{
			_otAdapter.GetItemsTable(_nOtType, true);	// force refresh of current table
		}

		// workaround for version discrepancy issue:
		// VssItem.Label() creates new version number.
		// Let IvssEventHandlerGF call this function _after_ assigning new version
		public int AddLink()
		{
			return _otAdapter.AddLink(_nOtItem, _nOtType, _vssItemSpec, _vssVersion.ToString());
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions