using System; using System.Collections.Generic; using System.Globalization; using System.Text.RegularExpressions; using System.Windows.Forms; using System.Xml; using TradeIdeas.MiscSupport; using TradeIdeas.TIProData.Interfaces; using TradeIdeas.XML; namespace TradeIdeas.TIProGUI { /// /// HistoryTimeFrame class. Enables User to view a history /// "snapshot" (or keep real time) for an Alert Form. /// public partial class HistoryTimeFrame : Form, ICultureListener { private IConnectionMaster _connectionMaster; private string _config; private AlertForm _alertForm; private MultiStrategy _multiStrategyForm; private DateTime _timeNow; private DateTime _start = ServerFormats.Now; private DateTime _end; private bool _isAlertForm = false; private DateTime _startDateTime; private DateTime _endDateTime; private DateTime _today; private ToolTip _okTip; private List _phrases; private List _commonPhrases; private List _endTimes; private bool _firstComboLoad = true; private int _preserveIndex; public ConfigHistory HistorySetting { get; set; } public bool ClickOK { get; set; } /// /// Combo getter and setter for alert configuration strings /// public string Config { get; set; } //When this window is first instantiated, the startTimePicker will be set to the //current time. However when this window is viewed again, we wish to retain //the setting of this time picker in the same fashion as with the other time // and date picker controls. private bool _firstViewing = true; // Save current language private string _currentLanguage; private const float DEFAULT_FONT_SIZE = 8.25F; /// /// A Structure for a ConfigHistory Item. /// When the user is in History mode on the alert window and /// is also in the "Don't Repeat For Mode as well, he may wish to /// change the parameters within the "Don't Repeat For mode". If so, /// History must be refreshed. Furthermore, when those parameters are /// changed history should start "back at the top" (most recent) again. /// That is, if the user has gotten history, and has hit "more" a few times, /// *then* changes the parameters in the "Don't Repeat For" mode, the history should /// refresh showing the most recent-not showing "midstream". /// This is automatically done when someone is changing the history parameters /// from within the History Time Frame window. However, within the Alert window /// these values in the struct below need to be collected as we wish to use /// the "SetConfigHistory" method called while in the alert window (we need to preserve /// the user's StartTime and EndTime). /// public struct ConfigHistory { public string itemConfig; public DateTime? itemStart; public DateTime? itemEnd; public ConfigHistory(string ConFig, DateTime? StartTime, DateTime? EndTime) { this.itemConfig = ConFig; this.itemStart = StartTime; this.itemEnd = EndTime; } } /// /// Constructor of the HistoryTimeFrame class /// /// /// alert configuration string /// alert form object public HistoryTimeFrame(IConnectionMaster connectionMaster,string config, object candidateForm) { _connectionMaster = connectionMaster; _config = config; Config = _config; //prevent a possible Assertion error on some machines if (candidateForm as AlertForm != null) { _isAlertForm = true; _alertForm = (AlertForm)candidateForm; } else { _isAlertForm = false; _multiStrategyForm = (MultiStrategy)candidateForm; } // _alertForm = alertForm; this.StartPosition = FormStartPosition.CenterParent; InitializeComponent(); // Open window in the center of the parent this.StartPosition = FormStartPosition.CenterParent; Icon = GuiEnvironment.Icon; _phrases = GuiEnvironment.XmlConfig.Node("HISTORY_TIME_FRAME").Node("PHRASES"); _commonPhrases = GuiEnvironment.XmlConfig.Node("COMMON_PHRASES"); _endTimes = GuiEnvironment.XmlConfig.Node("HISTORY_TIME_FRAME").Node("END_TIMES"); //set up the tooltips... ToolTip toolDates = new ToolTip(); toolDates.SetToolTip(this.startDatePicker, _phrases.Node("RECENT_ALERTS").PropertyForCulture("TEXT", "***")); toolDates.SetToolTip(this.startTimePicker, _phrases.Node("RECENT_ALERTS").PropertyForCulture("TEXT", "***")); toolDates.SetToolTip(this.endDatePicker, _phrases.Node("OLDEST_ALERTS").PropertyForCulture("TEXT", "***")); toolDates.SetToolTip(this.endTimePicker, _phrases.Node("OLDEST_ALERTS").PropertyForCulture("TEXT", "***")); toolDates.SetToolTip(this.cboEndDays, _phrases.Node("OLDEST_ALERTS").PropertyForCulture("TEXT", "***")); _okTip = new ToolTip(); _okTip.SetToolTip(this.btnOK, _phrases.Node("ERROR_DATES").PropertyForCulture("TEXT", "***")); _okTip.SetToolTip(this.btnCancel, _phrases.Node("ERROR_DATES").PropertyForCulture("TEXT", "***")); _okTip.Active = false; SetMinMaxDates(); // Set Format to Custom for time and date controls. This will allows us to modify how time and date // will be displayed startTimePicker.Format = DateTimePickerFormat.Custom; endTimePicker.Format = DateTimePickerFormat.Custom; startDatePicker.Format = DateTimePickerFormat.Custom; endDatePicker.Format = DateTimePickerFormat.Custom; // Define time and date controls to use current regional culture short date and time formats. // Additionally we must check if military time is selected. startTimePicker.CustomFormat = GuiEnvironment.ShowMilitaryTime ? GuiEnvironment.AlertTimeShortFormat : CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern; endTimePicker.CustomFormat = GuiEnvironment.ShowMilitaryTime ? GuiEnvironment.AlertTimeShortFormat : CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern; startDatePicker.CustomFormat = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern; endDatePicker.CustomFormat = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern; // By default this control shows the current time. However, that's the current time // in the computer's timezone. We want it to show the current time in the timezone // specified by the user. // Warning: This will cause a callback, and that callback will fail if it happens // too early in the constructor. startTimePicker.Value = ServerFormats.Now; Font = GuiEnvironment.FontSettings; Shown += new EventHandler(HistoryTimeFrame_Shown); } void HistoryTimeFrame_Shown(object sender, EventArgs e) { // this needs to be called when the form is shown in case the user has left the program // running for at least two nights SetMinMaxDates(); } /// /// Responsible for language changes /// public void CultureChanged() { _currentLanguage = GuiEnvironment.CultureManager.Current.TwoLetterISOLanguageName; // Set format of displayed time and date as a function of language except for English if (!_currentLanguage.Equals("en")) { startTimePicker.CustomFormat = _phrases.Node("TIME_FORMAT").PropertyForCulture("TEXT", "***"); endTimePicker.CustomFormat = _phrases.Node("TIME_FORMAT").PropertyForCulture("TEXT", "***"); startDatePicker.CustomFormat = _phrases.Node("DATE_FORMAT").PropertyForCulture("TEXT", "***"); endDatePicker.CustomFormat = _phrases.Node("DATE_FORMAT").PropertyForCulture("TEXT", "***"); } else { // Return to defined time and date controls using the current regional culture short date and time formats. // Additionally we must check if military time is selected. startTimePicker.CustomFormat = GuiEnvironment.ShowMilitaryTime ? GuiEnvironment.AlertTimeShortFormat : CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern; endTimePicker.CustomFormat = GuiEnvironment.ShowMilitaryTime ? GuiEnvironment.AlertTimeShortFormat : CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern; startDatePicker.CustomFormat = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern; endDatePicker.CustomFormat = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern; } this.Text = _phrases.Node("WINDOW_TITLE").PropertyForCulture("TEXT", "***"); grpStart.Text = _phrases.Node("START").PropertyForCulture("TEXT", "***"); grpEnd.Text = _phrases.Node("END").PropertyForCulture("TEXT", "***"); rdoStartNow.Text = _phrases.Node("NOW").PropertyForCulture("TEXT", "***"); btnOK.Text = _commonPhrases.Node("OK").PropertyForCulture("TEXT", "***"); btnCancel.Text = _commonPhrases.Node("CANCEL").PropertyForCulture("TEXT", "***"); cboEndDays.Items.Clear(); for (int i = 0; i < 15; i++) { string time = ""; if (i == 0) { time = _endTimes.Node("TODAY").PropertyForCulture("TEXT", "***"); cboEndDays.Items.Add(time); } else if (i == 1) { time = _endTimes.Node("YESTERDAY").PropertyForCulture("TEXT", "***"); cboEndDays.Items.Add(time); } else { time = String.Format(_endTimes.Node("PAST_DAYS").PropertyForCulture("TEXT", "***"), i); cboEndDays.Items.Add(time); } } //need to add one last entry to this combo box...30 days cboEndDays.Items.Add(String.Format(_endTimes.Node("PAST_DAYS").PropertyForCulture("TEXT", "***"), 30)); //History has now been extended out to 60 days, so add one more item to the combo... int moreHistory = GuiEnvironment.GetGeneralInfo(_connectionMaster.SendManager).GetOddsMakerDays(); if (moreHistory > 30) { cboEndDays.Items.Add(String.Format(_endTimes.Node("PAST_DAYS").PropertyForCulture("TEXT", "***"), moreHistory)); } if (_firstComboLoad) { cboEndDays.SelectedIndex = 0; _firstComboLoad = false; } else { if (rdoEndDays.Checked == true) { cboEndDays.SelectedIndex = _preserveIndex; } else { cboEndDays.SelectedIndex = _preserveIndex; //gotta change that radio button back to true, //because whenever the selected index of the combo changes, //the radio button for the combo box becomes checked. rdoEndDateTime.Checked = true; } } _today = ServerFormats.Today; } private void SetMinMaxDates() { /*for datetime.now, I must extract the strings for both the date and the time portions-I then recombine them again for the present dateTime object. The reason for this process is that milliseconds must get stripped away (get set to 0, in other words). Other wise, this will cause problems in some of the if-logic-blocks where although the two dateTimes being compared *appear* to be equal (date, hh mm ss), they might differ in milliseconds...which causes problems*/ _timeNow = ServerFormats.Now.Truncate(TimeSpan.TicksPerSecond); /*Saw something like this in the Delphi code to limit the maximum and minimum dates that the user can choose..*/ startDatePicker.MaxDate = _timeNow.AddDays(1); DateTime? oldestAlert = GuiEnvironment.GetGeneralInfo(_connectionMaster.SendManager).GetOldestAlert(); if (oldestAlert.HasValue) startDatePicker.MinDate = oldestAlert.Value; else startDatePicker.MinDate = startDatePicker.MaxDate.AddDays(-65); endDatePicker.MaxDate = startDatePicker.MaxDate; endDatePicker.MinDate = startDatePicker.MinDate; } private void loadSettings() { if (rdoStartNow.Checked == true ) { if (rdoEndDays.Checked == true) { _end = _today.AddDays(-(extractDays(cboEndDays.SelectedItem))); if (_isAlertForm) { _alertForm.SetConfigHistory(_config, null, _end); ConfigHistory c = new ConfigHistory(_config, null, _end); HistorySetting = c; } else //multi-strategy { _multiStrategyForm.SetConfigHistory(null, _end); } } else if (rdoEndDateTime.Checked == true) { if (_isAlertForm) { _alertForm.SetConfigHistory(_config, null, _endDateTime); ConfigHistory c = new ConfigHistory(_config, null, _endDateTime); HistorySetting = c; } else //multi-strategy { _multiStrategyForm.SetConfigHistory(null, _endDateTime); } } } else if (rdoStartDates.Checked == true) { if (rdoEndDays.Checked == true) { _end = _today.AddDays(-(extractDays(cboEndDays.SelectedItem))); if (_isAlertForm) { _alertForm.SetConfigHistory(_config, _startDateTime, _end); ConfigHistory c = new ConfigHistory(_config, _startDateTime, _end); HistorySetting = c; } else //multi-strategy { _multiStrategyForm.SetConfigHistory(_startDateTime, _end); } } else if (rdoEndDateTime.Checked == true) { if (_isAlertForm) { _alertForm.SetConfigHistory(_config, _startDateTime, _endDateTime); ConfigHistory c = new ConfigHistory(_config, _startDateTime, _endDateTime); HistorySetting = c; } else //multi-strategy { _multiStrategyForm.SetConfigHistory(_startDateTime, _endDateTime); } } } } private void checkDateEntries() { _startDateTime = new DateTime(startDatePicker.Value.Year, startDatePicker.Value.Month, startDatePicker.Value.Day, startTimePicker.Value.Hour, startTimePicker.Value.Minute, startTimePicker.Value.Second); _endDateTime = new DateTime(endDatePicker.Value.Year, endDatePicker.Value.Month, endDatePicker.Value.Day, endTimePicker.Value.Hour, endTimePicker.Value.Minute, endTimePicker.Value.Second); if (rdoStartNow.Checked == true) { if (rdoEndDays.Checked == true) { btnOK.Enabled = true; _okTip.Active = false; } else if (_endDateTime > ServerFormats.Now) { btnOK.Enabled = false; _okTip.Active = true; } else { btnOK.Enabled = true; _okTip.Active = false; } } else if (rdoStartDates.Checked == true) { if (rdoEndDays.Checked == true) { DateTime comboBox = new DateTime(); if (cboEndDays.SelectedItem == null) { comboBox = _today.AddDays(1); } else { comboBox = _today.AddDays(-(extractDays(cboEndDays.SelectedItem))); } if (comboBox > _startDateTime) { btnOK.Enabled = false; _okTip.Active = true; } else { btnOK.Enabled = true; _okTip.Active = false; } } else if (rdoEndDateTime.Checked == true) { if (_endDateTime > _startDateTime) { btnOK.Enabled = false; _okTip.Active = true; } else if(_endDateTime == _startDateTime) { btnOK.Enabled = false; _okTip.Active = true; } else { btnOK.Enabled = true; _okTip.Active = false; } } } } private void endDatePicker_ValueChanged(object sender, EventArgs e) { if (!rdoEndDateTime.Checked) { rdoEndDateTime.Checked = true; return; //only need to call checkDateEntries once... } checkDateEntries(); } private void endTimePicker_ValueChanged(object sender, EventArgs e) { if (!rdoEndDateTime.Checked) { rdoEndDateTime.Checked = true; return; //only need to call checkDateEntries once... } checkDateEntries(); } private void startDatePicker_ValueChanged(object sender, EventArgs e) { if (!rdoStartDates.Checked) { rdoStartDates.Checked = true; return; } checkDateEntries(); } private void startTimePicker_ValueChanged(object sender, EventArgs e) { if (!rdoStartDates.Checked) { rdoStartDates.Checked = true; return; } checkDateEntries(); } private void cboEndDays_SelectedIndexChanged(object sender, EventArgs e) { _preserveIndex = cboEndDays.SelectedIndex; if (!rdoEndDays.Checked) { rdoEndDays.Checked = true; return; } checkDateEntries(); } private void rdoStartNow_CheckedChanged(object sender, EventArgs e) { checkDateEntries(); } private void rdoStartDates_CheckedChanged(object sender, EventArgs e) { checkDateEntries(); } private void rdoEndDays_CheckedChanged(object sender, EventArgs e) { checkDateEntries(); } private void rdoEndDateTime_CheckedChanged(object sender, EventArgs e) { checkDateEntries(); } private void btnOK_Click(object sender, EventArgs e) { ClickOK = true; LoadSettings(); this.Hide(); } /// /// Load the current settings without opening the HistoryTimeFrame window. /// public void LoadSettings() { if (_connectionMaster.LoginManager.IsDemo) { return; } if (!_isAlertForm) { _multiStrategyForm.Finished = 0; _multiStrategyForm.getNumberSelectedStrategies(); } else { _alertForm.CurrentlyUsingHistory = true; } loadSettings(); } private void btnCancel_Click(object sender, EventArgs e) { ClickOK = false; this.Hide(); } private void HistoryTimeFrame_FormClosing(object sender, FormClosingEventArgs e) { this.Hide(); e.Cancel = true; } private void HistoryTimeFrame_VisibleChanged(object sender, EventArgs e) { if (Visible) { ClickOK = false; CultureChanged(); _config = Config; Font = GuiEnvironment.FontSettings; //When this window is first instantiated, the startTimePicker will be set to the //current time. However when this window is viewed again, we wish to retain //the setting of this time picker in the same fashion as with the other time // and date picker controls. if (_firstViewing) { _start = ServerFormats.Now; startTimePicker.Value = ServerFormats.Now; _firstViewing = false; } SetMinMaxDates(); } } private int extractDays(object obj) { /*Things were easy when the combo-box had the days, which were also equal to the index of each item. That is, day 0 was index 0, day 5 was index 5..etc. Calculations could be done just using cboEndDays.SelectedIndex However, now that we had to add "30 days ago", the whole landscape changed The index of "30 days ago" is not 30, but 16. So, have to work with the cboEndDays.SelectedItem instead...and extract the number from there...*/ string s = (string)obj; string str = Regex.Replace(s, "[^0-9]", ""); return Convert.ToInt32(str); } } }