private void CheckWarningLength(ListViewItem relevantitem, TimeSpan thetimespan) { return; //DISABLED... if (Database.Configuration.Monitor_WarningLength.Ticks == 0) { return; //0 is the "flag" to ignore warning length. } DataLayer.UserRecord gotrecord = (DataLayer.UserRecord)relevantitem.Tag; if (PreviousWarnStates == null) { PreviousWarnStates = new Dictionary <ListViewItem, bool>(); } if (!PreviousWarnStates.ContainsKey(relevantitem)) { //if not in the dict, add it as false... PreviousWarnStates.Add(relevantitem, false); } bool currwarnstate = thetimespan > Database.Configuration.Monitor_WarningLength; if (currwarnstate) { relevantitem.BackColor = Color.Plum; } if (currwarnstate && !(PreviousWarnStates[relevantitem])) { if (NotificationIcon.Visible) { NotificationIcon.ShowBalloonTip(750, "Length Notification", "Tech " + gotrecord.Username + " has exceeded Warning limit of " + DataLayer.FormatTimeSpan(Database.Configuration.Monitor_WarningLength) + ".", ToolTipIcon.Info); } } PreviousWarnStates[relevantitem] = currwarnstate; }
protected void InvokeWatchEvent(ChangeInfoConstants changetype, DataLayer.UserRecord oldRecord, DataLayer.UserRecord newRecord, Object extradata) { var copied = WatchEvent; if (copied != null) { copied(this, changetype, oldRecord, newRecord, extradata); } }
void MonitorUpdateTimer_Tick(object sender, EventArgs e) { if (Updateactive) { return; } Updateactive = true; //task: we want to update all the items in the list. //so we cheat, send some change event when there wasn't actually a change. //tag is in the format Record##, where ## is the RecordID of the value. //we don't want this to happen on a separate thread, either, if an invoke is required, //invoke ourself... try { lock (Database) { if (InvokeRequired) { Invoke((MethodInvoker)(() => MonitorUpdateTimer_Tick(sender, e))); } foreach (ListViewItem iterateitem in lvwUserListing.Items) { DataLayer.UserRecord oldrecord = ((DataLayer.UserRecord)iterateitem.Tag); int userecid = oldrecord.RecordID; DataLayer.UserRecord t; //create the updated record for this item... t = DataLayer.UserRecord.CreateRecord(userecid, Database); //fire! userwatch_WatchEvent(userwatch, CUserDataWatcher.ChangeInfoConstants.CIC_AllChanged, oldrecord, t, null); //and cross our fingers and hope that worked, of course. } } } catch { //hmm... } finally { Updateactive = false; } }
void userwatch_WatchEvent(CUserDataWatcher sender, CUserDataWatcher.ChangeInfoConstants changetype, DataLayer.UserRecord oldRecord, DataLayer.UserRecord newRecord, object extradata) { if (InvokeRequired) { Invoke((MethodInvoker)(() => userwatch_WatchEvent(sender, changetype, oldRecord, newRecord, extradata))); return; } Debug.Print("WatchEvent..." + changetype.ToString()); switch (changetype) { case CUserDataWatcher.ChangeInfoConstants.CIC_UserAdded: if (!newRecord.Active) { return; //don't show inactive users. } List <String> gotorders = Database.GetUserOrders(newRecord.Username); ListViewItem lvi = new ListViewItem(); String RO; lvi.Text = newRecord.Username; lvi.Tag = newRecord; lvi.Name = "Record" + newRecord.RecordID.ToString(); String busytext = ""; bool isclocked = false; DateTime?earlytime = GetEarliestStartTime(newRecord.PINCode, gotorders, out RO); if (earlytime == null) { busytext = " Not Clocked in"; lvi.ImageIndex = 1; lvi.Group = Clockedoutgroup; isclocked = false; } else { isclocked = true; lvi.Group = Clockedingroup; //otherwise, it needs to show the RO#'s they are clocked into with their time. //I get the feeling users won't be able to clock in more than one order at a time but may as well be flexible. List <String> useractiveorders = Database.GetUserOrders(newRecord.Username); Debug.Assert(useractiveorders.Count > 0); //should always have clocked in order if we get here. TimeSpan elapsedvalue = new TimeSpan(); if (useractiveorders.Count == 1) { busytext = FormatUserOrderInfo(newRecord.PINCode, useractiveorders[0], ref elapsedvalue); } else { List <String> buildlisting = (from o in useractiveorders let k = FormatUserOrderInfo(newRecord.PINCode, o, ref elapsedvalue) where k != "" select k).ToList(); busytext = String.Join(",", buildlisting.ToArray()); } CheckWarningLength(lvi, elapsedvalue); //busytext = "Busy since " + earlytime.Value.ToShortTimeString(); lvi.ImageIndex = 0; } lvi.SubItems.Add(busytext); lvi.Tag = newRecord; lvwUserListing.Items.Add(lvi); break; case CUserDataWatcher.ChangeInfoConstants.CIC_UserRemoved: //remove the item. ListViewItem finditem = lvwUserListing.Items["Record" + oldRecord.RecordID.ToString()]; lvwUserListing.Items.Remove(finditem); break; case CUserDataWatcher.ChangeInfoConstants.CIC_ActiveChanged: //we fake it by just refiring the event with Add or remove, respectively. bool newstate = (bool)extradata; if (newstate) { //visibilify. userwatch_WatchEvent(sender, CUserDataWatcher.ChangeInfoConstants.CIC_UserAdded, oldRecord, newRecord, null); } else { //invisibilify userwatch_WatchEvent(sender, CUserDataWatcher.ChangeInfoConstants.CIC_UserRemoved, oldRecord, newRecord, null); } break; case CUserDataWatcher.ChangeInfoConstants.CIC_AllChanged: ListViewItem ItemChanged = lvwUserListing.Items["Record" + newRecord.RecordID.ToString()]; if (ItemChanged != null) //null check, since it could fire immediately before a Add... { ItemChanged.Tag = newRecord; ItemChanged.Text = newRecord.Username; var activeorders = Database.GetUserOrders(newRecord.Username, true); TimeSpan refspan = new TimeSpan(); String[] formatted = (from m in activeorders select FormatUserOrderInfo(newRecord.PINCode, m, ref refspan)).ToArray(); String usesubitemtext = String.Join(",", formatted).Trim(); if (usesubitemtext != "") { ItemChanged.SubItems[1].Text = usesubitemtext; } CheckWarningLength(ItemChanged, refspan); } break; case CUserDataWatcher.ChangeInfoConstants.CIC_PINChanged: ListViewItem PINItem = lvwUserListing.Items["Record" + newRecord.RecordID.ToString()]; //well... actually we don't care if the PIN changes, but we need to keep things up to date nonetheless. PINItem.Tag = newRecord; break; case CUserDataWatcher.ChangeInfoConstants.CIC_NameChanged: ListViewItem changednameitem = lvwUserListing.Items["Record" + newRecord.RecordID.ToString()]; changednameitem.Text = newRecord.Username; changednameitem.Tag = newRecord; break; case CUserDataWatcher.ChangeInfoConstants.CIC_Clockin: ListViewItem clockedin = lvwUserListing.Items["Record" + newRecord.RecordID.ToString()]; List <String> inuserorders = Database.GetUserOrders(newRecord.Username, true); bool isclockedout = inuserorders.Count == 0; clockedin.ImageIndex = isclockedout ? 1 : 0; if (!isclockedout) { clockedin.Group = Clockedingroup; } clockedin.Group = Clockedingroup; if (inuserorders.Count == 0) { if (Database.Configuration.Monitor_NotifyAvailableTech) { NotificationIcon.ShowBalloonTip(750, newRecord.Username + " Available.", "A Tech no longer has active work orders.", ToolTipIcon.Info); } } clockedin.Tag = newRecord; break; case CUserDataWatcher.ChangeInfoConstants.CIC_Clockout: ListViewItem clockedout = lvwUserListing.Items["Record" + newRecord.RecordID.ToString()]; List <String> userorders = Database.GetUserOrders(newRecord.Username, true); bool isout = userorders.Count == 0; clockedout.ImageIndex = isout ? 1 : 0; clockedout.BackColor = SystemColors.Window; //recalc the UserOrder Format... if (isout) { clockedout.Group = Clockedoutgroup; } if (userorders.Count == 0) { //set subitem... clockedout.SubItems[1].Text = "Not Clocked in"; if (Database.Configuration.Monitor_NotifyAvailableTech) { NotificationIcon.ShowBalloonTip(750, newRecord.Username + " Available.", "A Tech no longer has active work orders.", ToolTipIcon.Info); } } clockedout.Tag = newRecord; break; } }