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

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

Mostly commenting the code.

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