private void UpdateComplete()
{
if(this.InvokeRequired)
{
VoidEventHandler d = new VoidEventHandler(UpdateComplete);
this.BeginInvoke(d);
}
else
{
try
{
// Size label, totally useless, purely decorative
float xmllen = (float)xml.InnerText.Length * 13.117f;
sizelabel.Text = xmllen.ToString("0 . 000 B");
// Received as "Dordrecht - 15:34"
string titletext = xml.DocumentElement.FirstChild.InnerText;
// Determine current time plus walk time to compare with
int lastspace = titletext.TrimEnd().LastIndexOf(' ');
int separator = titletext.IndexOf(':');
string hourstr = titletext.Substring(lastspace + 1, separator - lastspace - 1);
string minutestr = titletext.Substring(separator + 1).TrimEnd();
int hourint = int.Parse(hourstr);
int minuteint = int.Parse(minutestr);
DateTime statstime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, hourint, minuteint, 1);
statstime = statstime.AddMinutes(WALK_MINUTES);
titlelabel.Text = hourstr + ":" + minuteint.ToString("00");
// Move to the first <tr> element for the first item
XmlNode xmlitem = xml.DocumentElement.FirstChild.NextSibling;
xmlitem = xmlitem.NextSibling.NextSibling.NextSibling.FirstChild.NextSibling.FirstChild;
// Setup the items on screen using the XML data
for(int i = 0; i < items.GetLength(0); i++)
{
if(xmlitem != null)
{
string warning = "";
bool warningserious = false;
// Show all cells in normal state
for(int c = 0; c < items.GetLength(1); c++)
{
items[i, c].StopInfoFlash();
items[i, c].StopWarningFlash();
}
// Time and delay (received in a format like "16:45 + 2 min.")
string xmltime = xmlitem.FirstChild.InnerText.Trim();
int pluspos = xmltime.IndexOf('+');
string timeonly = xmltime;
string delayonly = "";
if(pluspos > -1)
{
timeonly = timeonly.Substring(0, pluspos - 1);
int minpos = xmltime.IndexOf("min.");
delayonly = xmltime.Substring(pluspos, (minpos - pluspos) - 1);
items[i, 1].StartWarningFlash();
}
items[i, 0].Text = timeonly;
items[i, 1].Text = delayonly;
items[i, 0].Visible = true;
items[i, 1].Visible = true;
// Determine time for comparison
int firstspace = xmltime.IndexOf(' ');
if(firstspace == -1) firstspace = xmltime.Length;
separator = xmltime.IndexOf(':');
hourstr = xmltime.Substring(0, separator);
minutestr = xmltime.Substring(separator + 1, firstspace - separator - 1);
hourint = int.Parse(hourstr);
minuteint = int.Parse(minutestr);
DateTime itemtime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, hourint, minuteint, 0);
if(itemtime.Ticks < statstime.Ticks)
items[i, 0].StartInfoFlash();
// Direction
string direction = xmlitem.FirstChild.NextSibling.InnerText;
items[i, 2].Text = direction.Trim();
items[i, 2].Visible = true;
// Spoor
XmlNode spoorxml = xmlitem.FirstChild.NextSibling.NextSibling;
items[i, 3].Text = spoorxml.InnerText.Trim();
items[i, 3].Visible = true;
XmlNode spoorclassxml = spoorxml.Attributes.GetNamedItem("class");
if(spoorclassxml != null)
items[i, 3].StartWarningFlash();
// Type (try finding a warning in here as well)
XmlNode typexml = xmlitem.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling;
string type = typexml.InnerText.TrimStart();
int spacepos = type.IndexOf(' ');
if(spacepos > -1)
{
string beforespace = type.Substring(0, spacepos).Trim();
// In case of "Rijdt vandaag niet" there is no train type
if(string.Compare(beforespace, "Rijdt", true) == 0)
{
spacepos = 0;
beforespace = "N/A";
warningserious = true;
// Make the entire row flash
for(int c = 0; c < items.GetLength(1); c++)
items[i, c].StartWarningFlash();
}
string afterspace = type.Substring(spacepos).Trim();
type = Tools.StripExcessiveWhitespace(beforespace.Replace(",", ""));
if(afterspace.Length > 0)
{
afterspace = afterspace.TrimStart(',');
warning = Tools.StripExcessiveWhitespace(afterspace.Trim());
// If the site indicates the text in red, so do we (exceptions below)
warningserious = (typexml.FirstChild.NextSibling != null) && (typexml.FirstChild.NextSibling.Name == "span");
if(warning.StartsWith("extra", StringComparison.InvariantCultureIgnoreCase))
warningserious = false;
}
}
items[i, 4].Text = type.Trim();
items[i, 4].Visible = true;
// Determine row color
ColorIndex rowcolor = ColorIndex.ControlNormal;
if(type.StartsWith("Sneltrein"))
rowcolor = ColorIndex.ControlColor3;
else if(type.StartsWith("Stoptrein"))
rowcolor = ColorIndex.ControlColor4;
else if(type.StartsWith("Sprinter"))
rowcolor = ColorIndex.ControlColor4;
// Give the entire row a color
for(int c = 0; c < items.GetLength(1); c++)
{
items[i, c].ColorNormal = rowcolor;
items[i, c].SetupColors(General.Colors);
}
// Any warning to show?
if(warning.Length > 0)
{
Font f;
if(warning.Length < 20)
f = items[i, 4].Font;
else
f = smallfontexample.Font;
items[i, 5].Font = f;
items[i, 5].Text = warning;
if(warningserious)
items[i, 5].StartWarningFlash();
else
items[i, 5].StartInfoFlash();
items[i, 5].Visible = true;
}
else
{
items[i, 5].Visible = false;
}
// Move to the next <tr> element
xmlitem = xmlitem.NextSibling;
}
else
{
// No more items, so hide these cells
for(int c = 0; c < items.GetLength(1); c++)
{
items[i, c].StopInfoFlash();
items[i, c].StopWarningFlash();
items[i, c].Visible = false;
}
}
}
}
catch(Exception e)
{
HandleFail("Failed to update treintijden. " + e.GetType().Name + ": " + e.Message);
}
// Start timer for next update
updatetimer.Interval = nextupdatedelay;
updatetimer.Start();
}
}