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

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

calendarGrid now inherits from ScrollableControl rather than Panel to support easy mouse scrolling. Don't know if this works on Windows XP yet.

File size: 54.8 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 : ScrollableControl
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 // This for loop draws the time scale (although I haven't completely traced it out)
501 // For each row except the first one (i starts from 1 rather than zero)
502 for (int i = 1; i < num4; i++)
503 {
504 int x = 0;
505 //point is (0, 1st Cell Start) then (0, 2nd Cell Start) until we run out
506 Point point = new Point(x, i * this.m_cellHeight);
507 //rectangle2 represents each cell rectangle
508 Rectangle rectangle2 = new Rectangle(point.X, point.Y, this.m_cellWidth, this.m_cellHeight);
509 //rect stands for the time scale rectangle; width is 100px; Height is length of the hour on grid
510 Rectangle rect = new Rectangle(0, rectangle2.Y, this.m_col0Width, rectangle2.Height * num3);
511 //height is length of hour
512 int height = rect.Height;
513 //Min font height is 25 pixels (100/4)--see below where it's used
514 height = (height > (this.m_col0Width / 4)) ? (this.m_col0Width / 4) : height;
515
516 //if we are the top of the time scale (at hour:00) -- num5 is min
517 if (num5 == 0)
518 {
519 // Fill time scale triangle with Gray (remember, this is the whole hour!)
520 g.FillRectangle(Brushes.LightGray, rect);
521 // Draw Rectangle
522 g.DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height);
523 //Pad time with at least one zero to make it 2 digits
524 string str = string.Format("{0}", num6).PadLeft(2, '0');
525 //Font height using pixels. Min is 25 pixels
526 Font font = new Font("Arial", (float) height, FontStyle.Bold, GraphicsUnit.Pixel);
527 // rectangle3 is the left half of the time rectangle
528 Rectangle rectangle3 = new Rectangle(rect.X, rect.Y, rect.Width / 2, rect.Height);
529 // In this left half, draw the hours (m_sfHour is the stringformat:
530 // Horizontal Center and Right Justified to rectangle3
531 g.DrawString(str, font, Brushes.Black, rectangle3, this.m_sfHour);
532 // Increment hour
533 num6++;
534 font.Dispose();
535 }
536
537 // Pad minutes with zeros to be 2 digits long
538 string s = string.Format("{0}", num5);
539 s = ":" + s.PadLeft(2, '0');
540 // Rectangle starts at
541 // X: 2/3rds of width of Time Rectangle
542 // Y: Top of the current time slot cell
543 // Width: 1/3rd of the width of the Time Rectangle
544 // Height: Height of a time slot
545 Rectangle layoutRectangle = new Rectangle(rect.X + ((rect.Width * 2) / 3), rectangle2.Top, rect.Width / 3, rectangle2.Height);
546 // At in this rectangle, write the minutes. Horizontal Ctr and Right Justified to Rectangle
547 g.DrawString(s, this.m_fCell, Brushes.Black, layoutRectangle, this.m_sfRight);
548 // Draw Line from two points, just under the time we have just written
549 Point point2 = new Point(rect.X + ((rect.Width * 2) / 3), rectangle2.Bottom);
550 Point point3 = new Point(rect.Right, rectangle2.Bottom);
551 g.DrawLine(pen, point2, point3);
552 // Increment the minutes with the time scale
553 num5 += this.m_nTimeScale;
554 // If miniutes reaches 60, reset to zero
555 num5 = (num5 >= 60) ? 0 : num5;
556 // When we reach the bottom (num4 - 1 is # of rows) and we are not scrolling
557 if ((i == (num4 - 1)) && !this.m_bScroll)
558 {
559 // Fill the last cell with Gray (?)
560 g.TranslateTransform((float) -base.AutoScrollPosition.X, (float) -base.AutoScrollPosition.Y);
561 rect = new Rectangle(0, 0, this.m_col0Width, this.m_cellHeight);
562 g.FillRectangle(Brushes.LightGray, rect);
563 g.DrawRectangle(pen, rect);
564 g.TranslateTransform((float) base.AutoScrollPosition.X, (float) base.AutoScrollPosition.Y);
565 }
566 }
567
568 //This for loop draws the cells
569 //Start from the bottom (num4 is # of rows) and go down to the zeroth row (ie date row/resource row)
570 for (int j = num4; j > -1; j--)
571 {
572 // For each column - 1 (we start at 1, not zero-->We drew the first column anyways in the 1st loop)
573 for (int k = 1; k < nColumns; k++)
574 {
575 int num12 = 0; // X-axis position
576 if (k == 1) // If we are at the first column, start at 100px (default)
577 {
578 num12 = this.m_col0Width;
579 }
580 if (k > 1) //
581 {
582 num12 = this.m_col0Width + (this.m_cellWidth * (k - 1));
583 }
584 Point point4 = new Point(num12, j * this.m_cellHeight);
585 Rectangle r = new Rectangle(point4.X, point4.Y, this.m_cellWidth, this.m_cellHeight);
586 if (j != 0)
587 {
588 CGCell cellFromRowCol = null;
589 if (flag)
590 {
591 cellFromRowCol = new CGCell(r, j, k);
592 this.m_gridCells.AddCell(cellFromRowCol);
593 }
594 else
595 {
596 cellFromRowCol = this.m_gridCells.GetCellFromRowCol(j, k);
597 cellFromRowCol.CellRectangle = r;
598 }
599 if (this.m_sResourcesArray.Count > 0)
600 {
601 if (this.m_selectedRange.CellIsInRange(cellFromRowCol))
602 {
603 g.FillRectangle(Brushes.Aquamarine, r);
604 }
605 else
606 {
607 g.FillRectangle(cellFromRowCol.AppointmentTypeColor, r);
608 }
609 g.DrawRectangle(pen, r.X, r.Y, r.Width, r.Height);
610 if (j == 1)
611 {
612 this.DrawAppointments(g, this.m_col0Width, this.m_cellWidth, this.m_cellHeight);
613 }
614 }
615 continue;
616 }
617 if (!this.m_bScroll)
618 {
619 g.TranslateTransform(0f, (float) -base.AutoScrollPosition.Y);
620 Rectangle rectangle6 = r;
621 g.FillRectangle(Brushes.LightBlue, rectangle6);
622 g.DrawRectangle(pen, rectangle6.X, rectangle6.Y, rectangle6.Width, rectangle6.Height);
623 string str3 = "";
624 if (this.m_sResourcesArray.Count > 1)
625 {
626 foreach (DictionaryEntry entry in this.m_ColumnInfoTable)
627 {
628 int num13 = (int) entry.Value;
629 num13++;
630 if (num13 == k)
631 {
632 str3 = entry.Key.ToString();
633 break;
634 }
635 }
636 }
637 else
638 {
639 DateTime dtStart = this.m_dtStart;
640 if (k > 1)
641 {
642 dtStart = dtStart.AddDays((double) (k - 1));
643 }
644 string format = "ddd, MMM d";
645 str3 = dtStart.ToString(format, DateTimeFormatInfo.InvariantInfo);
646 }
647 g.DrawString(str3, this.m_fCell, Brushes.Black, rectangle6, this.m_sf);
648 g.TranslateTransform(0f, (float) base.AutoScrollPosition.Y);
649 }
650 }
651 }
652 this.m_bScroll = false;
653 pen.Dispose();
654 }
655
656 public Rectangle GetAppointmentRect(CGAppointment a, int col0Width, int cellWidth, int cellHeight, out bool bRet)
657 {
658 DateTime startTime = a.StartTime;
659 DateTime endTime = a.EndTime;
660 string resource = a.Resource;
661 int originX = 0;
662 int originY = 0;
663 int recHeight = 0;
664 int recWidth = 0;
665 int columnToPutAppt = 0;
666 Rectangle rectangle = new Rectangle();
667 int startTotalMinutesoffset = (int) startTime.TimeOfDay.TotalMinutes;
668 int endTotalMinutesoffset = (int) endTime.TimeOfDay.TotalMinutes;
669 // if grid has more than one reource
670 if (this.m_sResourcesArray.Count > 1)
671 {
672 // get zero based index
673 columnToPutAppt = (int) this.m_ColumnInfoTable[resource];
674 // increment to 1 based index
675 columnToPutAppt++;
676 }
677 else
678 {
679 //columnToPutAppt = (startTime - this.m_dtStart).Days + 1;
680 //test sam
681 columnToPutAppt = (startTime - this.m_dtStart).Days + 1;
682 }
683 if (columnToPutAppt < 1)
684 {
685 bRet = false;
686 return rectangle;
687 }
688 originX = col0Width + (cellWidth * (columnToPutAppt - 1));
689 int num8 = startTotalMinutesoffset + this.m_nTimeScale;
690 int num9 = (endTotalMinutesoffset > 0) ? endTotalMinutesoffset : 0x5a0;
691 num9 -= startTotalMinutesoffset;
692 originY = (cellHeight * num8) / this.m_nTimeScale;
693 recHeight = (cellHeight * num9) / this.m_nTimeScale;
694 recWidth = cellWidth;
695 rectangle.X = originX;
696 rectangle.Y = originY;
697 rectangle.Width = recWidth;
698 rectangle.Height = recHeight;
699 bRet = true;
700 return rectangle;
701 }
702
703 public bool GetCellFromTime(DateTime dDate, ref int nRow, ref int nCol, bool bStartCell, string sResource)
704 {
705 int num = (dDate.Hour * 60) + dDate.Minute;
706 nRow = num / this.m_nTimeScale;
707 if (bStartCell)
708 {
709 nRow++;
710 }
711 if (this.m_sResourcesArray.Count > 1)
712 {
713 if (sResource == "")
714 {
715 sResource = this.m_sResourcesArray[0].ToString();
716 }
717 nCol = (int) this.m_ColumnInfoTable[sResource];
718 nCol++;
719 return true;
720 }
721 DateTime time = new DateTime(dDate.Year, dDate.Month, dDate.Day);
722 TimeSpan span = (TimeSpan) (time - this.StartDate);
723 int totalDays = 0;
724 totalDays = (int) span.TotalDays;
725 nCol = totalDays;
726 nCol++;
727 return true;
728 }
729
730 private string GetResourceFromColumn(int nCol)
731 {
732 if (this.m_sResourcesArray.Count == 1)
733 {
734 return this.m_sResourcesArray[0].ToString();
735 }
736 foreach (DictionaryEntry entry in this.m_ColumnInfoTable)
737 {
738 int num = (int) entry.Value;
739 num++;
740 if (num == nCol)
741 {
742 return entry.Key.ToString();
743 }
744 }
745 return "";
746 }
747
748 public bool GetSelectedTime(out DateTime dStart, out DateTime dEnd, out string sResource)
749 {
750 if (this.m_selectedRange.Cells.CellCount == 0)
751 {
752 dEnd = new DateTime();
753 dStart = dEnd;
754 sResource = "";
755 return false;
756 }
757 CGCell startCell = this.m_selectedRange.StartCell;
758 CGCell endCell = this.m_selectedRange.EndCell;
759 if (startCell.CellRow > endCell.CellRow)
760 {
761 CGCell cell3 = startCell;
762 startCell = endCell;
763 endCell = cell3;
764 }
765 dStart = this.GetTimeFromCell(startCell);
766 dEnd = this.GetTimeFromCell(endCell);
767 dEnd = dEnd.AddMinutes((double) this.m_nTimeScale);
768 sResource = this.GetResourceFromColumn(startCell.CellColumn);
769 return true;
770 }
771
772 public bool GetSelectedType(out int nAccessTypeID)
773 {
774 nAccessTypeID = 0;
775 if (this.m_selectedRange.Cells.CellCount == 0)
776 {
777 return false;
778 }
779 CGCell startCell = this.m_selectedRange.StartCell;
780 CGCell endCell = this.m_selectedRange.EndCell;
781 if (startCell.CellRow > endCell.CellRow)
782 {
783 CGCell cell3 = startCell;
784 startCell = endCell;
785 endCell = cell3;
786 }
787 DateTime timeFromCell = this.GetTimeFromCell(startCell);
788 DateTime time2 = this.GetTimeFromCell(endCell).AddMinutes((double) this.m_nTimeScale);
789 foreach (CGAvailability availability in this.m_pAvArray)
790 {
791 if (this.TimesOverlap(availability.StartTime, availability.EndTime, timeFromCell, time2))
792 {
793 nAccessTypeID = availability.AvailabilityType;
794 break;
795 }
796 }
797 return (nAccessTypeID > 0);
798 }
799
800 public DateTime GetTimeFromCell(CGCell cgCell)
801 {
802 int cellRow = cgCell.CellRow;
803 int cellColumn = cgCell.CellColumn;
804 DateTime dtStart = this.m_dtStart;
805 int num3 = (cellRow - 1) * this.m_nTimeScale;
806 int num4 = num3 / 60;
807 if (num4 > 0)
808 {
809 num3 = num3 % (num4 * 60);
810 }
811 dtStart = dtStart.AddHours((double) num4).AddMinutes((double) num3);
812 if (this.m_sResourcesArray.Count == 1)
813 {
814 dtStart = dtStart.AddDays((double) (cellColumn - 1));
815 }
816 return dtStart;
817 }
818
819 public bool GetTypeFromCell(CGCell cgCell, out int nAccessTypeID)
820 {
821 nAccessTypeID = 0;
822 CGCell cell = cgCell;
823 CGCell cell2 = cgCell;
824 if (cell.CellRow > cell2.CellRow)
825 {
826 CGCell cell3 = cell;
827 cell = cell2;
828 cell2 = cell3;
829 }
830 DateTime timeFromCell = this.GetTimeFromCell(cell);
831 DateTime time2 = this.GetTimeFromCell(cell2).AddMinutes((double) this.m_nTimeScale);
832 foreach (CGAvailability availability in this.m_pAvArray)
833 {
834 if (this.TimesOverlap(availability.StartTime, availability.EndTime, timeFromCell, time2))
835 {
836 nAccessTypeID = availability.AvailabilityType;
837 break;
838 }
839 }
840 return (nAccessTypeID > 0);
841 }
842
843 private bool HitTest(int X, int Y, ref int nRow, ref int nCol)
844 {
845 Y -= base.AutoScrollPosition.Y;
846 X -= base.AutoScrollPosition.X;
847 foreach (DictionaryEntry entry in this.m_gridCells)
848 {
849 CGCell cell = (CGCell) entry.Value;
850 if (cell.CellRectangle.Contains(X, Y))
851 {
852 nRow = cell.CellRow;
853 nCol = cell.CellColumn;
854 return true;
855 }
856 }
857 return false;
858 }
859
860 public void InitializeCalendarGrid()
861 {
862 this.AllowDrop = true;
863 }
864
865 private void InitializeComponent()
866 {
867 this.components = new System.ComponentModel.Container();
868 this.m_toolTip = new System.Windows.Forms.ToolTip(this.components);
869 this.SuspendLayout();
870 //
871 // CalendarGrid
872 //
873 this.AutoScroll = true;
874 this.AutoScrollMinSize = new System.Drawing.Size(600, 400);
875 this.BackColor = System.Drawing.SystemColors.Window;
876 this.Paint += new System.Windows.Forms.PaintEventHandler(this.CalendarGrid_Paint);
877 this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.CalendarGrid_MouseMove);
878 this.DragDrop += new System.Windows.Forms.DragEventHandler(this.CalendarGrid_DragDrop);
879 this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.CalendarGrid_MouseDown);
880 this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.CalendarGrid_MouseUp);
881 this.DragEnter += new System.Windows.Forms.DragEventHandler(this.CalendarGrid_DragEnter);
882 this.ResumeLayout(false);
883
884 }
885
886 private int MinSince80(DateTime d)
887 {
888 DateTime time = new DateTime(1980, 1, 1, 0, 0, 0);
889 TimeSpan span = (TimeSpan) (d - time);
890 return (int) span.TotalMinutes;
891 }
892
893 private void OnLButtonDown(int X, int Y, bool bStart)
894 {
895 this.m_bDragDropStart = false;
896 this.m_nSelectID = 0;
897 if (!this.m_bSelectingRange)
898 {
899 int y = Y - base.AutoScrollPosition.Y;
900 int x = X - base.AutoScrollPosition.X;
901 Point pt = new Point(x, y);
902 if (Control.ModifierKeys == Keys.Control)
903 {
904 this.m_bMouseDown = false;
905 foreach (CGAppointment appointment in this.m_Appointments.AppointmentTable.Values)
906 {
907 if (!appointment.GridRectangle.Contains(pt))
908 {
909 continue;
910 }
911 if (this.m_SelectedAppointments.AppointmentTable.ContainsKey(appointment.AppointmentKey))
912 {
913 this.m_SelectedAppointments.RemoveAppointment(appointment.AppointmentKey);
914 if (this.m_SelectedAppointments.AppointmentTable.Count == 0)
915 {
916 this.m_nSelectID = 0;
917 }
918 else
919 {
920 foreach (CGAppointment appointment2 in this.m_Appointments.AppointmentTable.Values)
921 {
922 this.m_nSelectID = appointment2.AppointmentKey;
923 }
924 }
925 }
926 else
927 {
928 this.m_SelectedAppointments.AddAppointment(appointment);
929 this.m_nSelectID = appointment.AppointmentKey;
930 }
931 appointment.Selected = !appointment.Selected;
932 break;
933 }
934 base.Invalidate();
935 return;
936 }
937 foreach (CGAppointment appointment3 in this.m_Appointments.AppointmentTable.Values)
938 {
939 if (!appointment3.GridRectangle.Contains(pt))
940 {
941 continue;
942 }
943 this.m_bMouseDown = false;
944 if (appointment3.Selected)
945 {
946 appointment3.Selected = false;
947 this.m_SelectedAppointments.ClearAllAppointments();
948 this.m_nSelectID = 0;
949 }
950 else
951 {
952 foreach (CGAppointment appointment4 in this.m_Appointments.AppointmentTable.Values)
953 {
954 appointment4.Selected = false;
955 }
956 this.m_SelectedAppointments.ClearAllAppointments();
957 this.m_SelectedAppointments.AddAppointment(appointment3);
958 appointment3.Selected = true;
959 this.m_nSelectID = appointment3.AppointmentKey;
960 this.m_bMouseDown = true;
961 this.m_bGridEnter = true;
962 }
963 base.Invalidate();
964 return;
965 }
966 }
967 int nRow = -1;
968 int nCol = -1;
969 if (this.HitTest(X, Y, ref nRow, ref nCol))
970 {
971 CGCell cellFromRowCol = this.m_gridCells.GetCellFromRowCol(nRow, nCol);
972 if (cellFromRowCol != null)
973 {
974 if (bStart)
975 {
976 this.m_currentCell = cellFromRowCol;
977 this.m_selectedRange.StartCell = null;
978 this.m_selectedRange.EndCell = null;
979 this.m_selectedRange.CreateRange(this.m_gridCells, cellFromRowCol, cellFromRowCol);
980 bStart = false;
981 this.m_bMouseDown = true;
982 this.m_bSelectingRange = true;
983 }
984 else if (cellFromRowCol != this.m_currentCell)
985 {
986 if (!this.m_selectedRange.Cells.CellHashTable.ContainsKey(cellFromRowCol.Key))
987 {
988 this.m_selectedRange.AppendCell(this.m_gridCells, cellFromRowCol);
989 }
990 else
991 {
992 bool bUp = cellFromRowCol.CellRow < this.m_currentCell.CellRow;
993 this.m_selectedRange.SubtractCell(this.m_gridCells, cellFromRowCol, bUp);
994 }
995 this.m_currentCell = cellFromRowCol;
996 }
997 cellFromRowCol.IsSelected = true;
998 base.Invalidate();
999 }
1000 }
1001 }
1002
1003 public void OnUpdateArrays()
1004 {
1005 try
1006 {
1007 this.m_gridCells.ClearAllCells();
1008 this.SetColumnInfo();
1009 this.SetOverlapTable();
1010 Graphics g = base.CreateGraphics();
1011 this.BuildGridCellsArray(g);
1012 this.SetAppointmentTypes();
1013 }
1014 catch (Exception exception)
1015 {
1016 string message = exception.Message;
1017 }
1018 }
1019
1020 private void SetAppointmentTypes()
1021 {
1022 if (this.m_gridCells.CellCount != 0)
1023 {
1024 foreach (DictionaryEntry entry in this.m_gridCells.CellHashTable)
1025 {
1026 CGCell cell = (CGCell) entry.Value;
1027 cell.AppointmentTypeColor = (this.m_GridBackColor == "blue") ? Brushes.CornflowerBlue : Brushes.Khaki;
1028 }
1029 if ((this.m_pAvArray != null) && (this.m_pAvArray.Count != 0))
1030 {
1031 foreach (CGAvailability availability in this.m_pAvArray)
1032 {
1033 int nRow = 0;
1034 int nCol = 0;
1035 int num3 = 0;
1036 int num4 = 0;
1037 Brush brush = new SolidBrush(Color.FromArgb(availability.Red, availability.Green, availability.Blue));
1038 this.GetCellFromTime(availability.StartTime, ref nRow, ref nCol, true, availability.ResourceList);
1039 this.GetCellFromTime(availability.EndTime, ref num3, ref num4, false, availability.ResourceList);
1040 for (int i = nCol; i <= num4; i++)
1041 {
1042 for (int j = nRow; (i == num4) && (j <= num3); j++)
1043 {
1044 string str = "r" + j.ToString() + "c" + i.ToString();
1045 CGCell cell2 = (CGCell) this.m_gridCells.CellHashTable[str];
1046 if (cell2 != null)
1047 {
1048 cell2.AppointmentTypeColor = brush;
1049 }
1050 }
1051 }
1052 }
1053 }
1054 }
1055 }
1056
1057 private void SetColumnInfo()
1058 {
1059 this.m_ColumnInfoTable.Clear();
1060 for (int i = 0; i < this.m_sResourcesArray.Count; i++)
1061 {
1062 this.m_ColumnInfoTable.Add(this.m_sResourcesArray[i], i);
1063 }
1064 if (this.m_sResourcesArray.Count > 1)
1065 {
1066 this.m_nColumns = this.m_sResourcesArray.Count;
1067 }
1068 }
1069
1070 public void SetOverlapTable()
1071 {
1072 Hashtable hashtable = new Hashtable();
1073 int y = 0;
1074 int num2 = 0;
1075 int x = 0;
1076 foreach (CGAppointment appointment in this.m_Appointments.AppointmentTable.Values)
1077 {
1078 if (!appointment.WalkIn || this.m_bDrawWalkIns)
1079 {
1080 string resource = appointment.Resource;
1081 y = appointment.StartTime.Minute + (60 * appointment.StartTime.Hour);
1082 num2 = appointment.EndTime.Minute + (60 * appointment.EndTime.Hour);
1083 x = (this.m_sResourcesArray.Count > 1) ? (((int) this.m_ColumnInfoTable[resource]) + 1) : appointment.StartTime.DayOfYear;
1084 Rectangle rectangle = new Rectangle(x, y, 1, num2 - y);
1085 hashtable.Add(appointment.m_nKey, rectangle);
1086 }
1087 }
1088 this.m_ApptOverlapTable.Clear();
1089 foreach (int num4 in hashtable.Keys)
1090 {
1091 this.m_ApptOverlapTable.Add(num4, 0);
1092 }
1093 // Here it draws the Dates on Top
1094 if (this.m_ApptOverlapTable.Count != 0)
1095 {
1096 int num5 = (this.m_sResourcesArray.Count > 1) ? 1 : this.StartDate.DayOfYear;
1097 int num6 = (this.m_sResourcesArray.Count > 1) ? (this.m_sResourcesArray.Count + 1) : (this.Columns + this.StartDate.DayOfYear);
1098 for (int i = num5; i < num6; i++)
1099 {
1100 ArrayList list = new ArrayList();
1101 for (int j = 1; j < this.Rows; j++)
1102 {
1103 Rectangle rectangle2 = new Rectangle(i, j * this.m_nTimeScale, 1, this.m_nTimeScale);
1104 int num9 = -1;
1105 list.Clear();
1106 foreach (int num10 in hashtable.Keys)
1107 {
1108 Rectangle rect = (Rectangle) hashtable[num10];
1109 if (rectangle2.IntersectsWith(rect))
1110 {
1111 num9++;
1112 list.Add(num10);
1113 }
1114 }
1115 if (num9 > 0)
1116 {
1117 foreach (object obj2 in list)
1118 {
1119 int num11 = (int) obj2;
1120 if (((int) this.m_ApptOverlapTable[num11]) < num9)
1121 {
1122 this.m_ApptOverlapTable[num11] = num9;
1123 }
1124 }
1125 }
1126 }
1127 }
1128 }
1129 }
1130
1131 private void tickEventHandler(object o, EventArgs e)
1132 {
1133 Point point = new Point(base.AutoScrollPosition.X, base.AutoScrollPosition.Y);
1134 int x = point.X;
1135 int num = point.Y * -1;
1136 num = this.m_bScrollDown ? (num + 5) : (num - 5);
1137 point.Y = num;
1138 base.AutoScrollPosition = point;
1139 base.Invalidate();
1140 }
1141
1142 private bool TimesOverlap(DateTime dStart1, DateTime dEnd1, DateTime dStart2, DateTime dEnd2)
1143 {
1144 long ticks = dEnd1.Ticks - dStart1.Ticks;
1145 TimeSpan ts = new TimeSpan(ticks);
1146 ticks = dEnd2.Ticks - dStart2.Ticks;
1147 new TimeSpan(ticks).Subtract(ts);
1148 Rectangle rect = new Rectangle();
1149 Rectangle rectangle2 = new Rectangle();
1150 rect.X = 0;
1151 rectangle2.X = 0;
1152 rect.Width = 1;
1153 rectangle2.Width = 1;
1154 rect.Y = this.MinSince80(dStart1);
1155 rect.Height = this.MinSince80(dEnd1) - rect.Y;
1156 rectangle2.Y = this.MinSince80(dStart2);
1157 rectangle2.Height = this.MinSince80(dEnd2) - rectangle2.Y;
1158 return rectangle2.IntersectsWith(rect);
1159 }
1160
1161 /// <summary>
1162 /// The purpose of this is to properly draw the date boxes at the top of the calendar grid.
1163 /// Otherwise, when scrolling, it gets garbled.
1164 /// </summary>
1165 /// <param name="msg">Handles two messages:
1166 /// WM_VSCROLL (0x115 - Vertical Scrolling)
1167 /// WM_HSCROLL (0x114 - Horizontal Scrolling)
1168 /// </param>
1169 protected override void WndProc(ref Message msg)
1170 {
1171 try
1172 {
1173 if (msg.Msg == WM_VSCROLL)
1174 {
1175 this.m_bScroll = true;
1176 base.Invalidate(false);
1177 this.m_bScroll = false;
1178 }
1179 if (msg.Msg == WM_HSCROLL)
1180 {
1181 base.Invalidate(false);
1182 }
1183 base.WndProc(ref msg);
1184 }
1185 catch (Exception exception)
1186 {
1187 MessageBox.Show("CalendarGrid::WndProc: " + exception.Message + "\nStack: " + exception.StackTrace);
1188 }
1189 }
1190
1191 public CGAppointments Appointments
1192 {
1193 get
1194 {
1195 return this.m_Appointments;
1196 }
1197 set
1198 {
1199 this.m_Appointments = value;
1200 }
1201 }
1202
1203 public string ApptDragSource
1204 {
1205 get
1206 {
1207 return this.m_sDragSource;
1208 }
1209 set
1210 {
1211 this.m_sDragSource = value;
1212 }
1213 }
1214
1215 public ArrayList AvailabilityArray
1216 {
1217 get
1218 {
1219 return this.m_pAvArray;
1220 }
1221 set
1222 {
1223 this.m_pAvArray = value;
1224 }
1225 }
1226
1227 public int CellHeight
1228 {
1229 get
1230 {
1231 return this.m_cellHeight;
1232 }
1233 }
1234
1235 public ToolTip CGToolTip
1236 {
1237 get
1238 {
1239 return this.m_toolTip;
1240 }
1241 }
1242
1243 public int Columns
1244 {
1245 get
1246 {
1247 return this.m_nColumns;
1248 }
1249 set
1250 {
1251 if ((value > 0) && (value < 11))
1252 {
1253 this.m_nColumns = value;
1254 this.m_gridCells.ClearAllCells();
1255 this.m_selectedRange.Cells.ClearAllCells();
1256 Graphics g = base.CreateGraphics();
1257 this.BuildGridCellsArray(g);
1258 this.SetAppointmentTypes();
1259 base.Invalidate();
1260 }
1261 }
1262 }
1263
1264 public bool DrawWalkIns
1265 {
1266 get
1267 {
1268 return this.m_bDrawWalkIns;
1269 }
1270 set
1271 {
1272 this.m_bDrawWalkIns = value;
1273 }
1274 }
1275
1276 public string GridBackColor
1277 {
1278 get
1279 {
1280 return this.m_GridBackColor;
1281 }
1282 set
1283 {
1284 this.m_GridBackColor = value;
1285 }
1286 }
1287
1288 public bool GridEnter
1289 {
1290 get
1291 {
1292 return this.m_bGridEnter;
1293 }
1294 set
1295 {
1296 this.m_bGridEnter = value;
1297 }
1298 }
1299
1300 public ArrayList Resources
1301 {
1302 get
1303 {
1304 return this.m_sResourcesArray;
1305 }
1306 set
1307 {
1308 this.m_sResourcesArray = value;
1309 }
1310 }
1311
1312 public int Rows
1313 {
1314 get
1315 {
1316 return (0x5a0 / this.m_nTimeScale);
1317 }
1318 }
1319
1320 public int SelectedAppointment
1321 {
1322 get
1323 {
1324 return this.m_nSelectID;
1325 }
1326 set
1327 {
1328 this.m_nSelectID = value;
1329 }
1330 }
1331
1332 public CGAppointments SelectedAppointments
1333 {
1334 get
1335 {
1336 return this.m_SelectedAppointments;
1337 }
1338 }
1339
1340 public CGRange SelectedRange
1341 {
1342 get
1343 {
1344 return this.m_selectedRange;
1345 }
1346 }
1347
1348 public DateTime StartDate
1349 {
1350 get
1351 {
1352 return this.m_dtStart;
1353 }
1354 set
1355 {
1356 this.m_dtStart = value;
1357 }
1358 }
1359
1360 public int TimeScale
1361 {
1362 get
1363 {
1364 return this.m_nTimeScale;
1365 }
1366 set
1367 {
1368 if ((((value == 5) || (value == 10)) || ((value == 15) || (value == 20))) || ((value == 30) || (value == 60)))
1369 {
1370 this.m_nTimeScale = value;
1371 this.m_gridCells.ClearAllCells();
1372 this.m_selectedRange.Cells.ClearAllCells();
1373 Graphics g = base.CreateGraphics();
1374 this.BuildGridCellsArray(g);
1375 this.SetAppointmentTypes();
1376 base.Invalidate();
1377 }
1378 }
1379 }
1380
1381 }
1382}
1383
Note: See TracBrowser for help on using the repository browser.