source: Scheduling/branches/Radiology-Support/cs/bsdx0200GUISourceCode/CalendarGrid.cs@ 1168

Last change on this file since 1168 was 1168, checked in by Sam Habiel, 13 years ago

Lots of Documentation updates.
Absorption of all updates from trunk.
CGView: Changes in Appointment Menu; Handlers for these; Radiology Support
DRadExamSelect: Change in form design; auto print appointment slip implemented.

File size: 64.9 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 using System.Linq;
12
13 /// <summary>
14 /// This class is reponsible for rendering the Calendar Grid.
15 /// </summary>
16 public class CalendarGrid : ScrollableControl
17 {
18 private IContainer components;
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;
27 //private bool m_bInitialUpdate;
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;
52 private Timer m_Timer; // Timer used in Drag and Drop Operations
53 private ToolTip m_toolTip;
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
57 private System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
58
59
60 public delegate void CGAppointmentChangedHandler(object sender, CGAppointmentChangedArgs e);
61 public event CGAppointmentChangedHandler CGAppointmentChanged;
62 public event CGAppointmentChangedHandler CGAppointmentAdded;
63
64 public delegate void CGSelectionChangedHandler(object sender, CGSelectionChangedArgs e);
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();
77 //this.m_Appointments = new CGAppointments();
78 this.m_dtStart = new DateTime(2003, 1, 27);
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;
95 // this.m_bInitialUpdate = false;
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();
118 this.m_Timer.Tick -= new EventHandler(this.tickEventHandler);
119 this.m_Timer.Dispose();
120 this.m_Timer = null;
121 }
122 }
123
124 private void BuildGridCellsArray(Graphics g)
125 {
126 try
127 {
128 //calculate each cell's height
129 SizeF ef = g.MeasureString("Test", this.m_fCell);
130 this.m_cellHeight = ((int) ef.Height) + 4;
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:
141 if (base.ClientRectangle.Width > 600)
142 {
143 this.m_cellWidth = (base.ClientRectangle.Width - this.m_col0Width) / (nColumns - 1);
144 }
145 // if only one column
146 if (this.m_nColumns == 1)
147 {
148 this.m_cellWidth = base.ClientRectangle.Width - this.m_col0Width;
149 }
150 //next line seems to be useless (we don't use X and Y below)
151 g.TranslateTransform((float) base.AutoScrollPosition.X, (float) base.AutoScrollPosition.Y);
152
153 //now, build the grid cells
154 for (int i = slotsPerDay; i > -1; i--)
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
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
293 private void CalendarGrid_MouseDown(object sender, MouseEventArgs e)
294 {
295 //watch.Restart();
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 }
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
345 }
346
347 private void CalendarGrid_MouseMove(object Sender, MouseEventArgs e)
348 {
349
350 //if the left mouse button is down and we are moving the mouse...
351 if (this.m_bMouseDown)
352 {
353 //if Y axis is outside the top or bottom
354 if ((e.Y >= base.ClientRectangle.Bottom) || (e.Y <= base.ClientRectangle.Top))
355 {
356 //start auto scrolling. m_bScrollDown decides whether we scroll up or down.
357 this.m_bScrollDown = e.Y >= base.ClientRectangle.Bottom;
358 AutoDragStart();
359 }
360
361 //if Y axis within client rectagle, stop dragging (whether you started or not)
362 if ((e.Y < base.ClientRectangle.Bottom) && (e.Y > base.ClientRectangle.Top))
363 {
364 AutoDragStop();
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 }
383 }
384 }
385 else
386 {
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
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);
438 /*
439 if (!this.m_bInitialUpdate)
440 {
441 this.SetAppointmentTypes();
442 base.Invalidate();
443 this.m_bInitialUpdate = true;
444 }
445 */
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);
482 num = (int) this.m_ApptOverlapTable[appointment.AppointmentKey];
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 {
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)
566 {
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.
588 bool noCellsFlag = this.m_gridCells.CellCount == 0;
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
593 // This for loop draws the time scale (although I haven't completely traced it out)
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)
611 {
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();
628 }
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);
641 // Draw Line from two points, just under the time we have just written
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);
645 // Increment the minutes with the time scale
646 num5 += this.m_nTimeScale;
647 // If miniutes reaches 60, reset to zero
648 num5 = (num5 >= 60) ? 0 : num5;
649 // When we reach the bottom (num4 - 1 is # of rows) and we are not scrolling
650 if ((i == (num4 - 1)) && !this.m_bScroll)
651 {
652 // Fill the last cell with Gray (?)
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);
658 }
659 }
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)
663 for (int j = num4; j > -1; j--)
664 {
665 // For each column - 1 (we start at 1, not zero-->We drew the first column anyways in the 1st loop)
666 for (int k = 1; k < nColumns; k++)
667 {
668 int num12 = 0; // X-axis position
669 if (k == 1) // If we are at the first column, start at 100px (default)
670 {
671 num12 = this.m_col0Width;
672 }
673 if (k > 1) // if we are subsequent columns, adjust accordingly
674 {
675 num12 = this.m_col0Width + (this.m_cellWidth * (k - 1));
676 }
677 //make a rectangle for the cell
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);
680 if (j != 0) // if we are not at the top (we are starting from the bottom)
681 {
682 CGCell cellFromRowCol = null;
683 if (noCellsFlag) //if there are no cells, create the cell
684 {
685 cellFromRowCol = new CGCell(r, j, k);
686 this.m_gridCells.AddCell(cellFromRowCol);
687 }
688 else // otherwise, get the cell from the m_gridCells array
689 {
690 cellFromRowCol = this.m_gridCells.GetCellFromRowCol(j, k);
691 cellFromRowCol.CellRectangle = r;
692 }
693 if (this.m_sResourcesArray.Count > 0) // if we have any resources open
694 {
695 //IMP
696 //this is the place where we the selected cells are drawn in Light Light Blue.
697 //IMP
698 // if cell is selected, draw it in Aquamarine (light light blue)
699 if (this.m_selectedRange.CellIsInRange(cellFromRowCol))
700 {
701 g.FillRectangle(Brushes.Aquamarine, r);
702 //g.FillRectangle(Brushes.AntiqueWhite, r);
703 }
704 // otherwise, draw it from Appointment Type Color set by BuildGridCellsArray()
705 else
706 {
707 g.FillRectangle(cellFromRowCol.AppointmentTypeColor, r);
708 }
709 // finally the drawing
710 g.DrawRectangle(pen, r.X, r.Y, r.Width, r.Height);
711 // once done with availabilities, draw the appointments
712 if (j == 1)
713 {
714 this.DrawAppointments(g, this.m_col0Width, this.m_cellWidth, this.m_cellHeight);
715 }
716 }
717 continue;
718 }
719
720 //Below draws the top column either containing the dates or resources
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)
729 {
730 foreach (DictionaryEntry entry in this.m_ColumnInfoTable)
731 {
732 int num13 = (int) entry.Value;
733 num13++;
734 if (num13 == k)
735 {
736 str3 = entry.Key.ToString();
737 break;
738 }
739 }
740 }
741 else
742 {
743 DateTime dtStart = this.m_dtStart;
744 if (k > 1)
745 {
746 dtStart = dtStart.AddDays((double) (k - 1));
747 }
748 string format = "ddd, MMM d";
749 str3 = dtStart.ToString(format, DateTimeFormatInfo.InvariantInfo);
750 }
751 g.DrawString(str3, this.m_fCell, Brushes.Black, rectangle6, this.m_sf);
752 g.TranslateTransform(0f, (float) base.AutoScrollPosition.Y);
753 }
754 }
755 }
756 this.m_bScroll = false;
757 pen.Dispose();
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;
765 int originX = 0;
766 int originY = 0;
767 int recHeight = 0;
768 int recWidth = 0;
769 int columnToPutAppt = 0;
770 Rectangle rectangle = new Rectangle();
771 int startTotalMinutesoffset = (int) startTime.TimeOfDay.TotalMinutes;
772 int endTotalMinutesoffset = (int) endTime.TimeOfDay.TotalMinutes;
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
781 // if grid has more than one reource
782 if (this.m_sResourcesArray.Count > 1)
783 {
784 // get zero based index
785 columnToPutAppt = (int) this.m_ColumnInfoTable[resource];
786 // increment to 1 based index
787 columnToPutAppt++;
788 }
789 else
790 {
791 columnToPutAppt = (startTime - this.m_dtStart).Days + 1;
792 }
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 //}
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;
810 bRet = true;
811 return rectangle;
812 }
813
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>
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 {
911 if (TimesOverlap(availability.StartTime, availability.EndTime, timeFromCell, time2))
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 {
954 if (TimesOverlap(availability.StartTime, availability.EndTime, timeFromCell, time2))
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 {
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 //
993 this.AutoScroll = true;
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);
1002 this.DragOver += new DragEventHandler(CalendarGrid_DragOver);
1003 this.ResumeLayout(false);
1004
1005 }
1006
1007
1008 private static int MinSince80(DateTime d)
1009 {
1010 DateTime time = new DateTime(1980, 1, 1, 0, 0, 0);
1011 TimeSpan span = (TimeSpan) (d - time);
1012 return (int) span.TotalMinutes;
1013 }
1014
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
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
1195 /// <summary>
1196 /// Draws Availabilities. Draws Some of the Empty cells (don't know where the rest go) with the Khaki color
1197 /// </summary>
1198 private void SetAppointmentTypes()
1199 {
1200 if (this.m_gridCells.CellCount != 0)
1201 {
1202 // this happens for the CGAVView Grid
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 }
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
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;
1218 // pick the color from the availability
1219 Brush brush = new SolidBrush(Color.FromArgb(availability.Red, availability.Green, availability.Blue));
1220 // get starting and ending cell
1221 this.GetCellFromTime(availability.StartTime, ref nRow, ref nCol, true, availability.ResourceList);
1222 this.GetCellFromTime(availability.EndTime, ref num3, ref num4, false, availability.ResourceList);
1223 // for each of the range cells between starting and ending, change their color
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);
1269 hashtable.Add(appointment.AppointmentKey, rectangle);
1270 }
1271 }
1272 this.m_ApptOverlapTable.Clear();
1273 foreach (int num4 in hashtable.Keys)
1274 {
1275 this.m_ApptOverlapTable.Add(num4, 0);
1276 }
1277 // Here it draws the Dates on Top
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
1315 /// <summary>
1316 /// Handles scrolling when the mouse button is down
1317 /// </summary>
1318 /// <param name="o"></param>
1319 /// <param name="e"></param>
1320 private void tickEventHandler(object o, EventArgs e)
1321 {
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
1325 Point point = new Point(base.AutoScrollPosition.X, base.AutoScrollPosition.Y);
1326 int x = point.X;
1327 int num = point.Y * -1;
1328 num = this.m_bScrollDown ? (num + 2) : (num - 2);
1329 point.Y = num;
1330 base.AutoScrollPosition = point;
1331 base.Invalidate();
1332 }
1333
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)
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;
1354 rect.Y = MinSince80(dStart1);
1355 rect.Height = MinSince80(dEnd1) - rect.Y;
1356 rectangle2.Y = MinSince80(dStart2);
1357 rectangle2.Height = MinSince80(dEnd2) - rectangle2.Y;
1358 return rectangle2.IntersectsWith(rect);
1359 }
1360
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
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>
1379 /// <param name="msg">Handles three messages:
1380 /// WM_VSCROLL (0x115 - Vertical Scrolling)
1381 /// WM_HSCROLL (0x114 - Horizontal Scrolling)
1382 /// WM_MOUSEWHEEL (0x20a - Mouse Wheel Movement)
1383 /// </param>
1384 protected override void WndProc(ref Message msg)
1385 {
1386 try
1387 {
1388 if (msg.Msg == WM_VSCROLL || msg.Msg == WM_MOUSEWHEEL)
1389 {
1390 this.m_bScroll = true;
1391 base.Invalidate(false);
1392 this.m_bScroll = false;
1393 }
1394 if (msg.Msg == WM_HSCROLL)
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;
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
1474 Graphics g = base.CreateGraphics();
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
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 {
1574 //this.m_dtStart = value;
1575 this.m_dtStart = value.Date; // only date portion!!!//smh
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 }
1599
1600 }
1601}
1602
Note: See TracBrowser for help on using the repository browser.