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

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

Support for different encodings besides ASCII.
Minor bug fixes dealing with internationalization of dates.

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