source: Scheduling/trunk/cs/bsdx0200GUISourceCode/CalendarGrid.cs@ 1501

Last change on this file since 1501 was 1174, checked in by Sam Habiel, 14 years ago

Absorbed all changed from Radiology Support branch.
Patient and Provider classes now serializable to address new bug: Availablity slots cannot be saved b/c these classes are not serializable.

File size: 64.9 KB
RevLine 
[622]1namespace IndianHealthService.ClinicalScheduling
2{
3 using System;
4 using System.Collections;
5 using System.ComponentModel;
6 using System.Drawing;
7 using System.Globalization;
8 using System.Runtime.CompilerServices;
9 using System.Runtime.InteropServices;
10 using System.Windows.Forms;
[1143]11 using System.Linq;
[824]12
[622]13 /// <summary>
[821]14 /// This class is reponsible for rendering the Calendar Grid.
[622]15 /// </summary>
[1027]16 public class CalendarGrid : ScrollableControl
[622]17 {
[821]18 private IContainer components;
[622]19 private Font fontArial10;
20 private Font fontArial8;
21 private CGAppointments m_Appointments;
22 private Hashtable m_ApptOverlapTable;
23 private bool m_bAutoDrag = true;
24 private bool m_bDragDropStart;
25 private bool m_bDrawWalkIns = true;
26 private bool m_bGridEnter;
[1106]27 //private bool m_bInitialUpdate;
[622]28 private bool m_bMouseDown;
29 private bool m_bScroll;
30 private bool m_bScrollDown;
31 private bool m_bSelectingRange;
32 private int m_cellHeight;
33 private int m_cellWidth;
34 private int m_col0Width;
35 private Hashtable m_ColumnInfoTable;
36 private CGCell m_currentCell;
37 private DateTime m_dtStart;
38 private Font m_fCell;
39 private string m_GridBackColor;
40 private CGCells m_gridCells;
41 private int m_nColumns = 5;
42 private int m_nSelectID;
43 private int m_nTimeScale = 20;
44 private ArrayList m_pAvArray;
45 private string m_sDragSource;
46 private CGAppointments m_SelectedAppointments;
47 private CGRange m_selectedRange;
48 private StringFormat m_sf;
49 private StringFormat m_sfHour;
50 private StringFormat m_sfRight;
51 private ArrayList m_sResourcesArray;
[1106]52 private Timer m_Timer; // Timer used in Drag and Drop Operations
[622]53 private ToolTip m_toolTip;
[1075]54 private const int WM_HSCROLL = 0x114; // Horizontal Scrolling Windows Message
55 private const int WM_VSCROLL = 0x115; // Vertical Scrolling Windows Message
56 private const int WM_MOUSEWHEEL = 0x20a; // Windows Mouse Scrolling Message
[1106]57 private System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
[622]58
[1106]59
[1068]60 public delegate void CGAppointmentChangedHandler(object sender, CGAppointmentChangedArgs e);
61 public event CGAppointmentChangedHandler CGAppointmentChanged;
[622]62 public event CGAppointmentChangedHandler CGAppointmentAdded;
63
[1068]64 public delegate void CGSelectionChangedHandler(object sender, CGSelectionChangedArgs e);
[622]65 public event CGSelectionChangedHandler CGSelectionChanged;
66
67 public CalendarGrid()
68 {
69 this.InitializeComponent();
70 base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
71 base.SetStyle(ControlStyles.UserPaint, true);
72 base.SetStyle(ControlStyles.DoubleBuffer, true);
73 this.m_nColumns = 5;
74 this.m_gridCells = new CGCells();
75 this.m_selectedRange = new CGRange();
76 this.m_SelectedAppointments = new CGAppointments();
[1073]77 //this.m_Appointments = new CGAppointments();
[821]78 this.m_dtStart = new DateTime(2003, 1, 27);
[622]79 this.m_ApptOverlapTable = new Hashtable();
80 this.m_ColumnInfoTable = new Hashtable();
81 this.m_sResourcesArray = new ArrayList();
82 base.ResizeRedraw = true;
83 this.m_col0Width = 100;
84 this.fontArial8 = new Font("Arial", 8f);
85 this.fontArial10 = new Font("Arial", 10f);
86 this.m_fCell = this.fontArial10;
87 this.m_sf = new StringFormat();
88 this.m_sfRight = new StringFormat();
89 this.m_sfHour = new StringFormat();
90 this.m_sf.LineAlignment = StringAlignment.Center;
91 this.m_sfRight.LineAlignment = StringAlignment.Center;
92 this.m_sfRight.Alignment = StringAlignment.Far;
93 this.m_sfHour.LineAlignment = StringAlignment.Center;
94 this.m_sfHour.Alignment = StringAlignment.Far;
[1106]95 // this.m_bInitialUpdate = false;
[622]96 }
97
98 private Rectangle AdjustRectForOverlap()
99 {
100 return new Rectangle();
101 }
102
103 private void AutoDragStart()
104 {
105 this.m_bAutoDrag = true;
106 this.m_Timer = new Timer();
107 this.m_Timer.Interval = 5;
108 this.m_Timer.Tick += new EventHandler(this.tickEventHandler);
109 this.m_Timer.Start();
110 }
111
112 private void AutoDragStop()
113 {
114 this.m_bAutoDrag = false;
115 if (this.m_Timer != null)
116 {
117 this.m_Timer.Stop();
[1106]118 this.m_Timer.Tick -= new EventHandler(this.tickEventHandler);
[622]119 this.m_Timer.Dispose();
120 this.m_Timer = null;
121 }
122 }
123
124 private void BuildGridCellsArray(Graphics g)
125 {
126 try
127 {
[1143]128 //calculate each cell's height
[622]129 SizeF ef = g.MeasureString("Test", this.m_fCell);
130 this.m_cellHeight = ((int) ef.Height) + 4;
[1143]131
132 int nColumns = this.m_nColumns; // columns set via property
133 int slotsPerHour = 60 / this.m_nTimeScale; //time scale set via property
134 int slotsPerDay = 24 * slotsPerHour;
135 nColumns++; // add extra column for time display
136 slotsPerDay++; // not sure here why that's don't
137
138 //calculate each cell's height
139 this.m_cellWidth = 600 / nColumns; // base size is 600 pixels
140 // if larger:
[622]141 if (base.ClientRectangle.Width > 600)
142 {
143 this.m_cellWidth = (base.ClientRectangle.Width - this.m_col0Width) / (nColumns - 1);
144 }
[1143]145 // if only one column
[622]146 if (this.m_nColumns == 1)
147 {
148 this.m_cellWidth = base.ClientRectangle.Width - this.m_col0Width;
149 }
[1143]150 //next line seems to be useless (we don't use X and Y below)
[622]151 g.TranslateTransform((float) base.AutoScrollPosition.X, (float) base.AutoScrollPosition.Y);
[1143]152
153 //now, build the grid cells
154 for (int i = slotsPerDay; i > -1; i--)
[622]155 {
156 for (int j = 1; j < nColumns; j++)
157 {
158 int x = 0;
159 if (j == 1)
160 {
161 x = this.m_col0Width;
162 }
163 if (j > 1)
164 {
165 x = this.m_col0Width + (this.m_cellWidth * (j - 1));
166 }
167 Point point = new Point(x, i * this.m_cellHeight);
168 Rectangle r = new Rectangle(point.X, point.Y, this.m_cellWidth, this.m_cellHeight);
169 if (i != 0)
170 {
171 CGCell cell = null;
172 cell = new CGCell(r, i, j);
173 this.m_gridCells.AddCell(cell);
174 }
175 }
176 }
177 }
178 catch (Exception exception)
179 {
180 string message = exception.Message;
181 }
182 }
183
184 private void CalendarGrid_DragDrop(object Sender, DragEventArgs e)
185 {
186 CGAppointment data = (CGAppointment) e.Data.GetData(typeof(CGAppointment));
187 Point point = base.PointToClient(new Point(e.X, e.Y));
188 int x = point.X - base.AutoScrollPosition.X;
189 int y = point.Y - base.AutoScrollPosition.Y;
190 Point pt = new Point(x, y);
191 foreach (DictionaryEntry entry in this.m_gridCells.CellHashTable)
192 {
193 CGCell cgCell = (CGCell) entry.Value;
194 if (cgCell.CellRectangle.Contains(pt))
195 {
196 DateTime timeFromCell = this.GetTimeFromCell(cgCell);
197 string resourceFromColumn = this.GetResourceFromColumn(cgCell.CellColumn);
198 int duration = data.Duration;
199 TimeSpan span = new TimeSpan(0, duration, 0);
200 DateTime time2 = timeFromCell + span;
201 data.Selected = false;
202 this.m_nSelectID = 0;
203 CGAppointmentChangedArgs args = new CGAppointmentChangedArgs();
204 args.Appointment = data;
205 args.StartTime = timeFromCell;
206 args.EndTime = time2;
207 args.Resource = resourceFromColumn;
208 args.OldResource = data.Resource;
209 args.AccessTypeID = data.AccessTypeID;
210 args.Slots = data.Slots;
211 if (this.ApptDragSource == "grid")
212 {
213 this.CGAppointmentChanged(this, args);
214 }
215 else
216 {
217 this.CGAppointmentAdded(this, args);
218 }
219 break;
220 }
221 }
222 this.SetOverlapTable();
223 base.Invalidate();
224 }
225
226 private void CalendarGrid_DragEnter(object Sender, DragEventArgs e)
227 {
228 if (e.Data.GetDataPresent(typeof(CGAppointment)))
229 {
230 if ((e.KeyState & 8) == 8)
231 {
232 e.Effect = DragDropEffects.Copy;
233 }
234 else
235 {
236 e.Effect = DragDropEffects.Move;
237 }
238 }
239 else
240 {
241 e.Effect = DragDropEffects.None;
242 }
243 }
244
[1143]245 void CalendarGrid_DragOver(object sender, DragEventArgs e)
246 {
247 //Translate point to client point
248 Point pt = this.PointToClient(new Point(e.X, e.Y));
249
250 //clear selections
251 foreach (DictionaryEntry entry in this.m_gridCells.CellHashTable)
252 {
253 CGCell cell = (CGCell)entry.Value;
254 cell.IsSelected = false;
255 }
256 this.m_selectedRange.Cells.ClearAllCells();
257
258 //select a cell based on current drag position to visually assist the user
259 int nRow = -1;
260 int nCol = -1;
261 if (this.HitTest(pt.X, pt.Y, ref nRow, ref nCol))
262 {
263 CGCell cellFromRowCol = this.m_gridCells.GetCellFromRowCol(nRow, nCol);
264 if (cellFromRowCol != null)
265 {
266 this.m_currentCell = cellFromRowCol;
267 this.m_selectedRange.StartCell = null;
268 this.m_selectedRange.EndCell = null;
269 this.m_selectedRange.CreateRange(this.m_gridCells, cellFromRowCol, cellFromRowCol);
270
271 cellFromRowCol.IsSelected = true;
272 }
273
274 base.Invalidate();
275 }
276
277 //if Y axis is outside the top or bottom
278
279 if ((pt.Y + 40 >= this.ClientRectangle.Bottom) || (pt.Y - 40 <= this.ClientRectangle.Top))
280 {
281 //start auto scrolling. m_bScrollDown decides whether we scroll up or down.
282 this.m_bScrollDown = (pt.Y + 40) >= this.ClientRectangle.Bottom;
283 AutoDragStart();
284 }
285
286 //if Y axis within client rectagle, stop dragging (whether you started or not)
287 if ((pt.Y + 40 < this.ClientRectangle.Bottom) && (pt.Y - 40 > this.ClientRectangle.Top))
288 {
289 AutoDragStop();
290 }
291 }
292
[622]293 private void CalendarGrid_MouseDown(object sender, MouseEventArgs e)
294 {
[1106]295 //watch.Restart();
[622]296 if (e.Button == MouseButtons.Left)
297 {
298 foreach (DictionaryEntry entry in this.m_gridCells.CellHashTable)
299 {
300 CGCell cell = (CGCell) entry.Value;
301 cell.IsSelected = false;
302 }
303 this.m_selectedRange.Cells.ClearAllCells();
304 this.m_bMouseDown = true;
305 this.OnLButtonDown(e.X, e.Y, true);
306 }
[1143]307 //new code!!! smh 4/13/2011 -- refactor later
308
309 else if (e.Button == MouseButtons.Right)
310 {
311 // clear all selected cells, but ONLY if the the pointer is NOT over one of the cells in
312 // the selected range
313
314 int nRow = -1;
315 int nCol = -1;
316 CGCell cellFromRowCol = null;
317 bool _isCellInRange = false;
318 if (this.HitTest(e.X, e.Y, ref nRow, ref nCol))
319 {
320 cellFromRowCol = this.m_gridCells.GetCellFromRowCol(nRow, nCol);
321 }
322
323 if (cellFromRowCol != null)
324 _isCellInRange = this.m_selectedRange.CellIsInRange(cellFromRowCol);
325
326 if (!_isCellInRange)
327 {
328 foreach (DictionaryEntry entry in this.m_gridCells.CellHashTable)
329 {
330 CGCell cell = (CGCell)entry.Value;
331 cell.IsSelected = false;
332 }
333 this.m_selectedRange.Cells.ClearAllCells();
334 }
335
336 // clear all selected appointments
337 this.m_SelectedAppointments.ClearAllAppointments();
338 foreach (CGAppointment a in this.m_Appointments.AppointmentTable.Values) a.Selected = false;
339 this.m_nSelectID = 0;
340
341 OnRButtonDown(e.X, e.Y, _isCellInRange);
342 }
343
344 //end new code!!! /smh 4/13/2011
[622]345 }
346
347 private void CalendarGrid_MouseMove(object Sender, MouseEventArgs e)
348 {
[1106]349
350 //if the left mouse button is down and we are moving the mouse...
[622]351 if (this.m_bMouseDown)
352 {
[1106]353 //if Y axis is outside the top or bottom
[622]354 if ((e.Y >= base.ClientRectangle.Bottom) || (e.Y <= base.ClientRectangle.Top))
355 {
[1106]356 //start auto scrolling. m_bScrollDown decides whether we scroll up or down.
[622]357 this.m_bScrollDown = e.Y >= base.ClientRectangle.Bottom;
[1106]358 AutoDragStart();
[622]359 }
[1106]360
361 //if Y axis within client rectagle, stop dragging (whether you started or not)
[622]362 if ((e.Y < base.ClientRectangle.Bottom) && (e.Y > base.ClientRectangle.Top))
363 {
[1106]364 AutoDragStop();
[622]365 }
366 if (this.m_bSelectingRange)
367 {
368 this.OnLButtonDown(e.X, e.Y, false);
369 }
370 if (this.m_nSelectID != 0)
371 {
372 if (this.m_bGridEnter)
373 {
374 this.m_bGridEnter = false;
375 }
376 else if (!this.m_bDragDropStart)
377 {
378 CGAppointment data = (CGAppointment) this.m_Appointments.AppointmentTable[this.m_nSelectID];
379 this.ApptDragSource = "grid";
380 base.DoDragDrop(data, DragDropEffects.Move);
381 this.m_bDragDropStart = true;
382 }
[1143]383 }
[622]384 }
385 else
386 {
[1143]387
388 AutoDragStop(); //is this needed? //just in case maybe
389
390 //this code below displays the tooltip if we are moving the mouse over an appointment
[622]391 int y = e.Y - base.AutoScrollPosition.Y;
392 int x = e.X - base.AutoScrollPosition.X;
393 Point pt = new Point(x, y);
394 foreach (CGAppointment appointment2 in this.m_Appointments.AppointmentTable.Values)
395 {
396 if (appointment2.GridRectangle.Contains(pt))
397 {
398 this.m_toolTip.SetToolTip(this, appointment2.ToString());
399 return;
400 }
401 }
402 this.m_toolTip.RemoveAll();
403 }
404 }
405
406 private void CalendarGrid_MouseUp(object Sender, MouseEventArgs e)
407 {
408 if (this.m_bAutoDrag)
409 {
410 this.m_bAutoDrag = false;
411 this.AutoDragStop();
412 }
413 this.m_bMouseDown = false;
414 if (this.m_bSelectingRange)
415 {
416 CGSelectionChangedArgs args = new CGSelectionChangedArgs();
417 args.StartTime = this.GetTimeFromCell(this.m_selectedRange.StartCell);
418 args.EndTime = this.GetTimeFromCell(this.m_selectedRange.EndCell);
419 args.Resource = this.GetResourceFromColumn(this.m_selectedRange.StartCell.CellColumn);
420 if (args.EndTime < args.StartTime)
421 {
422 DateTime startTime = args.StartTime;
423 args.StartTime = args.EndTime;
424 args.EndTime = startTime;
425 }
426 TimeSpan span = new TimeSpan(0, 0, this.m_nTimeScale, 0, 0);
427 args.EndTime += span;
428 this.CGSelectionChanged(this, args);
429 this.m_bSelectingRange = false;
430 }
431 }
432
433 private void CalendarGrid_Paint(object sender, PaintEventArgs e)
434 {
435 if (e.Graphics != null)
436 {
437 this.DrawGrid(e.Graphics);
[1106]438 /*
[622]439 if (!this.m_bInitialUpdate)
440 {
441 this.SetAppointmentTypes();
442 base.Invalidate();
443 this.m_bInitialUpdate = true;
444 }
[1106]445 */
[622]446 }
447 }
448
449 public void CloseGrid()
450 {
451 foreach (CGAppointment appointment in this.m_Appointments.AppointmentTable.Values)
452 {
453 appointment.Selected = false;
454 }
455 this.m_nSelectID = 0;
456 }
457
458 protected override void Dispose(bool disposing)
459 {
460 if (disposing && (this.components != null))
461 {
462 this.components.Dispose();
463 }
464 base.Dispose(disposing);
465 }
466
467 private void DrawAppointments(Graphics g, int col0Width, int cellWidth, int cellHeight)
468 {
469 if (!base.DesignMode && (this.m_Appointments != null))
470 {
471 int num = 0;
472 int num2 = 0;
473 int x = 0;
474 ArrayList list = new ArrayList();
475 foreach (CGAppointment appointment in this.m_Appointments.AppointmentTable.Values)
476 {
477 bool bRet = false;
478 Rectangle rect = this.GetAppointmentRect(appointment, col0Width, cellWidth, cellHeight, out bRet);
479 if (bRet && (!appointment.WalkIn || this.m_bDrawWalkIns))
480 {
481 rect.Inflate(-10, 0);
[1174]482 num = (int) this.m_ApptOverlapTable[appointment.AppointmentKey];
[622]483 num2 = rect.Right - rect.Left;
484 x = num2 / (num + 1);
485 rect.Width = x;
486 if (num > 0)
487 {
488 foreach (object obj2 in list)
489 {
490 Rectangle rectangle2 = (Rectangle) obj2;
491 if (rect.IntersectsWith(rectangle2))
492 {
493 rect.Offset(x, 0);
494 }
495 }
496 }
497 appointment.GridRectangle = rect;
498 if (appointment.Selected)
499 {
500 Pen pen = new Pen(Brushes.Black, 5f);
501 g.DrawRectangle(pen, rect);
502 pen.Dispose();
503 }
504 else
505 {
506 g.DrawRectangle(Pens.Blue, rect);
507 }
508 string s = appointment.ToString();
509 Rectangle rectangle3 = new Rectangle(rect.X + 1, rect.Y + 1, rect.Width - 1, rect.Height - 1);
510 g.FillRectangle(Brushes.White, rectangle3);
511 Brush black = Brushes.Black;
512 if (appointment.CheckInTime.Ticks > 0L)
513 {
514 black = Brushes.Green;
515 g.FillRectangle(Brushes.LightGreen, rectangle3);
516 }
517 if (appointment.NoShow)
518 {
519 black = Brushes.Red;
520 g.FillRectangle(Brushes.LightPink, rectangle3);
521 }
522 if (appointment.WalkIn)
523 {
524 black = Brushes.Blue;
525 g.FillRectangle(Brushes.LightSteelBlue, rectangle3);
526 }
527 g.DrawString(s, this.fontArial8, black, rectangle3);
528 list.Add(rect);
529 }
530 }
531 }
532 }
533
534 private void DrawGrid(Graphics g)
535 {
[821]536 //Default color of grid lines is black
537 Pen pen = new Pen(Color.Black);
538
539 //each cell's height is Height of Arial Font 10pt + 10 pixels (by default 26 pixels)
540 SizeF ef = g.MeasureString("Test", this.m_fCell);
541 int num = 10;
542 this.m_cellHeight = ((int) ef.Height) + num;
543
544 // Number of columns is dynamic based on user of Grid. See Property Columns. Default 5 in init.
545 int nColumns = this.m_nColumns;
546
547 //Time scale is also dynamic. Property TimeScale. Default 20 (minutes)
548 //num3 stands for number of cells per hour
549 int num3 = 60 / this.m_nTimeScale;
550 //num4 stands for number of cells per day (aka rows in the grid)
551 int num4 = 24 * num3;
552 //Add extra column to hold time in the left hand corner
553 nColumns++;
554 //add extra row to represent dates or resources (depending on which view we are in)
555 //Not sure of which variable controls view yet.
556 num4++;
557
558 // 100 px is reserved no matter our column sizes for displaying the time scale
559
560 // Minimum cell width is 600/columns (100 px by default)
561 this.m_cellWidth = 600 / nColumns;
562
563 // if we happen to have more than 600 pixels in our Client Window then cell
564 // is (Width-100) / (number of date columns)
565 if (base.ClientRectangle.Width > 600)
[622]566 {
[821]567 this.m_cellWidth = (base.ClientRectangle.Width - this.m_col0Width) / (nColumns - 1);
568 }
569
570 // If we have one column, the cell width is the itself - 100
571 if (this.m_nColumns == 1)
572 {
573 this.m_cellWidth = base.ClientRectangle.Width - this.m_col0Width;
574 }
575
576 // Our rectangle will start scrolling if width is less than 600 and height less than height of all cells comb
577 // Of course Height will scroll all the time unless you have a humungous screen
578 base.AutoScrollMinSize = new Size(600, this.m_cellHeight * num4);
579
580 // Default Rectangle is Gray
581 g.FillRectangle(Brushes.LightGray, base.ClientRectangle);
582
583 int num5 = 0; //Minutes (start at 0)
584 int num6 = 0; //Hour (starts at 0)
585
586 // flag is true only if there are no cells what so ever in the screen
587 // Only true when no resource is selected.
[1143]588 bool noCellsFlag = this.m_gridCells.CellCount == 0;
[821]589
590 // Move the base point from the client screen to the scrolling region top-left corner.
591 g.TranslateTransform((float) base.AutoScrollPosition.X, (float) base.AutoScrollPosition.Y);
592
[846]593 // This for loop draws the time scale (although I haven't completely traced it out)
[821]594 // For each row except the first one (i starts from 1 rather than zero)
595 for (int i = 1; i < num4; i++)
596 {
597 int x = 0;
598 //point is (0, 1st Cell Start) then (0, 2nd Cell Start) until we run out
599 Point point = new Point(x, i * this.m_cellHeight);
600 //rectangle2 represents each cell rectangle
601 Rectangle rectangle2 = new Rectangle(point.X, point.Y, this.m_cellWidth, this.m_cellHeight);
602 //rect stands for the time scale rectangle; width is 100px; Height is length of the hour on grid
603 Rectangle rect = new Rectangle(0, rectangle2.Y, this.m_col0Width, rectangle2.Height * num3);
604 //height is length of hour
605 int height = rect.Height;
606 //Min font height is 25 pixels (100/4)--see below where it's used
607 height = (height > (this.m_col0Width / 4)) ? (this.m_col0Width / 4) : height;
608
609 //if we are the top of the time scale (at hour:00) -- num5 is min
610 if (num5 == 0)
[622]611 {
[821]612 // Fill time scale triangle with Gray (remember, this is the whole hour!)
613 g.FillRectangle(Brushes.LightGray, rect);
614 // Draw Rectangle
615 g.DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height);
616 //Pad time with at least one zero to make it 2 digits
617 string str = string.Format("{0}", num6).PadLeft(2, '0');
618 //Font height using pixels. Min is 25 pixels
619 Font font = new Font("Arial", (float) height, FontStyle.Bold, GraphicsUnit.Pixel);
620 // rectangle3 is the left half of the time rectangle
621 Rectangle rectangle3 = new Rectangle(rect.X, rect.Y, rect.Width / 2, rect.Height);
622 // In this left half, draw the hours (m_sfHour is the stringformat:
623 // Horizontal Center and Right Justified to rectangle3
624 g.DrawString(str, font, Brushes.Black, rectangle3, this.m_sfHour);
625 // Increment hour
626 num6++;
627 font.Dispose();
[622]628 }
[821]629
630 // Pad minutes with zeros to be 2 digits long
631 string s = string.Format("{0}", num5);
632 s = ":" + s.PadLeft(2, '0');
633 // Rectangle starts at
634 // X: 2/3rds of width of Time Rectangle
635 // Y: Top of the current time slot cell
636 // Width: 1/3rd of the width of the Time Rectangle
637 // Height: Height of a time slot
638 Rectangle layoutRectangle = new Rectangle(rect.X + ((rect.Width * 2) / 3), rectangle2.Top, rect.Width / 3, rectangle2.Height);
639 // At in this rectangle, write the minutes. Horizontal Ctr and Right Justified to Rectangle
640 g.DrawString(s, this.m_fCell, Brushes.Black, layoutRectangle, this.m_sfRight);
[846]641 // Draw Line from two points, just under the time we have just written
[821]642 Point point2 = new Point(rect.X + ((rect.Width * 2) / 3), rectangle2.Bottom);
643 Point point3 = new Point(rect.Right, rectangle2.Bottom);
644 g.DrawLine(pen, point2, point3);
[846]645 // Increment the minutes with the time scale
[821]646 num5 += this.m_nTimeScale;
[846]647 // If miniutes reaches 60, reset to zero
[821]648 num5 = (num5 >= 60) ? 0 : num5;
[846]649 // When we reach the bottom (num4 - 1 is # of rows) and we are not scrolling
[821]650 if ((i == (num4 - 1)) && !this.m_bScroll)
[622]651 {
[846]652 // Fill the last cell with Gray (?)
[821]653 g.TranslateTransform((float) -base.AutoScrollPosition.X, (float) -base.AutoScrollPosition.Y);
654 rect = new Rectangle(0, 0, this.m_col0Width, this.m_cellHeight);
655 g.FillRectangle(Brushes.LightGray, rect);
656 g.DrawRectangle(pen, rect);
657 g.TranslateTransform((float) base.AutoScrollPosition.X, (float) base.AutoScrollPosition.Y);
[622]658 }
[821]659 }
[846]660
661 //This for loop draws the cells
662 //Start from the bottom (num4 is # of rows) and go down to the zeroth row (ie date row/resource row)
[821]663 for (int j = num4; j > -1; j--)
664 {
[846]665 // For each column - 1 (we start at 1, not zero-->We drew the first column anyways in the 1st loop)
[821]666 for (int k = 1; k < nColumns; k++)
[622]667 {
[846]668 int num12 = 0; // X-axis position
669 if (k == 1) // If we are at the first column, start at 100px (default)
[622]670 {
[821]671 num12 = this.m_col0Width;
[622]672 }
[1143]673 if (k > 1) // if we are subsequent columns, adjust accordingly
[622]674 {
[821]675 num12 = this.m_col0Width + (this.m_cellWidth * (k - 1));
[622]676 }
[1143]677 //make a rectangle for the cell
[821]678 Point point4 = new Point(num12, j * this.m_cellHeight);
679 Rectangle r = new Rectangle(point4.X, point4.Y, this.m_cellWidth, this.m_cellHeight);
[1143]680 if (j != 0) // if we are not at the top (we are starting from the bottom)
[622]681 {
[1143]682 CGCell cellFromRowCol = null;
683 if (noCellsFlag) //if there are no cells, create the cell
[622]684 {
[821]685 cellFromRowCol = new CGCell(r, j, k);
686 this.m_gridCells.AddCell(cellFromRowCol);
[622]687 }
[1143]688 else // otherwise, get the cell from the m_gridCells array
[622]689 {
[821]690 cellFromRowCol = this.m_gridCells.GetCellFromRowCol(j, k);
691 cellFromRowCol.CellRectangle = r;
[622]692 }
[1143]693 if (this.m_sResourcesArray.Count > 0) // if we have any resources open
[622]694 {
[1106]695 //IMP
696 //this is the place where we the selected cells are drawn in Light Light Blue.
697 //IMP
[1143]698 // if cell is selected, draw it in Aquamarine (light light blue)
[821]699 if (this.m_selectedRange.CellIsInRange(cellFromRowCol))
[622]700 {
[821]701 g.FillRectangle(Brushes.Aquamarine, r);
[1106]702 //g.FillRectangle(Brushes.AntiqueWhite, r);
[622]703 }
[1143]704 // otherwise, draw it from Appointment Type Color set by BuildGridCellsArray()
[622]705 else
706 {
[821]707 g.FillRectangle(cellFromRowCol.AppointmentTypeColor, r);
[622]708 }
[1143]709 // finally the drawing
[821]710 g.DrawRectangle(pen, r.X, r.Y, r.Width, r.Height);
[1143]711 // once done with availabilities, draw the appointments
[821]712 if (j == 1)
[622]713 {
[821]714 this.DrawAppointments(g, this.m_col0Width, this.m_cellWidth, this.m_cellHeight);
[622]715 }
716 }
[821]717 continue;
718 }
[1143]719
720 //Below draws the top column either containing the dates or resources
[821]721 if (!this.m_bScroll)
722 {
723 g.TranslateTransform(0f, (float) -base.AutoScrollPosition.Y);
724 Rectangle rectangle6 = r;
725 g.FillRectangle(Brushes.LightBlue, rectangle6);
726 g.DrawRectangle(pen, rectangle6.X, rectangle6.Y, rectangle6.Width, rectangle6.Height);
727 string str3 = "";
728 if (this.m_sResourcesArray.Count > 1)
[622]729 {
[821]730 foreach (DictionaryEntry entry in this.m_ColumnInfoTable)
[622]731 {
[821]732 int num13 = (int) entry.Value;
733 num13++;
734 if (num13 == k)
[622]735 {
[821]736 str3 = entry.Key.ToString();
737 break;
[622]738 }
739 }
[821]740 }
741 else
742 {
743 DateTime dtStart = this.m_dtStart;
744 if (k > 1)
[622]745 {
[821]746 dtStart = dtStart.AddDays((double) (k - 1));
[622]747 }
[821]748 string format = "ddd, MMM d";
749 str3 = dtStart.ToString(format, DateTimeFormatInfo.InvariantInfo);
[622]750 }
[821]751 g.DrawString(str3, this.m_fCell, Brushes.Black, rectangle6, this.m_sf);
752 g.TranslateTransform(0f, (float) base.AutoScrollPosition.Y);
[622]753 }
754 }
755 }
[821]756 this.m_bScroll = false;
757 pen.Dispose();
[622]758 }
759
760 public Rectangle GetAppointmentRect(CGAppointment a, int col0Width, int cellWidth, int cellHeight, out bool bRet)
761 {
762 DateTime startTime = a.StartTime;
763 DateTime endTime = a.EndTime;
764 string resource = a.Resource;
[900]765 int originX = 0;
766 int originY = 0;
767 int recHeight = 0;
768 int recWidth = 0;
769 int columnToPutAppt = 0;
[622]770 Rectangle rectangle = new Rectangle();
[900]771 int startTotalMinutesoffset = (int) startTime.TimeOfDay.TotalMinutes;
772 int endTotalMinutesoffset = (int) endTime.TimeOfDay.TotalMinutes;
[1038]773
774 // To fix a bug with 1 day view: if the start time of appt is before Calendar Start Date, don't draw anything.
775 if (startTime < this.m_dtStart)
776 {
777 bRet = false;
778 return rectangle;
779 }
780
[900]781 // if grid has more than one reource
[622]782 if (this.m_sResourcesArray.Count > 1)
783 {
[900]784 // get zero based index
785 columnToPutAppt = (int) this.m_ColumnInfoTable[resource];
786 // increment to 1 based index
787 columnToPutAppt++;
[622]788 }
789 else
790 {
[900]791 columnToPutAppt = (startTime - this.m_dtStart).Days + 1;
[622]792 }
[1038]793 // this if should not get tripped; it did the same function as the new first if check.
794 //if (columnToPutAppt < 1)
795 //{
796 // bRet = false;
797 // return rectangle;
798 //}
[900]799 originX = col0Width + (cellWidth * (columnToPutAppt - 1));
800 int num8 = startTotalMinutesoffset + this.m_nTimeScale;
801 int num9 = (endTotalMinutesoffset > 0) ? endTotalMinutesoffset : 0x5a0;
802 num9 -= startTotalMinutesoffset;
803 originY = (cellHeight * num8) / this.m_nTimeScale;
804 recHeight = (cellHeight * num9) / this.m_nTimeScale;
805 recWidth = cellWidth;
806 rectangle.X = originX;
807 rectangle.Y = originY;
808 rectangle.Width = recWidth;
809 rectangle.Height = recHeight;
[622]810 bRet = true;
811 return rectangle;
812 }
813
[1123]814 /// <summary>
815 /// Translates a StartTime into a Cell, for coloring
816 /// </summary>
817 /// <param name="dDate"></param>
818 /// <param name="nRow"></param>
819 /// <param name="nCol"></param>
820 /// <param name="bStartCell"></param>
821 /// <param name="sResource"></param>
822 /// <returns></returns>
[622]823 public bool GetCellFromTime(DateTime dDate, ref int nRow, ref int nCol, bool bStartCell, string sResource)
824 {
825 int num = (dDate.Hour * 60) + dDate.Minute;
826 nRow = num / this.m_nTimeScale;
827 if (bStartCell)
828 {
829 nRow++;
830 }
831 if (this.m_sResourcesArray.Count > 1)
832 {
833 if (sResource == "")
834 {
835 sResource = this.m_sResourcesArray[0].ToString();
836 }
837 nCol = (int) this.m_ColumnInfoTable[sResource];
838 nCol++;
839 return true;
840 }
841 DateTime time = new DateTime(dDate.Year, dDate.Month, dDate.Day);
842 TimeSpan span = (TimeSpan) (time - this.StartDate);
843 int totalDays = 0;
844 totalDays = (int) span.TotalDays;
845 nCol = totalDays;
846 nCol++;
847 return true;
848 }
849
850 private string GetResourceFromColumn(int nCol)
851 {
852 if (this.m_sResourcesArray.Count == 1)
853 {
854 return this.m_sResourcesArray[0].ToString();
855 }
856 foreach (DictionaryEntry entry in this.m_ColumnInfoTable)
857 {
858 int num = (int) entry.Value;
859 num++;
860 if (num == nCol)
861 {
862 return entry.Key.ToString();
863 }
864 }
865 return "";
866 }
867
868 public bool GetSelectedTime(out DateTime dStart, out DateTime dEnd, out string sResource)
869 {
870 if (this.m_selectedRange.Cells.CellCount == 0)
871 {
872 dEnd = new DateTime();
873 dStart = dEnd;
874 sResource = "";
875 return false;
876 }
877 CGCell startCell = this.m_selectedRange.StartCell;
878 CGCell endCell = this.m_selectedRange.EndCell;
879 if (startCell.CellRow > endCell.CellRow)
880 {
881 CGCell cell3 = startCell;
882 startCell = endCell;
883 endCell = cell3;
884 }
885 dStart = this.GetTimeFromCell(startCell);
886 dEnd = this.GetTimeFromCell(endCell);
887 dEnd = dEnd.AddMinutes((double) this.m_nTimeScale);
888 sResource = this.GetResourceFromColumn(startCell.CellColumn);
889 return true;
890 }
891
892 public bool GetSelectedType(out int nAccessTypeID)
893 {
894 nAccessTypeID = 0;
895 if (this.m_selectedRange.Cells.CellCount == 0)
896 {
897 return false;
898 }
899 CGCell startCell = this.m_selectedRange.StartCell;
900 CGCell endCell = this.m_selectedRange.EndCell;
901 if (startCell.CellRow > endCell.CellRow)
902 {
903 CGCell cell3 = startCell;
904 startCell = endCell;
905 endCell = cell3;
906 }
907 DateTime timeFromCell = this.GetTimeFromCell(startCell);
908 DateTime time2 = this.GetTimeFromCell(endCell).AddMinutes((double) this.m_nTimeScale);
909 foreach (CGAvailability availability in this.m_pAvArray)
910 {
[1095]911 if (TimesOverlap(availability.StartTime, availability.EndTime, timeFromCell, time2))
[622]912 {
913 nAccessTypeID = availability.AvailabilityType;
914 break;
915 }
916 }
917 return (nAccessTypeID > 0);
918 }
919
920 public DateTime GetTimeFromCell(CGCell cgCell)
921 {
922 int cellRow = cgCell.CellRow;
923 int cellColumn = cgCell.CellColumn;
924 DateTime dtStart = this.m_dtStart;
925 int num3 = (cellRow - 1) * this.m_nTimeScale;
926 int num4 = num3 / 60;
927 if (num4 > 0)
928 {
929 num3 = num3 % (num4 * 60);
930 }
931 dtStart = dtStart.AddHours((double) num4).AddMinutes((double) num3);
932 if (this.m_sResourcesArray.Count == 1)
933 {
934 dtStart = dtStart.AddDays((double) (cellColumn - 1));
935 }
936 return dtStart;
937 }
938
939 public bool GetTypeFromCell(CGCell cgCell, out int nAccessTypeID)
940 {
941 nAccessTypeID = 0;
942 CGCell cell = cgCell;
943 CGCell cell2 = cgCell;
944 if (cell.CellRow > cell2.CellRow)
945 {
946 CGCell cell3 = cell;
947 cell = cell2;
948 cell2 = cell3;
949 }
950 DateTime timeFromCell = this.GetTimeFromCell(cell);
951 DateTime time2 = this.GetTimeFromCell(cell2).AddMinutes((double) this.m_nTimeScale);
952 foreach (CGAvailability availability in this.m_pAvArray)
953 {
[1095]954 if (TimesOverlap(availability.StartTime, availability.EndTime, timeFromCell, time2))
[622]955 {
956 nAccessTypeID = availability.AvailabilityType;
957 break;
958 }
959 }
960 return (nAccessTypeID > 0);
961 }
962
963 private bool HitTest(int X, int Y, ref int nRow, ref int nCol)
964 {
965 Y -= base.AutoScrollPosition.Y;
966 X -= base.AutoScrollPosition.X;
967 foreach (DictionaryEntry entry in this.m_gridCells)
968 {
969 CGCell cell = (CGCell) entry.Value;
970 if (cell.CellRectangle.Contains(X, Y))
971 {
972 nRow = cell.CellRow;
973 nCol = cell.CellColumn;
974 return true;
975 }
976 }
977 return false;
978 }
979
980 public void InitializeCalendarGrid()
981 {
982 this.AllowDrop = true;
983 }
984
985 private void InitializeComponent()
986 {
[821]987 this.components = new System.ComponentModel.Container();
988 this.m_toolTip = new System.Windows.Forms.ToolTip(this.components);
989 this.SuspendLayout();
990 //
991 // CalendarGrid
992 //
[622]993 this.AutoScroll = true;
[821]994 this.AutoScrollMinSize = new System.Drawing.Size(600, 400);
995 this.BackColor = System.Drawing.SystemColors.Window;
996 this.Paint += new System.Windows.Forms.PaintEventHandler(this.CalendarGrid_Paint);
997 this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.CalendarGrid_MouseMove);
998 this.DragDrop += new System.Windows.Forms.DragEventHandler(this.CalendarGrid_DragDrop);
999 this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.CalendarGrid_MouseDown);
1000 this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.CalendarGrid_MouseUp);
1001 this.DragEnter += new System.Windows.Forms.DragEventHandler(this.CalendarGrid_DragEnter);
[1143]1002 this.DragOver += new DragEventHandler(CalendarGrid_DragOver);
[821]1003 this.ResumeLayout(false);
1004
[622]1005 }
1006
[1143]1007
[1095]1008 private static int MinSince80(DateTime d)
[622]1009 {
[821]1010 DateTime time = new DateTime(1980, 1, 1, 0, 0, 0);
[622]1011 TimeSpan span = (TimeSpan) (d - time);
1012 return (int) span.TotalMinutes;
1013 }
1014
[1143]1015 //new code1!! smh 4/14/2011
1016 private void OnRButtonDown(int X, int Y, bool RangeAlreadySelected)
1017 {
1018 //if right mouse button is clicked, select an appointment if mouse hovers over one
1019 foreach (CGAppointment appointment3 in this.m_Appointments.AppointmentTable.Values)
1020 {
1021 int y = Y - base.AutoScrollPosition.Y;
1022 int x = X - base.AutoScrollPosition.X;
1023 Point pt = new Point(x, y);
1024
1025 if (!appointment3.GridRectangle.Contains(pt))
1026 {
1027 continue;
1028 }
1029 this.m_bMouseDown = false;
1030
1031 this.m_SelectedAppointments.AddAppointment(appointment3);
1032 appointment3.Selected = true;
1033 this.m_nSelectID = appointment3.AppointmentKey;
1034 //this.m_bGridEnter = true;
1035 }
1036
1037 // if we find an appointment, redraw the grid
1038 if (this.m_SelectedAppointments.AppointmentCount > 0)
1039 {
1040 base.Invalidate();
1041 return;
1042 }
1043
1044 // Otherwise, select a cell, but only if we don't don't have an existing range
1045 if (RangeAlreadySelected) return;
1046
1047 // Ok, select cell here
1048 int nRow = -1;
1049 int nCol = -1;
1050 if (this.HitTest(X, Y, ref nRow, ref nCol))
1051 {
1052 CGCell cellFromRowCol = this.m_gridCells.GetCellFromRowCol(nRow, nCol);
1053 if (cellFromRowCol != null)
1054 {
1055 this.m_currentCell = cellFromRowCol;
1056 this.m_selectedRange.StartCell = null;
1057 this.m_selectedRange.EndCell = null;
1058 this.m_selectedRange.CreateRange(this.m_gridCells, cellFromRowCol, cellFromRowCol);
1059
1060 cellFromRowCol.IsSelected = true;
1061 }
1062
1063 base.Invalidate();
1064 return;
1065 }
1066 }
1067
[622]1068 private void OnLButtonDown(int X, int Y, bool bStart)
1069 {
1070 this.m_bDragDropStart = false;
1071 this.m_nSelectID = 0;
1072 if (!this.m_bSelectingRange)
1073 {
1074 int y = Y - base.AutoScrollPosition.Y;
1075 int x = X - base.AutoScrollPosition.X;
1076 Point pt = new Point(x, y);
1077 if (Control.ModifierKeys == Keys.Control)
1078 {
1079 this.m_bMouseDown = false;
1080 foreach (CGAppointment appointment in this.m_Appointments.AppointmentTable.Values)
1081 {
1082 if (!appointment.GridRectangle.Contains(pt))
1083 {
1084 continue;
1085 }
1086 if (this.m_SelectedAppointments.AppointmentTable.ContainsKey(appointment.AppointmentKey))
1087 {
1088 this.m_SelectedAppointments.RemoveAppointment(appointment.AppointmentKey);
1089 if (this.m_SelectedAppointments.AppointmentTable.Count == 0)
1090 {
1091 this.m_nSelectID = 0;
1092 }
1093 else
1094 {
1095 foreach (CGAppointment appointment2 in this.m_Appointments.AppointmentTable.Values)
1096 {
1097 this.m_nSelectID = appointment2.AppointmentKey;
1098 }
1099 }
1100 }
1101 else
1102 {
1103 this.m_SelectedAppointments.AddAppointment(appointment);
1104 this.m_nSelectID = appointment.AppointmentKey;
1105 }
1106 appointment.Selected = !appointment.Selected;
1107 break;
1108 }
1109 base.Invalidate();
1110 return;
1111 }
1112 foreach (CGAppointment appointment3 in this.m_Appointments.AppointmentTable.Values)
1113 {
1114 if (!appointment3.GridRectangle.Contains(pt))
1115 {
1116 continue;
1117 }
1118 this.m_bMouseDown = false;
1119 if (appointment3.Selected)
1120 {
1121 appointment3.Selected = false;
1122 this.m_SelectedAppointments.ClearAllAppointments();
1123 this.m_nSelectID = 0;
1124 }
1125 else
1126 {
1127 foreach (CGAppointment appointment4 in this.m_Appointments.AppointmentTable.Values)
1128 {
1129 appointment4.Selected = false;
1130 }
1131 this.m_SelectedAppointments.ClearAllAppointments();
1132 this.m_SelectedAppointments.AddAppointment(appointment3);
1133 appointment3.Selected = true;
1134 this.m_nSelectID = appointment3.AppointmentKey;
1135 this.m_bMouseDown = true;
1136 this.m_bGridEnter = true;
1137 }
1138 base.Invalidate();
1139 return;
1140 }
1141 }
1142 int nRow = -1;
1143 int nCol = -1;
1144 if (this.HitTest(X, Y, ref nRow, ref nCol))
1145 {
1146 CGCell cellFromRowCol = this.m_gridCells.GetCellFromRowCol(nRow, nCol);
1147 if (cellFromRowCol != null)
1148 {
1149 if (bStart)
1150 {
1151 this.m_currentCell = cellFromRowCol;
1152 this.m_selectedRange.StartCell = null;
1153 this.m_selectedRange.EndCell = null;
1154 this.m_selectedRange.CreateRange(this.m_gridCells, cellFromRowCol, cellFromRowCol);
1155 bStart = false;
1156 this.m_bMouseDown = true;
1157 this.m_bSelectingRange = true;
1158 }
1159 else if (cellFromRowCol != this.m_currentCell)
1160 {
1161 if (!this.m_selectedRange.Cells.CellHashTable.ContainsKey(cellFromRowCol.Key))
1162 {
1163 this.m_selectedRange.AppendCell(this.m_gridCells, cellFromRowCol);
1164 }
1165 else
1166 {
1167 bool bUp = cellFromRowCol.CellRow < this.m_currentCell.CellRow;
1168 this.m_selectedRange.SubtractCell(this.m_gridCells, cellFromRowCol, bUp);
1169 }
1170 this.m_currentCell = cellFromRowCol;
1171 }
1172 cellFromRowCol.IsSelected = true;
1173 base.Invalidate();
1174 }
1175 }
1176 }
1177
1178 public void OnUpdateArrays()
1179 {
1180 try
1181 {
1182 this.m_gridCells.ClearAllCells();
1183 this.SetColumnInfo();
1184 this.SetOverlapTable();
1185 Graphics g = base.CreateGraphics();
1186 this.BuildGridCellsArray(g);
1187 this.SetAppointmentTypes();
1188 }
1189 catch (Exception exception)
1190 {
1191 string message = exception.Message;
1192 }
1193 }
1194
[1083]1195 /// <summary>
1196 /// Draws Availabilities. Draws Some of the Empty cells (don't know where the rest go) with the Khaki color
1197 /// </summary>
[622]1198 private void SetAppointmentTypes()
1199 {
1200 if (this.m_gridCells.CellCount != 0)
1201 {
[1143]1202 // this happens for the CGAVView Grid
[622]1203 foreach (DictionaryEntry entry in this.m_gridCells.CellHashTable)
1204 {
1205 CGCell cell = (CGCell) entry.Value;
1206 cell.AppointmentTypeColor = (this.m_GridBackColor == "blue") ? Brushes.CornflowerBlue : Brushes.Khaki;
1207 }
[1143]1208 // won't happen for CGAVView Grid b/c it has no availabilites
1209 // BUT, will happen for normal CGView Grid if there any availabilies
[622]1210 if ((this.m_pAvArray != null) && (this.m_pAvArray.Count != 0))
1211 {
1212 foreach (CGAvailability availability in this.m_pAvArray)
1213 {
1214 int nRow = 0;
1215 int nCol = 0;
1216 int num3 = 0;
1217 int num4 = 0;
[1143]1218 // pick the color from the availability
[622]1219 Brush brush = new SolidBrush(Color.FromArgb(availability.Red, availability.Green, availability.Blue));
[1143]1220 // get starting and ending cell
[622]1221 this.GetCellFromTime(availability.StartTime, ref nRow, ref nCol, true, availability.ResourceList);
1222 this.GetCellFromTime(availability.EndTime, ref num3, ref num4, false, availability.ResourceList);
[1143]1223 // for each of the range cells between starting and ending, change their color
[622]1224 for (int i = nCol; i <= num4; i++)
1225 {
1226 for (int j = nRow; (i == num4) && (j <= num3); j++)
1227 {
1228 string str = "r" + j.ToString() + "c" + i.ToString();
1229 CGCell cell2 = (CGCell) this.m_gridCells.CellHashTable[str];
1230 if (cell2 != null)
1231 {
1232 cell2.AppointmentTypeColor = brush;
1233 }
1234 }
1235 }
1236 }
1237 }
1238 }
1239 }
1240
1241 private void SetColumnInfo()
1242 {
1243 this.m_ColumnInfoTable.Clear();
1244 for (int i = 0; i < this.m_sResourcesArray.Count; i++)
1245 {
1246 this.m_ColumnInfoTable.Add(this.m_sResourcesArray[i], i);
1247 }
1248 if (this.m_sResourcesArray.Count > 1)
1249 {
1250 this.m_nColumns = this.m_sResourcesArray.Count;
1251 }
1252 }
1253
1254 public void SetOverlapTable()
1255 {
1256 Hashtable hashtable = new Hashtable();
1257 int y = 0;
1258 int num2 = 0;
1259 int x = 0;
1260 foreach (CGAppointment appointment in this.m_Appointments.AppointmentTable.Values)
1261 {
1262 if (!appointment.WalkIn || this.m_bDrawWalkIns)
1263 {
1264 string resource = appointment.Resource;
1265 y = appointment.StartTime.Minute + (60 * appointment.StartTime.Hour);
1266 num2 = appointment.EndTime.Minute + (60 * appointment.EndTime.Hour);
1267 x = (this.m_sResourcesArray.Count > 1) ? (((int) this.m_ColumnInfoTable[resource]) + 1) : appointment.StartTime.DayOfYear;
1268 Rectangle rectangle = new Rectangle(x, y, 1, num2 - y);
[1174]1269 hashtable.Add(appointment.AppointmentKey, rectangle);
[622]1270 }
1271 }
1272 this.m_ApptOverlapTable.Clear();
1273 foreach (int num4 in hashtable.Keys)
1274 {
1275 this.m_ApptOverlapTable.Add(num4, 0);
1276 }
[821]1277 // Here it draws the Dates on Top
[622]1278 if (this.m_ApptOverlapTable.Count != 0)
1279 {
1280 int num5 = (this.m_sResourcesArray.Count > 1) ? 1 : this.StartDate.DayOfYear;
1281 int num6 = (this.m_sResourcesArray.Count > 1) ? (this.m_sResourcesArray.Count + 1) : (this.Columns + this.StartDate.DayOfYear);
1282 for (int i = num5; i < num6; i++)
1283 {
1284 ArrayList list = new ArrayList();
1285 for (int j = 1; j < this.Rows; j++)
1286 {
1287 Rectangle rectangle2 = new Rectangle(i, j * this.m_nTimeScale, 1, this.m_nTimeScale);
1288 int num9 = -1;
1289 list.Clear();
1290 foreach (int num10 in hashtable.Keys)
1291 {
1292 Rectangle rect = (Rectangle) hashtable[num10];
1293 if (rectangle2.IntersectsWith(rect))
1294 {
1295 num9++;
1296 list.Add(num10);
1297 }
1298 }
1299 if (num9 > 0)
1300 {
1301 foreach (object obj2 in list)
1302 {
1303 int num11 = (int) obj2;
1304 if (((int) this.m_ApptOverlapTable[num11]) < num9)
1305 {
1306 this.m_ApptOverlapTable[num11] = num9;
1307 }
1308 }
1309 }
1310 }
1311 }
1312 }
1313 }
1314
[1106]1315 /// <summary>
1316 /// Handles scrolling when the mouse button is down
1317 /// </summary>
1318 /// <param name="o"></param>
1319 /// <param name="e"></param>
[622]1320 private void tickEventHandler(object o, EventArgs e)
1321 {
[1106]1322 //if there are still WM_TIME messages in the Queue after the timer is dead, don't do anything.
1323 if (this.m_Timer == null) return;
1324
[622]1325 Point point = new Point(base.AutoScrollPosition.X, base.AutoScrollPosition.Y);
1326 int x = point.X;
1327 int num = point.Y * -1;
[1106]1328 num = this.m_bScrollDown ? (num + 2) : (num - 2);
[622]1329 point.Y = num;
1330 base.AutoScrollPosition = point;
1331 base.Invalidate();
1332 }
1333
[1095]1334 /// <summary>
1335 /// Do 2 time ranges overlap each other?
1336 /// </summary>
1337 /// <param name="dStart1">First Start Time</param>
1338 /// <param name="dEnd1">First End Time</param>
1339 /// <param name="dStart2">Second Start Time</param>
1340 /// <param name="dEnd2">Second End Time</param>
1341 /// <returns>True or False</returns>
1342 public static bool TimesOverlap(DateTime dStart1, DateTime dEnd1, DateTime dStart2, DateTime dEnd2)
[622]1343 {
1344 long ticks = dEnd1.Ticks - dStart1.Ticks;
1345 TimeSpan ts = new TimeSpan(ticks);
1346 ticks = dEnd2.Ticks - dStart2.Ticks;
1347 new TimeSpan(ticks).Subtract(ts);
1348 Rectangle rect = new Rectangle();
1349 Rectangle rectangle2 = new Rectangle();
1350 rect.X = 0;
1351 rectangle2.X = 0;
1352 rect.Width = 1;
1353 rectangle2.Width = 1;
[1095]1354 rect.Y = MinSince80(dStart1);
1355 rect.Height = MinSince80(dEnd1) - rect.Y;
1356 rectangle2.Y = MinSince80(dStart2);
1357 rectangle2.Height = MinSince80(dEnd2) - rectangle2.Y;
[622]1358 return rectangle2.IntersectsWith(rect);
1359 }
1360
[1068]1361 public void PositionGrid(int nHour)
1362 {
1363 //Position grid to nHour
1364 int nRow = 0, nCol = 0;
1365 DateTime dStart = DateTime.Today;
1366 dStart = dStart.AddHours(nHour);
1367 this.GetCellFromTime(dStart, ref nRow, ref nCol, false, "");
1368 int nHeight = this.CellHeight + 10;
1369 nHeight *= nRow;
1370 this.AutoScrollPosition = new Point(50, nHeight);
1371 this.Invalidate();
1372 }
1373
1374
[821]1375 /// <summary>
1376 /// The purpose of this is to properly draw the date boxes at the top of the calendar grid.
1377 /// Otherwise, when scrolling, it gets garbled.
1378 /// </summary>
[1075]1379 /// <param name="msg">Handles three messages:
[821]1380 /// WM_VSCROLL (0x115 - Vertical Scrolling)
1381 /// WM_HSCROLL (0x114 - Horizontal Scrolling)
[1075]1382 /// WM_MOUSEWHEEL (0x20a - Mouse Wheel Movement)
[821]1383 /// </param>
[622]1384 protected override void WndProc(ref Message msg)
1385 {
1386 try
1387 {
[1075]1388 if (msg.Msg == WM_VSCROLL || msg.Msg == WM_MOUSEWHEEL)
[622]1389 {
1390 this.m_bScroll = true;
1391 base.Invalidate(false);
1392 this.m_bScroll = false;
1393 }
[821]1394 if (msg.Msg == WM_HSCROLL)
[622]1395 {
1396 base.Invalidate(false);
1397 }
1398 base.WndProc(ref msg);
1399 }
1400 catch (Exception exception)
1401 {
1402 MessageBox.Show("CalendarGrid::WndProc: " + exception.Message + "\nStack: " + exception.StackTrace);
1403 }
1404 }
1405
1406 public CGAppointments Appointments
1407 {
1408 get
1409 {
1410 return this.m_Appointments;
1411 }
1412 set
1413 {
1414 this.m_Appointments = value;
1415 }
1416 }
1417
1418 public string ApptDragSource
1419 {
1420 get
1421 {
1422 return this.m_sDragSource;
1423 }
1424 set
1425 {
1426 this.m_sDragSource = value;
1427 }
1428 }
1429
1430 public ArrayList AvailabilityArray
1431 {
1432 get
1433 {
1434 return this.m_pAvArray;
1435 }
1436 set
1437 {
1438 this.m_pAvArray = value;
1439 }
1440 }
1441
1442 public int CellHeight
1443 {
1444 get
1445 {
1446 return this.m_cellHeight;
1447 }
1448 }
1449
1450 public ToolTip CGToolTip
1451 {
1452 get
1453 {
1454 return this.m_toolTip;
1455 }
1456 }
1457
1458 public int Columns
1459 {
1460 get
1461 {
1462 return this.m_nColumns;
1463 }
1464 set
1465 {
1466 if ((value > 0) && (value < 11))
1467 {
1468 this.m_nColumns = value;
[1143]1469 //new line
1470 this.SetColumnInfo(); // redoes the columns if we have multiple resources
1471 //end new line
1472 this.m_gridCells.ClearAllCells(); //remove all cells
1473 this.m_selectedRange.Cells.ClearAllCells(); //remove selected range
[622]1474 Graphics g = base.CreateGraphics();
[1143]1475 this.BuildGridCellsArray(g); //rebuild the cells
1476 this.SetAppointmentTypes(); //set the colors on the cells for availabilities
1477 base.Invalidate(); //Fire paint to call DrawGrid
[622]1478 }
1479 }
1480 }
1481
1482 public bool DrawWalkIns
1483 {
1484 get
1485 {
1486 return this.m_bDrawWalkIns;
1487 }
1488 set
1489 {
1490 this.m_bDrawWalkIns = value;
1491 }
1492 }
1493
1494 public string GridBackColor
1495 {
1496 get
1497 {
1498 return this.m_GridBackColor;
1499 }
1500 set
1501 {
1502 this.m_GridBackColor = value;
1503 }
1504 }
1505
1506 public bool GridEnter
1507 {
1508 get
1509 {
1510 return this.m_bGridEnter;
1511 }
1512 set
1513 {
1514 this.m_bGridEnter = value;
1515 }
1516 }
1517
1518 public ArrayList Resources
1519 {
1520 get
1521 {
1522 return this.m_sResourcesArray;
1523 }
1524 set
1525 {
1526 this.m_sResourcesArray = value;
1527 }
1528 }
1529
1530 public int Rows
1531 {
1532 get
1533 {
1534 return (0x5a0 / this.m_nTimeScale);
1535 }
1536 }
1537
1538 public int SelectedAppointment
1539 {
1540 get
1541 {
1542 return this.m_nSelectID;
1543 }
1544 set
1545 {
1546 this.m_nSelectID = value;
1547 }
1548 }
1549
1550 public CGAppointments SelectedAppointments
1551 {
1552 get
1553 {
1554 return this.m_SelectedAppointments;
1555 }
1556 }
1557
1558 public CGRange SelectedRange
1559 {
1560 get
1561 {
1562 return this.m_selectedRange;
1563 }
1564 }
1565
1566 public DateTime StartDate
1567 {
1568 get
1569 {
1570 return this.m_dtStart;
1571 }
1572 set
1573 {
[1123]1574 //this.m_dtStart = value;
1575 this.m_dtStart = value.Date; // only date portion!!!//smh
[622]1576 }
1577 }
1578
1579 public int TimeScale
1580 {
1581 get
1582 {
1583 return this.m_nTimeScale;
1584 }
1585 set
1586 {
1587 if ((((value == 5) || (value == 10)) || ((value == 15) || (value == 20))) || ((value == 30) || (value == 60)))
1588 {
1589 this.m_nTimeScale = value;
1590 this.m_gridCells.ClearAllCells();
1591 this.m_selectedRange.Cells.ClearAllCells();
1592 Graphics g = base.CreateGraphics();
1593 this.BuildGridCellsArray(g);
1594 this.SetAppointmentTypes();
1595 base.Invalidate();
1596 }
1597 }
1598 }
[821]1599
[622]1600 }
1601}
1602
Note: See TracBrowser for help on using the repository browser.