using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; using TradeIdeas.MiscSupport; using TradeIdeas.TIProData; namespace TradeIdeas.TIProGUI.Charting { public partial class IndicatorManager : Form { private List _libraryIndicators = Charts.AllLibraryIndicators; private List _chartIndicators = new List(); private List _chartAreas = new List(); //The below map keeps track of what indicators are edited while in the Edit mode (i.e. using Edit tab). Any time the user makes // a change to one of his/her indicators, this map will be updated(hence the event handlers created for all of the components such as chart area radio buttons, period box,status line checkbox ) //By keeping track of edits, the user will be able to switch between any existing indicators in the edit tab without losing any edits //that may have been done - This allows the user to edit more than one indicator while this window is still open, and apply those changes // after the 'Save' button is clicked to close this window.the int value(key) is the id of the TiqColumn in question(value) private Dictionary _editMap = new Dictionary(); private Charts _chart; private TiqColumn _indicatorSelected; String _selectedColorString = "#ed9f40"; String _selectedText = ""; TiqColumn _addBak; TiqColumn _editBak; private bool _skipUpdate = true; private System.Windows.Forms.Timer _updateTimer = new System.Windows.Forms.Timer(); //for when we exit this window private bool _doSave = false; private bool _doAdd = false; private bool _doRemove = false; // for "Edit tab" BindingList _dataSource = new BindingList(); private List _removables = new List(); //contains the id of indicators that might be removed (Edit tab). public IndicatorManager(Charts chart) { InitializeComponent(); _chart = chart; _chartAreas = chart.CurrentChartAreas; _chartIndicators = _chart.CurrentChartIndicators; _indicatorSelected = retrieveIndicator("AVG_VOLUME"); //default StartPosition = FormStartPosition.CenterParent; Icon = GuiEnvironment.Icon; buildGUI(_indicatorSelected); loadAddTab(); loadCurrentChartAreas(); Text = "Indicator Manager"; prepareDataGridView(); selectTheFont(); } /// /// This builds the dynamic portions of the GUI that depends on the number of parameters /// the indicator has. /// /// private void buildGUI(TiqColumn indicator) { FontFamily f = this.Font.FontFamily; float size = this.Font.Size * 1.2f; lblTitle.Font = new Font(f, size,FontStyle.Bold); lblTitle.Tag = indicator; //_chartIndicators = addMissingChartAreaNameToChartIndicatorList(_chartIndicators); // Remove current parameter rows. while (tableLayoutPanelParameters.RowCount > 4) { RemoveRow(tableLayoutPanelParameters, tableLayoutPanelParameters.RowCount - 1); } int currentRowCountIndex = tableLayoutPanelParameters.RowCount - 1; int widestHeaderWidth = 0; int widestValueWidth = 0; if (_chart.NotPrimitiveMode) { foreach (IndicatorParameter parameter in indicator.Parameters) { tableLayoutPanelParameters.RowCount++; RowStyle parameterRowStyle = new RowStyle(SizeType.AutoSize); tableLayoutPanelParameters.RowStyles.Add(parameterRowStyle); currentRowCountIndex++; Label parameterLabel = new Label(); parameterLabel.Text = parameter.Name; parameterLabel.AutoSize = true; parameterLabel.Dock = DockStyle.Fill; parameterLabel.Padding = new Padding(0, 5, 0, 0); parameterLabel.TextAlign = ContentAlignment.TopRight; if (parameterLabel.Width > widestHeaderWidth) widestHeaderWidth = parameterLabel.Width; tableLayoutPanelParameters.Controls.Add(parameterLabel, 0, currentRowCountIndex); NumericUpDown parameterUpDown = new NumericUpDown(); parameterUpDown.Tag = parameter; parameterUpDown.ValueChanged += ParameterUpDown_ValueChanged; parameterUpDown.Minimum = (decimal)parameter.Minimum; parameterUpDown.Maximum = (decimal)parameter.Maximum; parameterUpDown.Value = (decimal)parameter.Value; parameterUpDown.TabIndex = currentRowCountIndex; if (parameterUpDown.Width > widestValueWidth) widestValueWidth = parameterUpDown.Width; else parameterUpDown.Width = widestValueWidth; // Try to keep controls the same width as the combobox. tableLayoutPanelParameters.Controls.Add(parameterUpDown, 1, currentRowCountIndex); //lastIndicatorControl = parameterUpDown; } } } private void RemoveRow(TableLayoutPanel panel, int Rowindex) { if (Rowindex >= panel.RowCount) { return; } for (int i = 0; i < panel.ColumnCount; i++) { var control = panel.GetControlFromPosition(i, Rowindex); if (null != control as NumericUpDown) { NumericUpDown parameterUpDown = (NumericUpDown)control; parameterUpDown.ValueChanged -= ParameterUpDown_ValueChanged; } panel.Controls.Remove(control); } for (int i = Rowindex + 1; i < panel.RowCount; i++) { for (int j = 0; j < panel.ColumnCount; j++) { var control = panel.GetControlFromPosition(j, i); if (control != null) { panel.SetRow(control, i - 1); } } } if (panel.RowStyles.Count > panel.RowCount) panel.RowStyles.RemoveAt(panel.RowCount - 1); panel.RowCount--; } /// /// This will rebuild the chart area /// private void loadCurrentChartAreas() { if (null != _chartAreas) { int fH = this.FontHeight * 2; rdoMainChartArea.Tag = "MainChartArea"; ClearChartAreaPanelControls(); foreach (ChartArea chartArea in _chartAreas.ToList()) { if (chartArea.Name == "MainChartArea") continue; String nme = chartArea.Name; String end = (nme[nme.Length - 1]).ToString(); RadioButton rdo = new RadioButton(); rdo.AutoSize = true; rdo.Tag = chartArea.Name; rdo.CheckedChanged += Rdo_CheckedChanged; rdo.Text = "Chart Area #" + end; rdo.Location = new Point(4, aPanel.Controls.Count * fH); aPanel.Controls.Add(rdo); } } } private void ClearChartAreaPanelControls() { List controlsToRemove = new List(); foreach (Control control in aPanel.Controls) { if (null != control as RadioButton) { RadioButton rdoBtn = (RadioButton)control; if (!rdoBtn.Text.Contains("New Chart Area") && !rdoBtn.Text.Contains("(main)")) { rdoBtn.CheckedChanged -= Rdo_CheckedChanged; controlsToRemove.Add(rdoBtn); } } } foreach (RadioButton control in controlsToRemove) { aPanel.Controls.Remove(control); } } private void loadAddTab() { foreach (TiqColumn indicator in Charts.AllLibraryIndicators) //populate the panel with the available indicators from library { float currentSize = Font.Size; int spacer = 5; Label lbl = new Label(); lbl.AutoSize = true; lbl.Tag = indicator; lbl.Font = new Font(lbl.Font.FontFamily, currentSize, FontStyle.Bold); lbl.Text = indicator.DisplayName; lbl.Cursor = Cursors.Hand; lbl.Location = new Point(2, (addTabPanel.Controls.Count * 33) + spacer); lbl.MouseEnter += Lbl_MouseEnter; lbl.MouseLeave += Lbl_MouseLeave; lbl.Click += Lbl_Click; addTabPanel.Controls.Add(lbl); } } private List addMissingChartAreaNameToChartIndicatorList(List indicators) { List retVal = new List(); if (_chart.PrimitiveMode) { return retVal; } foreach (TiqColumn indicator in indicators) { //notice when adding a brand new indicator (Add tab) to Chart, debugger shows that the ChartAreaName is blank The other instance is where I add an existing indicator //that's in the main chart to a brand new area. In this case, the ChartAreaName remains as "MainChartArea", which is incorrect - (the actual name can be captured from ChartArea.Name. //So, this little method cleans up those errors each time this window is open. Plus it adds this corrected indicator info to replace that in _chart.CurrentChartIndicators ChartArea a = indicator.ChartArea; string name = a.Name; indicator.ChartAreaName = name; TiqColumn temp = indicator.DeepCopy(); temp.ChartArea = a; retVal.Add(temp); } _chart.CurrentChartIndicators = retVal; return retVal; } private void Lbl_Click(object sender, EventArgs e) { Label l = (Label)sender; _selectedText = l.Text; colorTheSelectedLabel(_selectedText); if (l.Tag != null) { TiqColumn ind = (TiqColumn)(l.Tag); restoreSpecs(ind); } } private void Lbl_MouseLeave(object sender, EventArgs e) { Label l = (Label)sender; if (l.Text == _selectedText) l.ForeColor = ColorTranslator.FromHtml(_selectedColorString); else l.ForeColor = Color.Black; } private void Lbl_MouseEnter(object sender, EventArgs e) { Label l = (Label)sender; l.ForeColor = ColorTranslator.FromHtml("#2e98f0"); } private void colorTheSelectedLabel(String labelText) { //first, put all labels to black: foreach (Control c in this.addTabPanel.Controls) { ((Label)c).ForeColor = Color.Black; } //now color the label with the selection color foreach (Control c in this.addTabPanel.Controls) { if(((Label)c).Text == labelText) ((Label)c).ForeColor = ColorTranslator.FromHtml(_selectedColorString); } } private void btnColor_Click(object sender, EventArgs e) { TiqColumn returnObject = getIndicatorObjectFromTitleLabel(); if (returnObject != null) { IndicatorColorChooser colorChooser = new IndicatorColorChooser(returnObject, this.tabControl.SelectedIndex == 0); DialogResult result = colorChooser.ShowDialog(); if (result == DialogResult.OK) { returnObject = (colorChooser.Indicator).DeepCopy(); returnObject.ChartArea = getChartAreaFromChartName(colorChooser.Indicator.ChartAreaName); if (btnAdd.Enabled == false) { if (!_skipUpdate) returnObject.DoUpdate = true; processEditedIndicator(returnObject); UpdateChangedIndicators(returnObject); } lblTitle.Tag = returnObject; if (returnObject.ColorType == IndicatorColorType.One) lblColor.BackColor = returnObject.Color; else lblColor.BackColor = SystemColors.Control; } } } private TiqColumn retrieveIndicator(String referencename) { TiqColumn retVal = null; foreach (TiqColumn c in _libraryIndicators) { if (c.ReferenceName == referencename) { retVal = c.DeepCopy(); retVal.ChartArea = getChartAreaFromChartName(c.ChartAreaName); break; } } return retVal; } private void rdoNewArea_CheckedChanged(object sender, EventArgs e) { if (rdoNewArea.Checked && btnAdd.Enabled == false) // edit mode { TiqColumn returnObject = getIndicatorObjectFromTitleLabel(); returnObject.PrefersOwnPane = true; returnObject.ChartAreaName = ""; returnObject.ChartArea = null; if (!_skipUpdate) returnObject.DoUpdate = true; processEditedIndicator(returnObject); UpdateChangedIndicators(returnObject); lblTitle.Tag = returnObject; } } private void rdoMainChartArea_CheckedChanged(object sender, EventArgs e) { if (rdoMainChartArea.Checked && btnAdd.Enabled == false) // edit mode { TiqColumn returnObject = getIndicatorObjectFromTitleLabel(); returnObject.ChartAreaName = "MainChartArea"; returnObject.ChartArea = getChartAreaFromChartName("MainChartArea"); returnObject.PrefersOwnPane = false; if (!_skipUpdate) returnObject.DoUpdate = true; processEditedIndicator(returnObject); UpdateChangedIndicators(returnObject); lblTitle.Tag = returnObject; } } private void Rdo_CheckedChanged(object sender, EventArgs e) //for other chart area radios that aren't "New" or "MainChartArea" { RadioButton radio = (RadioButton)sender; if (radio.Checked && btnAdd.Enabled == false && radio.Tag != null) { String chartAreaName = (radio.Tag).ToString(); TiqColumn returnObject = getIndicatorObjectFromTitleLabel(); returnObject.ChartAreaName = chartAreaName; returnObject.ChartArea = getChartAreaFromChartName(chartAreaName); returnObject.PrefersOwnPane = true; if (!_skipUpdate) returnObject.DoUpdate = true; processEditedIndicator(returnObject); UpdateChangedIndicators(returnObject); lblTitle.Tag = returnObject; } } private void checkBoxShowInStatusLine_Click(object sender, EventArgs e) { if (btnAdd.Enabled == false) { TiqColumn returnObject = getIndicatorObjectFromTitleLabel(); returnObject.ShowInStatusLine = checkBoxShowInStatusLine.Checked; if (!_skipUpdate) returnObject.DoUpdate = true; processEditedIndicator(returnObject); UpdateChangedIndicators(returnObject); lblTitle.Tag = returnObject; } } private void ParameterUpDown_ValueChanged(Object sender, EventArgs e) { NumericUpDown numericUpDown = (NumericUpDown)sender; if (null != numericUpDown.Tag) { IndicatorParameter currentParmeter = (IndicatorParameter)numericUpDown.Tag; TiqColumn returnObject = getIndicatorObjectFromTitleLabel(); int index = 0; foreach (IndicatorParameter parameter in returnObject.Parameters) { if (parameter.ReferenceId.Equals(currentParmeter.ReferenceId)) { double value = Decimal.ToDouble(numericUpDown.Value); if (value > parameter.Maximum) value = parameter.Maximum; else if (value < parameter.Minimum) value = parameter.Minimum; returnObject.Parameters[index].Value = value; } index++; } if (!_skipUpdate) returnObject.DoUpdate = true; processEditedIndicator(returnObject); UpdateChangedIndicators(returnObject); } } private ChartArea getChartAreaFromChartName(String chartName) { ChartArea retVal = null; foreach (ChartArea chartArea in _chartAreas.ToList()) { if(chartArea.Name == chartName) { retVal = chartArea; break; } } return retVal; } private void processEditedIndicator(TiqColumn indc) { if (!_editMap.ContainsKey(indc.HelperId)) { TiqColumn temp = indc.DeepCopy(); if (indc.ChartArea != null) temp.ChartArea = getChartAreaFromChartName(indc.ChartAreaName); _editMap.Add(indc.HelperId, temp); } else { _editMap.Remove(indc.HelperId); TiqColumn temp = indc.DeepCopy(); if(indc.ChartArea != null) //we want to grab the chart area name. Otherwise we're dealing with an indicator that wants it's own pane. temp.ChartArea = getChartAreaFromChartName(indc.ChartAreaName); _editMap.Add(indc.HelperId, temp); } } private void restoreSpecs(TiqColumn col) { if (!col.DoUpdate) _skipUpdate = true; if (_editMap.ContainsKey(col.HelperId) && btnAdd.Enabled == false) _editMap[col.HelperId] = col; //lblTitle.Text = col.ResolvedAbbreviatedName(); lblTitle.Text = col.DisplayName; lblTitle.Tag = col; if (col.ColorType == IndicatorColorType.One) lblColor.BackColor = col.Color; else lblColor.BackColor = SystemColors.Control; _indicatorSelected = col; checkBoxShowInStatusLine.Checked = col.ShowInStatusLine; if (col.PrefersOwnPane) { String name = col.ChartAreaName; if ((name == null || name == "") && col.ChartArea == null) rdoNewArea.Checked = true; else setSelectedRadio(name); } else { setSelectedRadio("MainChartArea"); } buildGUI(col); _skipUpdate = false; } private void setSelectedRadio(String chartAreaName) { foreach (Control c in aPanel.Controls) { RadioButton r = (RadioButton)c; if (r.Tag != null) { String name = (r.Tag).ToString(); if (name == chartAreaName) { r.Checked = true; break; } } else //test this code block-- we may not need it { String name = ""; if (name == chartAreaName) { r.Checked = true; break; } } } } private String getSelectedRadio() //we're actually retrieving the chart code(string) from the selected radio button { String retVal = ""; foreach (Control c in aPanel.Controls) { RadioButton r = (RadioButton)c; if (r.Checked) { if (r.Tag != null) { String name = (r.Tag).ToString(); retVal = name; } else retVal = ""; break; } } return retVal; } //The 4 save/restore methods below are when we wish to set the right-hand side of the GUI (radio buttons, label, ..etc) //when we're switching back and forth between the "Add" and "Edit" tabs. private void saveValuesFromAddMode() { TiqColumn ind = getIndicatorObjectFromTitleLabel(); ind = changeParametersFromFormSettings(ind); TiqColumn temp = ind.DeepCopy(); temp.ChartArea = getChartAreaFromChartName(ind.ChartAreaName); _addBak = temp; } private void saveValuesFromEditMode() { if (dataGridView1.Rows.Count > 0) { TiqColumn ind = getIndicatorObjectFromTitleLabel(); //deep copy occurrs in this method ind = changeParametersFromFormSettings(ind); _editBak = ind; } } private void restoreEditModeValues() { restoreSpecs(_editBak); } private void restoreAddModeValues() { restoreSpecs(_addBak); } private TiqColumn getIndicatorObjectFromTitleLabel() { TiqColumn retVal = null; Object o = lblTitle.Tag; if (o != null) { TiqColumn temp = (TiqColumn)o; retVal = temp.DeepCopy(); //don't forget to do this!! if(temp.ChartArea != null) retVal.ChartArea = getChartAreaFromChartName(temp.ChartAreaName); //re-install the chartArea (can also be null)!! } return retVal; } private TiqColumn changeParametersFromFormSettings(TiqColumn col) { if (getSelectedRadio() == "MainChartArea") { col.PrefersOwnPane = false; col.ChartAreaName = "MainChartArea"; } else { String name = getSelectedRadio(); col.PrefersOwnPane = true; col.ChartAreaName = name; } bool b = checkBoxShowInStatusLine.Checked; col.ShowInStatusLine = b; foreach (Control control in tableLayoutPanelParameters.Controls) { if (control as NumericUpDown != null) { NumericUpDown parameterUpDown = control as NumericUpDown; IndicatorParameter parameter = parameterUpDown.Tag as IndicatorParameter; if (null != parameter) { int index = 0; foreach (IndicatorParameter item in col.Parameters) { if (item.ReferenceId.Equals(parameter.ReferenceId)) col.Parameters[index].Value = Decimal.ToDouble(parameterUpDown.Value); index++; } } } } return col; } private void tabControl_SelectedIndexChanged(object sender, EventArgs e) { //index 0 is the AddTab, and index1 is the EditTab int selectedIndex = tabControl.SelectedIndex; _skipUpdate = true; if (selectedIndex == 0) //Add tab { btnRemove.Enabled = false; btnSave.Enabled = false; btnAdd.Enabled = true; tableLayoutPanelParameters.Visible = true; saveValuesFromEditMode(); restoreAddModeValues(); } else //Edit tab { btnRemove.Enabled = true; btnSave.Enabled = true; btnAdd.Enabled = false; //_chartIndicators = _chart.CurrentChartIndicators; saveValuesFromAddMode(); updatateRemovablesStatus(); if (_editBak == null) { if (_chartIndicators.Count > 0) { TiqColumn i = _chartIndicators[0]; TiqColumn ind = i.DeepCopy(); //this had stripped away the chartArea object from TiqColumn i; ind.ChartArea = i.ChartArea; ind.ChartAreaName = i.ChartArea.Name; restoreSpecs(ind); } else { // Hide tableLayoutPanelParameters. tableLayoutPanelParameters.Visible = false; } } else { restoreEditModeValues(); } checkRowSelectionStatus(); } _skipUpdate = false; } private void IndicatorManager_FormClosing(object sender, FormClosingEventArgs e) { foreach (Control c in this.addTabPanel.Controls) { Label l = ((Label)c); l.MouseEnter -= Lbl_MouseEnter; l.MouseLeave -= Lbl_MouseLeave; l.Click -= Lbl_Click; } _dataSource.Clear(); dataGridView1.Rows.Clear(); } private void IndicatorManager_VisibleChanged(object sender, EventArgs e) { //Whenever this window becomes visible, we will show Avg Volume as default selected in the Add Tab if (Visible) { _selectedText = "Average Volume"; colorTheSelectedLabel(_selectedText); restoreSpecs(_indicatorSelected); } } private void dataGridView1_VisibleChanged(object sender, EventArgs e) { UpdateDataGridView(); } private void UpdateDataGridView() { if (dataGridView1.Visible) { //_chartIndicators = _chart.CurrentChartIndicators; //_chartIndicators = addMissingChartAreaNameToChartIndicatorList(_chartIndicators); _chartAreas = _chart.CurrentChartAreas; loadCurrentChartAreas(); _dataSource = getDataSource(_chartIndicators); dataGridView1.DataSource = _dataSource; for (int i = 0; i < dataGridView1.RowCount; i++) { DataGridViewCell cell = dataGridView1.Rows[i].Cells[0]; CustomDataItem dat = _dataSource[i]; cell.Style.BackColor = dat.Color; cell.Style.ForeColor = dat.Color; cell.Style.SelectionForeColor = dat.Color; cell.Style.SelectionBackColor = dat.Color; } UpdateAllChangedIndicators(); } } private void UpdateChangedIndicators(TiqColumn indicator) { if (dataGridView1.Visible) { for (int i = 0; i < dataGridView1.RowCount; i++) { CustomDataItem dat = _dataSource[i]; if (dat.Indicator.HelperId == indicator.HelperId) { TiqColumn ind = _editMap[indicator.HelperId]; if (ind.DoUpdate) { dataGridView1.Rows[i].Cells[1].Style.ForeColor = Color.Green; dataGridView1.Rows[i].Cells[1].Style.SelectionForeColor = Color.Green; } else { dataGridView1.Rows[i].Cells[1].Style.ForeColor = Color.Black; dataGridView1.Rows[i].Cells[1].Style.SelectionForeColor = Color.Black; } } dataGridView1.Invalidate(); } } } private void UpdateAllChangedIndicators() { if (dataGridView1.Visible) { for (int i = 0; i < dataGridView1.RowCount; i++) { CustomDataItem dat = _dataSource[i]; if (dat.Indicator.DoUpdate) { dataGridView1.Rows[i].Cells[1].Style.ForeColor = Color.Green; dataGridView1.Rows[i].Cells[1].Style.SelectionForeColor = Color.Green; } else { dataGridView1.Rows[i].Cells[1].Style.ForeColor = Color.Black; dataGridView1.Rows[i].Cells[1].Style.SelectionForeColor = Color.Black; } } dataGridView1.Invalidate(); } } private void prepareDataGridView() { dataGridView1.Font = this.Font; dataGridView1.DefaultCellStyle.SelectionBackColor = Color.FromArgb(213, 228, 242); dataGridView1.DefaultCellStyle.SelectionForeColor = Color.Black; //This column "plainCol" is just an empty textbox column which shall display the color of the respective indicator. DataGridViewTextBoxColumn plainCol = new DataGridViewTextBoxColumn(); plainCol.Name = "Plain"; plainCol.DataPropertyName = "Plain"; plainCol.HeaderText = "Plain"; plainCol.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; plainCol.FillWeight = 10; plainCol.ReadOnly = true; dataGridView1.Columns.Add(plainCol); //Hide this column-from being *viewed* (even though it will stay databound so that we can get the color component to determine the color for the "plainCol" cell of the row DataGridViewTextBoxColumn bCol = new DataGridViewTextBoxColumn(); bCol.Name = "Color"; bCol.DataPropertyName = "Color"; bCol.HeaderText = "Color"; bCol.ReadOnly = true; bCol.DefaultCellStyle.Padding = new Padding(4); dataGridView1.Columns.Add(bCol); DataGridViewTextBoxColumn tCol = new DataGridViewTextBoxColumn(); tCol.Name = "ResolvedAbbreviatedName"; tCol.DataPropertyName = "ResolvedAbbreviatedName"; //don't forget this!! tCol.HeaderText = "Abbrev"; tCol.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; tCol.FillWeight = 90; tCol.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; tCol.ReadOnly = true; dataGridView1.Columns.Add(tCol); //Styling: dataGridView1.GridColor = Color.FromArgb(186, 186, 186); //now populate grid: _dataSource = getDataSource(_chartIndicators); //dataGridView1.AutoGenerateColumns = false; dataGridView1.DataSource = _dataSource; dataGridView1.Columns[2].Visible = false; //color column(used to be at index 2) dataGridView1.Columns[3].Visible = false;//indicator column //populate the "removables" list with the very first item in the grid. _removables.Clear(); if (_chartIndicators.Count > 0) _removables.Add(_chartIndicators[0].HelperId); } private BindingList getDataSource(List cols) { BindingList retVal = new BindingList(); foreach (TiqColumn col in cols) { CustomDataItem customDat = new CustomDataItem(col); // Edited indicators should be used in the dataGridView datasource. if (_editMap.ContainsKey(col.HelperId)) customDat = new CustomDataItem(_editMap[col.HelperId]); retVal.Add(customDat); } return retVal; } private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) { updatateRemovablesStatus(); checkRowSelectionStatus(); int selectedRow = e.RowIndex; CustomDataItem itm = _dataSource[selectedRow]; TiqColumn indicator = itm.Indicator; // Unsaved indicator changes should be restored. if (_editMap.ContainsKey(indicator.HelperId)) indicator = _editMap[indicator.HelperId]; restoreSpecs(indicator); //update the GUI labels, radio buttons when clicking on the EditPanel's display of indicators on the chart changeParametersFromFormSettings(indicator); } private void updatateRemovablesStatus() { int u = dataGridView1.SelectedRows.Count; _removables.Clear(); foreach (DataGridViewRow row in dataGridView1.SelectedRows) { int s = row.Index; CustomDataItem item = _dataSource[s]; //int iD = item.Indicator.Id; string iD = item.Indicator.HelperId; _removables.Add(iD); } } private void checkRowSelectionStatus() { if (_removables.Count > 1) { btnColor.Enabled = false; btnAdd.Enabled = false; btnSave.Enabled = true; groupBox1.Enabled = false; checkBoxShowInStatusLine.Enabled = false; tableLayoutPanelParameters.Enabled = false; } else { btnAdd.Enabled = false; btnColor.Enabled = true; btnSave.Enabled = true; groupBox1.Enabled = true; checkBoxShowInStatusLine.Enabled = true; tableLayoutPanelParameters.Enabled = true; } } private class CustomDataItem { private TiqColumn _col; private Color _clr; private String _resolvedAbbName; public CustomDataItem(TiqColumn col) { if(col.ColorType == IndicatorColorType.One) _clr = col.Color; if (col.ColorType == IndicatorColorType.UpDown) _clr = col.UpColor; if (col.ColorType == IndicatorColorType.Gradient) _clr = col.TopColor; _resolvedAbbName = col.ResolvedAbbreviatedName(); ChartArea c = col.ChartArea; _col = col.DeepCopy(); _col.ChartArea = c; } public String ResolvedAbbreviatedName { get { return _resolvedAbbName; } set { _resolvedAbbName = value; } } public Color Color { get { return _clr; } set { _clr = value; } } public TiqColumn Indicator { get { return _col; } set { _col = value; } } } public bool getDoSave() { return _doSave; } public bool getDoAdd() { return _doAdd; } public bool getDoDelete() { return _doRemove; } public TiqColumn getIndicator() { return _indicatorSelected; } public Dictionary getEditedIndicators() { return _editMap; } public List getIndicatorsToRemove() { return _removables; } private void btnAdd_Click(object sender, EventArgs e) { TiqColumn ind = getIndicatorObjectFromTitleLabel(); ind = changeParametersFromFormSettings(ind); ind.HelperId = System.Guid.NewGuid().ToString(); //_chartIndicators.Add(ind); _chart.AddIndicator(ind); _chartIndicators = addMissingChartAreaNameToChartIndicatorList(_chartIndicators); _chartAreas = _chart.CurrentChartAreas; TiqColumn chartIndicator = FindIndicatorFromChartIndicators(ind); processEditedIndicator(chartIndicator); loadCurrentChartAreas(); //UpdateChangedIndicators(); _indicatorSelected = ind; //this is retrieved with "getIndicator" upon exiting. _doAdd = true; _doSave = false; _doRemove = false; } private TiqColumn FindIndicatorFromChartIndicators(TiqColumn ind) { TiqColumn revisedIndicator = ind; foreach (TiqColumn item in _chartIndicators) { if (item.HelperId == ind.HelperId) { revisedIndicator = item.DeepCopy(); revisedIndicator.ChartArea = getChartAreaFromChartName(revisedIndicator.ChartAreaName); } } return revisedIndicator; } private void btnRemove_Click(object sender, EventArgs e) { _chart.RemoveIndicators(_removables); UpdateDataGridView(); updatateRemovablesStatus(); StartUpdateTimer(); _doRemove = true; _doAdd = false; _doSave = false; } private void btnSave_Click(object sender, EventArgs e) { Dictionary selectedEditedIndicators = new Dictionary(); foreach (string helperID in _removables) { if (!selectedEditedIndicators.ContainsKey(helperID) && _editMap.ContainsKey(helperID)) { TiqColumn ind = _editMap[helperID].DeepCopy(); ChartArea chartArea = _editMap[helperID].ChartArea; if (ind.DoUpdate) { ind.DoUpdate = false; ind.ChartArea = chartArea; selectedEditedIndicators.Add(helperID, ind); _editMap.Remove(helperID); } } } if (selectedEditedIndicators.Count > 0) { _chart.UpdateIndicators(selectedEditedIndicators); _chartIndicators = addMissingChartAreaNameToChartIndicatorList(_chartIndicators); _chartAreas = _chart.CurrentChartAreas; UpdateDataGridView(); StartUpdateTimer(); } _doSave = true; _doAdd = false; _doRemove = false; } private void StartUpdateTimer() { _updateTimer.Interval = 500; _updateTimer.Tick -= _updateTimer_Tick; _updateTimer.Tick += _updateTimer_Tick; _updateTimer.Start(); } private void _updateTimer_Tick(object sender, EventArgs e) { _updateTimer.Stop(); UpdateDataGridView(); if (dataGridView1.Rows.Count > 0) dataGridView1_CellClick(this.dataGridView1, new DataGridViewCellEventArgs(0, 0)); if (dataGridView1.Rows.Count == 0) { _editMap.Clear(); _editBak = null; tabControl.SelectTab(0); } } private void dataGridView1_SelectionChanged(object sender, EventArgs e) { //if (dataGridView1.SelectedCells.Count > 0) //{ dataGridView1.Invalidate(); //} } private void selectTheFont() { Font = GuiEnvironment.FontSettings; dataGridView1.Font = Font; lblTitle.Font = new Font(Font, FontStyle.Bold); foreach (Control control in addTabPanel.Controls) { Label label = control as Label; if (null != label) { label.Font = new Font(Font, FontStyle.Bold); } } } private void btnClose_Click(object sender, EventArgs e) { this.Close(); } } }