private void JobMonitor_Load(object sender, EventArgs e) { NotificationIcon = new NotifyIcon(); //same icon as this form. NotificationIcon.Icon = this.Icon; //set the ContextMenuStrip.... NotificationMenu = new ContextMenuStrip(); HideItem = new ToolStripMenuItem("&Hide"); RestoreItem = new ToolStripMenuItem("&Restore"); //make it bold to indicate it is the "default" action. RestoreItem.Font = new Font(RestoreItem.Font, FontStyle.Bold); QuitItem = new ToolStripMenuItem("&Quit"); //set handlers... NotificationMenu.Opening += new CancelEventHandler(NotificationMenu_Opening); MonitorSorter = new GenericListViewSorter(lvwUserListing, null); HideItem.Click += new EventHandler(HideItem_Click); QuitItem.Click += new EventHandler(QuitItem_Click); RestoreItem.Click += new EventHandler(RestoreItem_Click); NotificationMenu.Items.AddRange(new ToolStripItem[] { RestoreItem, HideItem, QuitItem }); NotificationIcon.DoubleClick += new EventHandler(RestoreItem_Click); NotificationIcon.ContextMenuStrip = NotificationMenu; //That's the Notification Icon setup. //ready the db... tryagain: try { //Database.GetConnection(); Database.DbConnection_Progress(); } catch (Exception exx) { //oh no! //log the error. DataLayer.LogAdmin("Exception:" + exx.Message + " Stack Trace:" + exx.StackTrace); //show a message. if (MessageBox.Show(this, "Error Connecting to the Database:" + exx.Message, "Database Error", MessageBoxButtons.RetryCancel) == DialogResult.Retry) { goto tryagain; } Close(); } DbConnection gotcon = Database.GetConnection(); //draw our "LED" bitmaps. LEDs = new Bitmap[LEDColorsMiddle.Length]; LEDGraphics = new Graphics[LEDColorsMiddle.Length]; for (int i = 0; i < LEDColorsMiddle.Length; i++) { LEDs[i] = new Bitmap(16, 16); Graphics g = LEDGraphics[i] = Graphics.FromImage(LEDs[i]); g.Clear(Color.Transparent); //draw an ellipse... GraphicsPath gpp = new GraphicsPath(); gpp.AddEllipse(2, 2, 14, 14); PathGradientBrush pathbrush = new PathGradientBrush(gpp); pathbrush.CenterColor = LEDColorsMiddle[i]; Color[] surround = pathbrush.SurroundColors; for (int j = 0; j < surround.Length; j++) { surround[j] = LEDColorsOuter[i]; } pathbrush.SurroundColors = surround; pathbrush.CenterPoint = new PointF(8, 8); g.FillPath(pathbrush, gpp); gpp.Dispose(); pathbrush.Dispose(); } //create the ImageList. imlListView = new ImageList(); imlListView.ImageSize = new Size(16, 16); imlListView.ColorDepth = ColorDepth.Depth32Bit; imlListView.Images.AddRange(LEDs); //add the columns to the listview. //right now- a "unlabelled" one, 17 pixels wide, to show the LED; //and their Name. simple enough, really. lvwUserListing.SmallImageList = imlListView; lvwUserListing.Columns.Add("NAME", "Name", 100); lvwUserListing.Columns.Add("BUSY", "Time", 100); lvwUserListing.SizeColumnsEqual(); //add two groups: one for clocked-in and one for clocked-out. Clockedingroup = lvwUserListing.Groups.Add("CLOCKEDIN", "Clocked In"); Clockedoutgroup = lvwUserListing.Groups.Add("CLOCKEDOUT", "Clocked Out"); MonitorSelChange = new BeforeSelItemChange(lvwUserListing); MonitorSelChange.fireChange += new BeforeSelItemChange.BeforeItemChangeFunction(MonitorSelChange_fireChange); userwatch = new CUserDataWatcher(Database); userwatch.WatchEvent += new CUserDataWatcher.WatchEventFunc(userwatch_WatchEvent); //set up the timer as well, which will periodically fire... MonitorUpdateTimer = new Timer(); MonitorUpdateTimer.Interval = 500; MonitorUpdateTimer.Tick += new EventHandler(MonitorUpdateTimer_Tick); //MonitorUpdateTimer.Start(); }
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; } }