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

Last change on this file since 940 was 900, checked in by Sam Habiel, 14 years ago
  1. Fix bug of not showing appointments in 7 day view if arabic locale on machine.
  2. Fix printing of routing slip (add clinic and fix appointment time and HRN)
  3. Add RTL support for letters printed in Arabic Locale.
File size: 54.7 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 // 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 }
681 if (columnToPutAppt < 1)
682 {
683 bRet = false;
684 return rectangle;
685 }
686 originX = col0Width + (cellWidth * (columnToPutAppt - 1));
687 int num8 = startTotalMinutesoffset + this.m_nTimeScale;
688 int num9 = (endTotalMinutesoffset > 0) ? endTotalMinutesoffset : 0x5a0;
689 num9 -= startTotalMinutesoffset;
690 originY = (cellHeight * num8) / this.m_nTimeScale;
691 recHeight = (cellHeight * num9) / this.m_nTimeScale;
692 recWidth = cellWidth;
693 rectangle.X = originX;
694 rectangle.Y = originY;
695 rectangle.Width = recWidth;
696 rectangle.Height = recHeight;
697 bRet = true;
698 return rectangle;
699 }
700
701 public bool GetCellFromTime(DateTime dDate, ref int nRow, ref int nCol, bool bStartCell, string sResource)
702 {
703 int num = (dDate.Hour * 60) + dDate.Minute;
704 nRow = num / this.m_nTimeScale;
705 if (bStartCell)
706 {
707 nRow++;
708 }
709 if (this.m_sResourcesArray.Count > 1)
710 {
711 if (sResource == "")
712 {
713 sResource = this.m_sResourcesArray[0].ToString();
714 }
715 nCol = (int) this.m_ColumnInfoTable[sResource];
716 nCol++;
717 return true;
718 }
719 DateTime time = new DateTime(dDate.Year, dDate.Month, dDate.Day);
720 TimeSpan span = (TimeSpan) (time - this.StartDate);
721 int totalDays = 0;
722 totalDays = (int) span.TotalDays;
723 nCol = totalDays;
724 nCol++;
725 return true;
726 }
727
728 private string GetResourceFromColumn(int nCol)
729 {
730 if (this.m_sResourcesArray.Count == 1)
731 {
732 return this.m_sResourcesArray[0].ToString();
733 }
734 foreach (DictionaryEntry entry in this.m_ColumnInfoTable)
735 {
736 int num = (int) entry.Value;
737 num++;
738 if (num == nCol)
739 {
740 return entry.Key.ToString();
741 }
742 }
743 return "";
744 }
745
746 public bool GetSelectedTime(out DateTime dStart, out DateTime dEnd, out string sResource)
747 {
748 if (this.m_selectedRange.Cells.CellCount == 0)
749 {
750 dEnd = new DateTime();
751 dStart = dEnd;
752 sResource = "";
753 return false;
754 }
755 CGCell startCell = this.m_selectedRange.StartCell;
756 CGCell endCell = this.m_selectedRange.EndCell;
757 if (startCell.CellRow > endCell.CellRow)
758 {
759 CGCell cell3 = startCell;
760 startCell = endCell;
761 endCell = cell3;
762 }
763 dStart = this.GetTimeFromCell(startCell);
764 dEnd = this.GetTimeFromCell(endCell);
765 dEnd = dEnd.AddMinutes((double) this.m_nTimeScale);
766 sResource = this.GetResourceFromColumn(startCell.CellColumn);
767 return true;
768 }
769
770 public bool GetSelectedType(out int nAccessTypeID)
771 {
772 nAccessTypeID = 0;
773 if (this.m_selectedRange.Cells.CellCount == 0)
774 {
775 return false;
776 }
777 CGCell startCell = this.m_selectedRange.StartCell;
778 CGCell endCell = this.m_selectedRange.EndCell;
779 if (startCell.CellRow > endCell.CellRow)
780 {
781 CGCell cell3 = startCell;
782 startCell = endCell;
783 endCell = cell3;
784 }
785 DateTime timeFromCell = this.GetTimeFromCell(startCell);
786 DateTime time2 = this.GetTimeFromCell(endCell).AddMinutes((double) this.m_nTimeScale);
787 foreach (CGAvailability availability in this.m_pAvArray)
788 {
789 if (this.TimesOverlap(availability.StartTime, availability.EndTime, timeFromCell, time2))
790 {
791 nAccessTypeID = availability.AvailabilityType;
792 break;
793 }
794 }
795 return (nAccessTypeID > 0);
796 }
797
798 public DateTime GetTimeFromCell(CGCell cgCell)
799 {
800 int cellRow = cgCell.CellRow;
801 int cellColumn = cgCell.CellColumn;
802 DateTime dtStart = this.m_dtStart;
803 int num3 = (cellRow - 1) * this.m_nTimeScale;
804 int num4 = num3 / 60;
805 if (num4 > 0)
806 {
807 num3 = num3 % (num4 * 60);
808 }
809 dtStart = dtStart.AddHours((double) num4).AddMinutes((double) num3);
810 if (this.m_sResourcesArray.Count == 1)
811 {
812 dtStart = dtStart.AddDays((double) (cellColumn - 1));
813 }
814 return dtStart;
815 }
816
817 public bool GetTypeFromCell(CGCell cgCell, out int nAccessTypeID)
818 {
819 nAccessTypeID = 0;
820 CGCell cell = cgCell;
821 CGCell cell2 = cgCell;
822 if (cell.CellRow > cell2.CellRow)
823 {
824 CGCell cell3 = cell;
825 cell = cell2;
826 cell2 = cell3;
827 }
828 DateTime timeFromCell = this.GetTimeFromCell(cell);
829 DateTime time2 = this.GetTimeFromCell(cell2).AddMinutes((double) this.m_nTimeScale);
830 foreach (CGAvailability availability in this.m_pAvArray)
831 {
832 if (this.TimesOverlap(availability.StartTime, availability.EndTime, timeFromCell, time2))
833 {
834 nAccessTypeID = availability.AvailabilityType;
835 break;
836 }
837 }
838 return (nAccessTypeID > 0);
839 }
840
841 private bool HitTest(int X, int Y, ref int nRow, ref int nCol)
842 {
843 Y -= base.AutoScrollPosition.Y;
844 X -= base.AutoScrollPosition.X;
845 foreach (DictionaryEntry entry in this.m_gridCells)
846 {
847 CGCell cell = (CGCell) entry.Value;
848 if (cell.CellRectangle.Contains(X, Y))
849 {
850 nRow = cell.CellRow;
851 nCol = cell.CellColumn;
852 return true;
853 }
854 }
855 return false;
856 }
857
858 public void InitializeCalendarGrid()
859 {
860 this.AllowDrop = true;
861 }
862
863 private void InitializeComponent()
864 {
865 this.components = new System.ComponentModel.Container();
866 this.m_toolTip = new System.Windows.Forms.ToolTip(this.components);
867 this.SuspendLayout();
868 //
869 // CalendarGrid
870 //
871 this.AutoScroll = true;
872 this.AutoScrollMinSize = new System.Drawing.Size(600, 400);
873 this.BackColor = System.Drawing.SystemColors.Window;
874 this.Paint += new System.Windows.Forms.PaintEventHandler(this.CalendarGrid_Paint);
875 this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.CalendarGrid_MouseMove);
876 this.DragDrop += new System.Windows.Forms.DragEventHandler(this.CalendarGrid_DragDrop);
877 this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.CalendarGrid_MouseDown);
878 this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.CalendarGrid_MouseUp);
879 this.DragEnter += new System.Windows.Forms.DragEventHandler(this.CalendarGrid_DragEnter);
880 this.ResumeLayout(false);
881
882 }
883
884 private int MinSince80(DateTime d)
885 {
886 DateTime time = new DateTime(1980, 1, 1, 0, 0, 0);
887 TimeSpan span = (TimeSpan) (d - time);
888 return (int) span.TotalMinutes;
889 }
890
891 private void OnLButtonDown(int X, int Y, bool bStart)
892 {
893 this.m_bDragDropStart = false;
894 this.m_nSelectID = 0;
895 if (!this.m_bSelectingRange)
896 {
897 int y = Y - base.AutoScrollPosition.Y;
898 int x = X - base.AutoScrollPosition.X;
899 Point pt = new Point(x, y);
900 if (Control.ModifierKeys == Keys.Control)
901 {
902 this.m_bMouseDown = false;
903 foreach (CGAppointment appointment in this.m_Appointments.AppointmentTable.Values)
904 {
905 if (!appointment.GridRectangle.Contains(pt))
906 {
907 continue;
908 }
909 if (this.m_SelectedAppointments.AppointmentTable.ContainsKey(appointment.AppointmentKey))
910 {
911 this.m_SelectedAppointments.RemoveAppointment(appointment.AppointmentKey);
912 if (this.m_SelectedAppointments.AppointmentTable.Count == 0)
913 {
914 this.m_nSelectID = 0;
915 }
916 else
917 {
918 foreach (CGAppointment appointment2 in this.m_Appointments.AppointmentTable.Values)
919 {
920 this.m_nSelectID = appointment2.AppointmentKey;
921 }
922 }
923 }
924 else
925 {
926 this.m_SelectedAppointments.AddAppointment(appointment);
927 this.m_nSelectID = appointment.AppointmentKey;
928 }
929 appointment.Selected = !appointment.Selected;
930 break;
931 }
932 base.Invalidate();
933 return;
934 }
935 foreach (CGAppointment appointment3 in this.m_Appointments.AppointmentTable.Values)
936 {
937 if (!appointment3.GridRectangle.Contains(pt))
938 {
939 continue;
940 }
941 this.m_bMouseDown = false;
942 if (appointment3.Selected)
943 {
944 appointment3.Selected = false;
945 this.m_SelectedAppointments.ClearAllAppointments();
946 this.m_nSelectID = 0;
947 }
948 else
949 {
950 foreach (CGAppointment appointment4 in this.m_Appointments.AppointmentTable.Values)
951 {
952 appointment4.Selected = false;
953 }
954 this.m_SelectedAppointments.ClearAllAppointments();
955 this.m_SelectedAppointments.AddAppointment(appointment3);
956 appointment3.Selected = true;
957 this.m_nSelectID = appointment3.AppointmentKey;
958 this.m_bMouseDown = true;
959 this.m_bGridEnter = true;
960 }
961 base.Invalidate();
962 return;
963 }
964 }
965 int nRow = -1;
966 int nCol = -1;
967 if (this.HitTest(X, Y, ref nRow, ref nCol))
968 {
969 CGCell cellFromRowCol = this.m_gridCells.GetCellFromRowCol(nRow, nCol);
970 if (cellFromRowCol != null)
971 {
972 if (bStart)
973 {
974 this.m_currentCell = cellFromRowCol;
975 this.m_selectedRange.StartCell = null;
976 this.m_selectedRange.EndCell = null;
977 this.m_selectedRange.CreateRange(this.m_gridCells, cellFromRowCol, cellFromRowCol);
978 bStart = false;
979 this.m_bMouseDown = true;
980 this.m_bSelectingRange = true;
981 }
982 else if (cellFromRowCol != this.m_currentCell)
983 {
984 if (!this.m_selectedRange.Cells.CellHashTable.ContainsKey(cellFromRowCol.Key))
985 {
986 this.m_selectedRange.AppendCell(this.m_gridCells, cellFromRowCol);
987 }
988 else
989 {
990 bool bUp = cellFromRowCol.CellRow < this.m_currentCell.CellRow;
991 this.m_selectedRange.SubtractCell(this.m_gridCells, cellFromRowCol, bUp);
992 }
993 this.m_currentCell = cellFromRowCol;
994 }
995 cellFromRowCol.IsSelected = true;
996 base.Invalidate();
997 }
998 }
999 }
1000
1001 public void OnUpdateArrays()
1002 {
1003 try
1004 {
1005 this.m_gridCells.ClearAllCells();
1006 this.SetColumnInfo();
1007 this.SetOverlapTable();
1008 Graphics g = base.CreateGraphics();
1009 this.BuildGridCellsArray(g);
1010 this.SetAppointmentTypes();
1011 }
1012 catch (Exception exception)
1013 {
1014 string message = exception.Message;
1015 }
1016 }
1017
1018 private void SetAppointmentTypes()
1019 {
1020 if (this.m_gridCells.CellCount != 0)
1021 {
1022 foreach (DictionaryEntry entry in this.m_gridCells.CellHashTable)
1023 {
1024 CGCell cell = (CGCell) entry.Value;
1025 cell.AppointmentTypeColor = (this.m_GridBackColor == "blue") ? Brushes.CornflowerBlue : Brushes.Khaki;
1026 }
1027 if ((this.m_pAvArray != null) && (this.m_pAvArray.Count != 0))
1028 {
1029 foreach (CGAvailability availability in this.m_pAvArray)
1030 {
1031 int nRow = 0;
1032 int nCol = 0;
1033 int num3 = 0;
1034 int num4 = 0;
1035 Brush brush = new SolidBrush(Color.FromArgb(availability.Red, availability.Green, availability.Blue));
1036 this.GetCellFromTime(availability.StartTime, ref nRow, ref nCol, true, availability.ResourceList);
1037 this.GetCellFromTime(availability.EndTime, ref num3, ref num4, false, availability.ResourceList);
1038 for (int i = nCol; i <= num4; i++)
1039 {
1040 for (int j = nRow; (i == num4) && (j <= num3); j++)
1041 {
1042 string str = "r" + j.ToString() + "c" + i.ToString();
1043 CGCell cell2 = (CGCell) this.m_gridCells.CellHashTable[str];
1044 if (cell2 != null)
1045 {
1046 cell2.AppointmentTypeColor = brush;
1047 }
1048 }
1049 }
1050 }
1051 }
1052 }
1053 }
1054
1055 private void SetColumnInfo()
1056 {
1057 this.m_ColumnInfoTable.Clear();
1058 for (int i = 0; i < this.m_sResourcesArray.Count; i++)
1059 {
1060 this.m_ColumnInfoTable.Add(this.m_sResourcesArray[i], i);
1061 }
1062 if (this.m_sResourcesArray.Count > 1)
1063 {
1064 this.m_nColumns = this.m_sResourcesArray.Count;
1065 }
1066 }
1067
1068 public void SetOverlapTable()
1069 {
1070 Hashtable hashtable = new Hashtable();
1071 int y = 0;
1072 int num2 = 0;
1073 int x = 0;
1074 foreach (CGAppointment appointment in this.m_Appointments.AppointmentTable.Values)
1075 {
1076 if (!appointment.WalkIn || this.m_bDrawWalkIns)
1077 {
1078 string resource = appointment.Resource;
1079 y = appointment.StartTime.Minute + (60 * appointment.StartTime.Hour);
1080 num2 = appointment.EndTime.Minute + (60 * appointment.EndTime.Hour);
1081 x = (this.m_sResourcesArray.Count > 1) ? (((int) this.m_ColumnInfoTable[resource]) + 1) : appointment.StartTime.DayOfYear;
1082 Rectangle rectangle = new Rectangle(x, y, 1, num2 - y);
1083 hashtable.Add(appointment.m_nKey, rectangle);
1084 }
1085 }
1086 this.m_ApptOverlapTable.Clear();
1087 foreach (int num4 in hashtable.Keys)
1088 {
1089 this.m_ApptOverlapTable.Add(num4, 0);
1090 }
1091 // Here it draws the Dates on Top
1092 if (this.m_ApptOverlapTable.Count != 0)
1093 {
1094 int num5 = (this.m_sResourcesArray.Count > 1) ? 1 : this.StartDate.DayOfYear;
1095 int num6 = (this.m_sResourcesArray.Count > 1) ? (this.m_sResourcesArray.Count + 1) : (this.Columns + this.StartDate.DayOfYear);
1096 for (int i = num5; i < num6; i++)
1097 {
1098 ArrayList list = new ArrayList();
1099 for (int j = 1; j < this.Rows; j++)
1100 {
1101 Rectangle rectangle2 = new Rectangle(i, j * this.m_nTimeScale, 1, this.m_nTimeScale);
1102 int num9 = -1;
1103 list.Clear();
1104 foreach (int num10 in hashtable.Keys)
1105 {
1106 Rectangle rect = (Rectangle) hashtable[num10];
1107 if (rectangle2.IntersectsWith(rect))
1108 {
1109 num9++;
1110 list.Add(num10);
1111 }
1112 }
1113 if (num9 > 0)
1114 {
1115 foreach (object obj2 in list)
1116 {
1117 int num11 = (int) obj2;
1118 if (((int) this.m_ApptOverlapTable[num11]) < num9)
1119 {
1120 this.m_ApptOverlapTable[num11] = num9;
1121 }
1122 }
1123 }
1124 }
1125 }
1126 }
1127 }
1128
1129 private void tickEventHandler(object o, EventArgs e)
1130 {
1131 Point point = new Point(base.AutoScrollPosition.X, base.AutoScrollPosition.Y);
1132 int x = point.X;
1133 int num = point.Y * -1;
1134 num = this.m_bScrollDown ? (num + 5) : (num - 5);
1135 point.Y = num;
1136 base.AutoScrollPosition = point;
1137 base.Invalidate();
1138 }
1139
1140 private bool TimesOverlap(DateTime dStart1, DateTime dEnd1, DateTime dStart2, DateTime dEnd2)
1141 {
1142 long ticks = dEnd1.Ticks - dStart1.Ticks;
1143 TimeSpan ts = new TimeSpan(ticks);
1144 ticks = dEnd2.Ticks - dStart2.Ticks;
1145 new TimeSpan(ticks).Subtract(ts);
1146 Rectangle rect = new Rectangle();
1147 Rectangle rectangle2 = new Rectangle();
1148 rect.X = 0;
1149 rectangle2.X = 0;
1150 rect.Width = 1;
1151 rectangle2.Width = 1;
1152 rect.Y = this.MinSince80(dStart1);
1153 rect.Height = this.MinSince80(dEnd1) - rect.Y;
1154 rectangle2.Y = this.MinSince80(dStart2);
1155 rectangle2.Height = this.MinSince80(dEnd2) - rectangle2.Y;
1156 return rectangle2.IntersectsWith(rect);
1157 }
1158
1159 /// <summary>
1160 /// The purpose of this is to properly draw the date boxes at the top of the calendar grid.
1161 /// Otherwise, when scrolling, it gets garbled.
1162 /// </summary>
1163 /// <param name="msg">Handles two messages:
1164 /// WM_VSCROLL (0x115 - Vertical Scrolling)
1165 /// WM_HSCROLL (0x114 - Horizontal Scrolling)
1166 /// </param>
1167 protected override void WndProc(ref Message msg)
1168 {
1169 try
1170 {
1171 if (msg.Msg == WM_VSCROLL)
1172 {
1173 this.m_bScroll = true;
1174 base.Invalidate(false);
1175 this.m_bScroll = false;
1176 }
1177 if (msg.Msg == WM_HSCROLL)
1178 {
1179 base.Invalidate(false);
1180 }
1181 base.WndProc(ref msg);
1182 }
1183 catch (Exception exception)
1184 {
1185 MessageBox.Show("CalendarGrid::WndProc: " + exception.Message + "\nStack: " + exception.StackTrace);
1186 }
1187 }
1188
1189 public CGAppointments Appointments
1190 {
1191 get
1192 {
1193 return this.m_Appointments;
1194 }
1195 set
1196 {
1197 this.m_Appointments = value;
1198 }
1199 }
1200
1201 public string ApptDragSource
1202 {
1203 get
1204 {
1205 return this.m_sDragSource;
1206 }
1207 set
1208 {
1209 this.m_sDragSource = value;
1210 }
1211 }
1212
1213 public ArrayList AvailabilityArray
1214 {
1215 get
1216 {
1217 return this.m_pAvArray;
1218 }
1219 set
1220 {
1221 this.m_pAvArray = value;
1222 }
1223 }
1224
1225 public int CellHeight
1226 {
1227 get
1228 {
1229 return this.m_cellHeight;
1230 }
1231 }
1232
1233 public ToolTip CGToolTip
1234 {
1235 get
1236 {
1237 return this.m_toolTip;
1238 }
1239 }
1240
1241 public int Columns
1242 {
1243 get
1244 {
1245 return this.m_nColumns;
1246 }
1247 set
1248 {
1249 if ((value > 0) && (value < 11))
1250 {
1251 this.m_nColumns = value;
1252 this.m_gridCells.ClearAllCells();
1253 this.m_selectedRange.Cells.ClearAllCells();
1254 Graphics g = base.CreateGraphics();
1255 this.BuildGridCellsArray(g);
1256 this.SetAppointmentTypes();
1257 base.Invalidate();
1258 }
1259 }
1260 }
1261
1262 public bool DrawWalkIns
1263 {
1264 get
1265 {
1266 return this.m_bDrawWalkIns;
1267 }
1268 set
1269 {
1270 this.m_bDrawWalkIns = value;
1271 }
1272 }
1273
1274 public string GridBackColor
1275 {
1276 get
1277 {
1278 return this.m_GridBackColor;
1279 }
1280 set
1281 {
1282 this.m_GridBackColor = value;
1283 }
1284 }
1285
1286 public bool GridEnter
1287 {
1288 get
1289 {
1290 return this.m_bGridEnter;
1291 }
1292 set
1293 {
1294 this.m_bGridEnter = value;
1295 }
1296 }
1297
1298 public ArrayList Resources
1299 {
1300 get
1301 {
1302 return this.m_sResourcesArray;
1303 }
1304 set
1305 {
1306 this.m_sResourcesArray = value;
1307 }
1308 }
1309
1310 public int Rows
1311 {
1312 get
1313 {
1314 return (0x5a0 / this.m_nTimeScale);
1315 }
1316 }
1317
1318 public int SelectedAppointment
1319 {
1320 get
1321 {
1322 return this.m_nSelectID;
1323 }
1324 set
1325 {
1326 this.m_nSelectID = value;
1327 }
1328 }
1329
1330 public CGAppointments SelectedAppointments
1331 {
1332 get
1333 {
1334 return this.m_SelectedAppointments;
1335 }
1336 }
1337
1338 public CGRange SelectedRange
1339 {
1340 get
1341 {
1342 return this.m_selectedRange;
1343 }
1344 }
1345
1346 public DateTime StartDate
1347 {
1348 get
1349 {
1350 return this.m_dtStart;
1351 }
1352 set
1353 {
1354 this.m_dtStart = value;
1355 }
1356 }
1357
1358 public int TimeScale
1359 {
1360 get
1361 {
1362 return this.m_nTimeScale;
1363 }
1364 set
1365 {
1366 if ((((value == 5) || (value == 10)) || ((value == 15) || (value == 20))) || ((value == 30) || (value == 60)))
1367 {
1368 this.m_nTimeScale = value;
1369 this.m_gridCells.ClearAllCells();
1370 this.m_selectedRange.Cells.ClearAllCells();
1371 Graphics g = base.CreateGraphics();
1372 this.BuildGridCellsArray(g);
1373 this.SetAppointmentTypes();
1374 base.Invalidate();
1375 }
1376 }
1377 }
1378
1379 }
1380}
1381
Note: See TracBrowser for help on using the repository browser.