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());
}
}
}