source: Scheduling/trunk/cs/bsdx0200GUISourceCode/Printing.cs@ 1474

Last change on this file since 1474 was 1474, checked in by Sam Habiel, 12 years ago

Finally, v 1.7 to the main repo. I will delete the branch after this.

This commit merges all the BMX4 changes in the Scheduling GUI back to the main trunk.

File size: 44.4 KB
Line 
1using System;
2using System.Drawing.Printing;
3using System.Drawing;
4using System.Text;
5using System.Drawing.Drawing2D;
6using System.Linq;
7using System.Data;
8
9namespace IndianHealthService.ClinicalScheduling
10{
11 public partial class Printing
12 {
13 /// <summary>
14 /// Print Appointments
15 /// </summary>
16 /// <param name="ds">Strongly Typed DataSet contains Resources and Appointments</param>
17 /// <param name="e">PrintPageEventArgs from PrintDocument Print handler</param>
18 /// <param name="beg">Begin Datetime to print appointments</param>
19 /// <param name="end">End Datetime to print appointments</param
20 /// <param name="resourceToPrint">The resouce to print</param>
21 /// <param name="apptPrinting">Current Appointment printing</param>
22 /// <param name="pageNumber">Current page number</param>
23 /// <remarks>beg and end have no effect on operation--they are there for documentation for user only</remarks>
24 public virtual void PrintAppointments(dsPatientApptDisplay2 ds, PrintPageEventArgs e, DateTime beg, DateTime end, int resourceToPrint, ref int apptPrinting, int pageNumber)
25 {
26 Graphics g = e.Graphics;
27 //g.PageUnit = GraphicsUnit.Millimeter;
28 //SizeF szVCB = g.VisibleClipBounds.Size;
29 //PointF[] ptszVCB = {new PointF(szVCB.Width,szVCB.Height)};
30 //g.TransformPoints(CoordinateSpace.Page, CoordinateSpace.Device, ptszVCB);
31 //Create Fonts
32 Font f8 = new Font(FontFamily.GenericSerif, 8);
33 Font f10 = new Font(FontFamily.GenericSerif, 10);
34 Font f14bold = new Font(FontFamily.GenericSerif, 14, FontStyle.Bold);
35
36 //Center Alignment for some stuff
37 StringFormat sf = new StringFormat();
38 sf.Alignment = StringAlignment.Center;
39
40 //Header
41 g.DrawString("Confidential Patient Information", f8, Brushes.Black, e.PageBounds, sf);
42
43 //Footer
44 sf.Alignment = StringAlignment.Center;
45 sf.LineAlignment = StringAlignment.Far;
46 g.DrawString("Page " + pageNumber, f8, Brushes.Black, e.PageBounds, sf);
47
48 //Typical manipulable print area
49 Rectangle printArea = e.MarginBounds;
50 Rectangle pageArea = e.PageBounds;
51 Rectangle headerArea = new Rectangle()
52 {
53 X = e.MarginBounds.X,
54 Y = e.PageBounds.Y,
55 Height = e.MarginBounds.Y - e.PageBounds.Y,
56 Width = e.MarginBounds.Width
57 };
58 Rectangle footerArea = new Rectangle()
59 {
60 X = e.MarginBounds.X,
61 Y = e.MarginBounds.Height + headerArea.Height,
62 Width = e.MarginBounds.Width,
63 Height = pageArea.Height - (e.MarginBounds.Height + headerArea.Height)
64 };
65
66 //print footer
67 StringFormat sfFooter = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
68 string s = strings.Printed + ": " + DateTime.Now.ToString();
69 Font fFooter = new Font(FontFamily.GenericSerif, 7);
70 g.DrawString(s, fFooter, Brushes.Black, footerArea, sfFooter);
71
72 //resource we want to print
73 dsPatientApptDisplay2.BSDXResourceRow r = ds.BSDXResource[resourceToPrint];
74
75 //header
76 string toprint;
77 if (beg.Date == end.Date) toprint = "Appointments for " + r.RESOURCE_NAME + " on " + beg.ToLongDateString();
78 else toprint = "Appointments for " + r.RESOURCE_NAME + " from " + beg.ToShortDateString() + " to "
79 + end.ToShortDateString();
80 g.DrawString(toprint, f14bold, Brushes.Black, printArea);
81
82 //Move print area down
83 int titleHeight = (int)g.MeasureString(toprint, f14bold, printArea.Size).Height;
84 printArea.Height -= titleHeight;
85 printArea.Y += titleHeight;
86
87 //Draw Line
88 g.DrawLine(new Pen(Brushes.Black, 0), printArea.X, printArea.Y, printArea.X + printArea.Width, printArea.Y);
89
90 //Move print area down
91 printArea.Y += 5;
92 printArea.Height -= 5;
93
94 System.Data.DataRow[] appts = r.GetChildRows(ds.Relations[0]); //ds has only one relation
95
96 StringFormat sf2 = new StringFormat(); //sf to hold tab stops
97 sf2.SetTabStops(50, new float[] { 100, 250, 25 });
98
99 //appt printed starts at zero
100 while (apptPrinting < appts.Length)
101 {
102 dsPatientApptDisplay2.PatientApptsRow a = (dsPatientApptDisplay2.PatientApptsRow)appts[apptPrinting];
103
104 StringBuilder apptPrintStr = new StringBuilder(200);
105 apptPrintStr.AppendLine(a.ApptDate.ToString() + "\t" + a.Name + " (" + a.Sex + ")" + "\t" + "DOB: " + a.DOB.ToShortDateString() + "\t" + "ID: " + a.HRN);
106 apptPrintStr.AppendLine("P: " + a.HOMEPHONE + "\t" + "Address: " + a.STREET + ", " + a.CITY + ", " + a.STATE + " " + a.ZIP);
107 apptPrintStr.AppendLine("Note: " + a.NOTE);
108 apptPrintStr.AppendLine("Appointment made by " + a.APPT_MADE_BY + " on " + a.DATE_APPT_MADE);
109
110 int printedApptHeight = (int)g.MeasureString(apptPrintStr.ToString(), f10, printArea.Width).Height;
111 if (printedApptHeight > printArea.Height) // too much to print -- move to next page
112 // but don't increment the appointment to print since we haven't printed it yet.
113 // i.e. apptPrinting stays the same.
114 {
115 e.HasMorePages = true;
116 break;
117 }
118
119 //otherwise print it
120 g.DrawString(apptPrintStr.ToString(), f10, Brushes.Black, printArea, sf2);
121
122 //Move print area down
123 printArea.Y += printedApptHeight + 3;
124 printArea.Height -= printedApptHeight + 3;
125
126 //Draw a divider line
127 Point pt1 = new Point((int)(printArea.X + printArea.Width * 0.25), printArea.Y);
128 Point pt2 = new Point((int)(printArea.X + printArea.Width * 0.75), printArea.Y);
129 g.DrawLine(Pens.Gray, pt1, pt2);
130
131 //move down, again
132 printArea.Y += 3;
133 printArea.Height -= 3;
134
135 //go to the next appointment
136 apptPrinting++;
137 }
138
139
140 g.Dispose();
141 }
142
143 /// <summary>
144 /// Prints a single appointment slip to give to the patient
145 /// </summary>
146 /// <param name="appt">The Appointment to print</param>
147 /// <param name="e">PrintPageEventArgs from PrintDocument Print handler</param>
148 public virtual void PrintAppointmentSlip(CGAppointment appt, PrintPageEventArgs e)
149 {
150 // setting the reference values for calculating the needed ratio of the coming page.
151 //referrenceHeight and referrenceWidth for A6 size.
152 double referrenceHeight = 383;
153 double referrenceWidth = 213;
154
155 //check if the paper is landscape or portrait. if it is landscape then new ratio need to be calculated.
156 if (e.MarginBounds.Width > e.MarginBounds.Height)
157 {
158 //landscape = true;
159 referrenceHeight = 213;
160 referrenceWidth = 383;
161 //fontRatio = ((e.MarginBounds.Height) / referrenceHeight);
162 }
163
164 //setting the font,width and height ratios
165 double fontRatio = (e.MarginBounds.Height / referrenceHeight);
166 if (fontRatio > 1.0)
167 {
168 fontRatio = fontRatio * 0.75;
169 }
170 double widthRatio = ((e.MarginBounds.Width) / referrenceWidth);
171 double heightRatio = ((e.MarginBounds.Height) / referrenceHeight);
172
173 Graphics g = e.Graphics;
174 //this is the string which is used to fill with the data and to be print on the screen.
175 string stringData;
176
177 //in portrait we used fonts that fits with the A6 paper and changed depending on the page ratio,but in the land scape we used fonts fits with the A5 paper and counted the other pages depening on the ratios.
178 Font fontTitle = new Font(FontFamily.GenericSerif, (int)(13 * fontRatio), FontStyle.Bold); //for title
179 Font fontBody = new Font(FontFamily.GenericSerif, (int)(13 * fontRatio));
180 Font fontGroupTitle = new Font(FontFamily.GenericSansSerif, (int)(13 * fontRatio), FontStyle.Bold);
181 Font fFooter = new Font(FontFamily.GenericSerif, (int)(7 * fontRatio));
182
183 StringFormat sfCenterNear = new StringFormat()
184 {
185 Alignment = StringAlignment.Near,
186 LineAlignment = StringAlignment.Near
187 };
188
189 StringFormat sfCenterCenter = new StringFormat()
190 {
191 Alignment = StringAlignment.Center,
192 LineAlignment = StringAlignment.Center
193 };
194
195 StringFormat sfCenterFar = new StringFormat()
196 {
197 Alignment = StringAlignment.Far,
198 LineAlignment = StringAlignment.Near
199 };
200
201 StringFormat sf3 = new StringFormat(System.Threading.Thread.CurrentThread.CurrentUICulture.TextInfo.IsRightToLeft ? StringFormatFlags.DirectionRightToLeft : 0);
202 sf3.SetDigitSubstitution(System.Threading.Thread.CurrentThread.CurrentUICulture.LCID, StringDigitSubstitute.Traditional);
203
204
205 //set the hard margin which different for each printer and multiplied with 2
206 int HardMarginX = 0;
207 if ((int)(e.PageSettings.HardMarginX) > 0)
208 {
209 HardMarginX=((int)(e.PageSettings.HardMarginX) *2);
210 }
211 int HardMarginY = 0;
212 if ((int)(e.PageSettings.HardMarginY) > 0)
213 {
214 HardMarginY = ((int)(e.PageSettings.HardMarginY) * 2);
215 }
216
217 // Draw Header
218
219 string division = CGDocumentManager.Current.RemoteSession.User.Division.Name;
220 int divisionStringHeight = (int)g.MeasureString(division.ToString(), fontBody, e.PageBounds.Width - (int)(10 * widthRatio) - HardMarginX).Height;
221
222 Rectangle headerArea = new Rectangle()
223 {
224 X = (int)(5 * widthRatio),
225 Y = (int)(5 * heightRatio),
226 Height = divisionStringHeight + (int)(5 * heightRatio),
227 Width = e.PageBounds.Width - (int)(10 * widthRatio) - HardMarginX
228 };
229 g.DrawString(division, fontBody, Brushes.Black, headerArea, sfCenterNear);
230
231 //use stringData to print the footer (center all the way)
232 stringData = strings.Printed + ": " + DateTime.Now.ToString();
233 int stringDataStringHeight = (int)g.MeasureString(stringData.ToString(), fFooter, e.MarginBounds.Width).Height;
234 Rectangle footerArea = new Rectangle()
235 {
236 X = headerArea.X,
237 Y = e.PageBounds.Height - stringDataStringHeight - HardMarginY - (int)(5 * heightRatio),
238 Width = headerArea.Width,
239 Height = stringDataStringHeight
240 };
241 g.DrawString(stringData, fFooter, Brushes.Black, footerArea, sfCenterCenter);
242
243 //setting the printing area bigger than the margin bounds to use more printing space on the paper.
244 Rectangle printArea = new Rectangle()
245 {
246 X = headerArea.X,
247 Y = headerArea.Y+headerArea.Height,
248 Height = footerArea.Y-(headerArea.Y+headerArea.Height) - (int)(5 * heightRatio),
249 Width = headerArea.Width
250 };
251
252 // if there is a need for the watermark use the following code.
253 //const int watermarkLength = 75*heightratio;
254
255 // Move down for optional form paper
256 //printArea.Y += watermarkLength;
257 //printArea.Height -= watermarkLength;
258
259 //// Draw Title
260 //StringFormat sfCenter = new StringFormat();
261 //sfCenter.Alignment = StringAlignment.Center; //for title & header
262
263 //string data for the appointment slip title
264 stringData = strings.ApptReminderSlip;
265 g.DrawString(stringData, fontTitle, Brushes.Black, printArea, sfCenterFar); //title
266
267 //// move down
268 int titleHeight = (int)g.MeasureString(stringData, fontTitle, printArea.Width).Height;
269 printArea.Y += titleHeight;
270 printArea.Height -= titleHeight;
271
272 // draw underline
273 g.DrawLine(Pens.Black, printArea.Location, new Point(printArea.Right, printArea.Y));
274 printArea.Y += (int)(10 * heightRatio);
275 printArea.Height -= (int)(10 * heightRatio);
276
277 // building the string of the person information to write
278 StringBuilder personInformationString = new StringBuilder(500);
279 personInformationString.AppendLine(strings.Name + ":" + "\t" + appt.Patient.Name);
280 //personInformationString.AppendLine();
281 stringData = appt.Patient.Sex == Sex.Male ? strings.Male : strings.Female;
282 personInformationString.AppendLine(strings.ID + ":" + "\t" + appt.Patient.ID + "\t" + "( " + stringData + " )");
283 //personInformationString.AppendLine();
284 stringData = appt.Patient.DOB.ToString("dd") + " " + appt.Patient.DOB.ToString("MMM") + ", " + appt.Patient.DOB.Year;
285 personInformationString.AppendLine(strings.DOB + ":" + "\t" + stringData);
286 //personInformationString.AppendLine();
287 //personInformationString.AppendLine(strings.Age + ":" + "\t" + appt.Patient.UserFriendlyAge);
288
289
290 // building the string of the appointment information to write
291 StringBuilder appointmentInformationString = new StringBuilder(500);
292 appointmentInformationString = new StringBuilder();
293 appointmentInformationString.AppendLine(strings.Clinic + ":" + "\t" + appt.Resource);
294 //appointmentInformationString.AppendLine();
295 stringData = appt.StartTime.ToString("dddd") + " " + appt.StartTime.ToString("dd") + " " + appt.StartTime.ToString("MMM") + ", " + appt.StartTime.Year;
296 appointmentInformationString.AppendLine(strings.Date + ":" + "\t" + stringData);
297 //sb.AppendLine();
298 //appointmentInformationString.AppendLine(strings.Day + ":" + "\t" + appt.StartTime.ToString("dddd"));
299 //sb.AppendLine();
300 appointmentInformationString.AppendLine(strings.Time + ":" + "\t" + appt.StartTime.ToShortTimeString());
301
302
303 //counting the width and hieght of the information inner aera for the person and appointment rectangels.
304 int InfoInnerRectangleWidth = (printArea.Width / 2 - printArea.X / 2) - (int)(10 * widthRatio);
305
306 //Counting the height of the two strings (PersontInformationStringappointment & InformationStringto)to be allocated to the InfoInnerRectangleHeight later.
307 int PersonInformationStringHeight = (int)g.MeasureString(personInformationString.ToString(), fontBody, InfoInnerRectangleWidth).Height;
308 int appointmentInformationStringHeight = (int)g.MeasureString(appointmentInformationString.ToString(), fontBody, InfoInnerRectangleWidth).Height;
309
310 int InfoInnerRectangleHeight = PersonInformationStringHeight;
311 if (appointmentInformationStringHeight > PersonInformationStringHeight)
312 {
313 InfoInnerRectangleHeight = appointmentInformationStringHeight;
314 }
315
316 // draw curved rectangle for the person informations.
317 Rectangle personalInfoRectangle = new Rectangle(printArea.X, printArea.Y, InfoInnerRectangleWidth + (int)(10 * widthRatio), InfoInnerRectangleHeight + (int)(10 * heightRatio));
318 using (GraphicsPath path = GetRoundedRectPath(personalInfoRectangle, 5))
319 {
320 g.DrawPath(Pens.Black, path);
321 }
322
323 // inner rectangle for drawing strings:
324 Rectangle personalInfoInnerRectangle = new Rectangle(personalInfoRectangle.X + (int)(5 * widthRatio), personalInfoRectangle.Y + (int)(5 * heightRatio), InfoInnerRectangleWidth, InfoInnerRectangleHeight);
325
326 // Draw the preson informations.
327 //sf3.SetTabStops(0, new float[] {75} );
328
329 g.DrawString(personInformationString.ToString(), fontBody, Brushes.Black, personalInfoInnerRectangle, sf3);
330
331 // draw curved rectangle for the appointment informations.
332 Rectangle apptInfoRectangle = new Rectangle((int)(printArea.X + personalInfoRectangle.Width + printArea.X), personalInfoRectangle.Y, personalInfoRectangle.Width, personalInfoRectangle.Height);
333 using (GraphicsPath path = GetRoundedRectPath(apptInfoRectangle, 5))
334 {
335 g.DrawPath(Pens.Black, path);
336 }
337
338
339 // Draw appointment informations in the inner rectangle.
340 Rectangle apptInfoInnerRectangle = new Rectangle(apptInfoRectangle.X + (int)(5 * widthRatio), apptInfoRectangle.Y + (int)(5 * heightRatio), InfoInnerRectangleWidth, InfoInnerRectangleHeight);
341 g.DrawString(appointmentInformationString.ToString(), fontBody, Brushes.Black, apptInfoInnerRectangle, sf3);
342
343 // Move Drawing Rectangle Down
344 printArea.Y += personalInfoRectangle.Height + (int)(5 * heightRatio);
345 printArea.Height -= personalInfoRectangle.Height + (int)(5 * heightRatio);
346
347 // Draw New Line
348 g.DrawLine(Pens.Black, printArea.Location, new Point(printArea.Right, printArea.Y));
349 printArea.Y += (int)(5 * heightRatio);
350 printArea.Height -= (int)(5 * heightRatio);
351
352 // Draw new Title
353 stringData = strings.ClinicInstructions;
354 titleHeight = (int)g.MeasureString(stringData, fontTitle, printArea.Width).Height;
355 g.DrawString(stringData, fontTitle, Brushes.Black, printArea, sf3); //title
356 // move down
357 printArea.Y += titleHeight;
358 printArea.Height -= titleHeight;
359
360 // Get Resource Clinic Appointment Letter Text
361 DataTable resources = CGDocumentManager.Current.GlobalDataSet.Tables["Resources"];
362
363 string ltrTxt = (from resource in resources.AsEnumerable()
364 where resource.Field<string>("RESOURCE_NAME") == appt.Resource
365 select resource.Field<string>("LETTER_TEXT")).SingleOrDefault<string>();
366
367 if (String.IsNullOrWhiteSpace(ltrTxt)) ltrTxt = strings.NoInstructionsProvided;
368 int ltrTxtHeight = (int)g.MeasureString(ltrTxt, fontBody,printArea.Width).Height;
369 //setting the instructions area smaller than the printing area.
370 int instructionsAreaHeight = ltrTxtHeight;
371 //missingString true if there are no more printing area for the instructions and will use it to print a statement for it.
372 bool missingString = false;
373 string missingStringStatement = "";
374 int missingStringStatementHeight = 0;
375 if (ltrTxtHeight > printArea.Height)
376 {
377 missingStringStatement = "etc...";
378 missingStringStatementHeight = (int)g.MeasureString(missingStringStatement, fFooter, printArea.Width).Height;
379 instructionsAreaHeight = printArea.Height -missingStringStatementHeight- (int)(5 * heightRatio);
380 missingString = true;
381 }
382 Rectangle instructionsArea = new Rectangle()
383 {
384 X = printArea.X,
385 Y = printArea.Y,
386 Height = instructionsAreaHeight,
387 Width = printArea.Width
388 };
389 g.DrawString(ltrTxt, fontBody, Brushes.Black, instructionsArea, sf3);
390
391 //moving down
392 printArea.Y += instructionsAreaHeight + (int)(5 * heightRatio);
393 printArea.Height -= instructionsAreaHeight + (int)(5 * heightRatio);
394
395 if (missingString)
396 {
397 g.DrawString(missingStringStatement, fFooter, Brushes.Black, printArea, sf3); //title
398 printArea.Y += missingStringStatementHeight;
399 printArea.Height -= missingStringStatementHeight;
400 }
401 //Draing new line
402 if (printArea.Height > 0)
403 {
404 g.DrawLine(Pens.Black, printArea.Location, new Point(printArea.Right, printArea.Y));
405 printArea.Y += (int)(5 * heightRatio);
406 printArea.Height -= (int)(5 * heightRatio);
407
408 string noteStringData = strings.Notes;
409 int noteTitleHeight = (int)g.MeasureString(noteStringData, fontTitle, printArea.Width).Height;
410
411 //check if the remaining area height enugh for the notes
412 if (printArea.Height > ((int)(noteTitleHeight)))
413 {
414 //draw the note title.
415 g.DrawString(noteStringData, fontTitle, Brushes.Black, printArea, sf3); // Notes title
416 }
417
418
419 }
420 g.Dispose();
421 }
422
423
424 private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
425 {
426 int diameter = 2 * radius;
427
428 Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
429 GraphicsPath path = new GraphicsPath();
430
431 path.AddArc(arcRect, 180, 90); //top left
432 arcRect.X = rect.Right - diameter;
433 path.AddArc(arcRect, 270, 90); // top right
434 arcRect.Y = rect.Bottom - diameter;
435 path.AddArc(arcRect, 0, 90); // bottom right
436 arcRect.X = rect.Left;
437 path.AddArc(arcRect, 90, 90); // bottom left
438
439 path.CloseFigure();
440
441 return path;
442 }
443
444 /// <summary>
445 /// Print Letter to be given or mailed to the patient
446 /// </summary>
447 /// <param name="ptrow">Strongly typed PatientApptsRow to pass (just one ApptRow)</param>
448 /// <param name="e">You know what that is</param>
449 /// <param name="letter">Contains letter string</param>
450 /// <param name="title">Title of the letter</param>
451 public virtual void PrintReminderLetter(dsPatientApptDisplay2.PatientApptsRow ptRow, PrintPageEventArgs e, string letter, string title)
452 {
453
454 Rectangle printArea = e.MarginBounds;
455 Graphics g = e.Graphics;
456 StringFormat sf = new StringFormat();
457 sf.Alignment = StringAlignment.Center; //for title
458 Font fTitle = new Font(FontFamily.GenericSerif, 24, FontStyle.Bold); //for title
459 Font fBody = new Font(FontFamily.GenericSerif, 12);
460 g.DrawString(title, fTitle, Brushes.Black, printArea, sf); //title
461
462 // move down
463 int titleHeight = (int)g.MeasureString(title, fTitle, printArea.Width).Height;
464 printArea.Y += titleHeight;
465 printArea.Height -= titleHeight;
466
467 // draw underline
468 g.DrawLine(Pens.Black, printArea.Location, new Point(printArea.Right, printArea.Y));
469 printArea.Y += 15;
470 printArea.Height -= 15;
471
472 // write appointment date
473 string str = "Appointment Date: " + ptRow.ApptDate + "\n\n";
474 g.DrawString(str, fBody, Brushes.Black, printArea);
475
476 // move down
477 int strHeight = (int)g.MeasureString(str, fBody, printArea.Width).Height;
478 printArea.Y += strHeight;
479 printArea.Height -= strHeight;
480
481 //Text Direction
482 StringFormat sf2 = new StringFormat();
483 if (System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.IsRightToLeft)
484 sf2.FormatFlags = StringFormatFlags.DirectionRightToLeft;
485
486 // write missive
487 g.DrawString(letter, fBody, Brushes.Black, printArea, sf2);
488
489 //print Address in lower left corner for windowed envolopes
490 printArea.Location = new Point(e.MarginBounds.X, (int)(e.PageBounds.Height * 0.66));
491 printArea.Height = (int)(e.MarginBounds.Height * 0.20);
492 sf.Alignment = StringAlignment.Near;
493 sf.LineAlignment = StringAlignment.Center;
494 StringBuilder address = new StringBuilder(100);
495 address.AppendLine(ptRow.Name);
496 address.AppendLine(ptRow.STREET);
497 address.AppendLine(ptRow.CITY + ", " + ptRow.STATE + " " + ptRow.ZIP);
498 g.DrawString(address.ToString(), fBody, Brushes.Black, printArea, sf);
499
500 g.Dispose();
501 }
502
503 /// <summary>
504 /// Cancellation Letter to be given or mailed to the patient
505 /// </summary>
506 /// <param name="ptRow">Strongly typed PatientApptsRow to pass (just one ApptRow)</param>
507 /// <param name="e">You know what that is</param>
508 /// <param name="letter">Contains letter string</param>
509 /// <param name="title">Title of the letter</param>
510 public virtual void PrintCancelLetter(dsRebookAppts.PatientApptsRow ptRow, PrintPageEventArgs e, string letter, string title)
511 {
512 Rectangle printArea = e.MarginBounds;
513 Graphics g = e.Graphics;
514 StringFormat sf = new StringFormat();
515 sf.Alignment = StringAlignment.Center; //for title
516 Font fTitle = new Font(FontFamily.GenericSerif, 24, FontStyle.Bold); //for title
517 Font fBody = new Font(FontFamily.GenericSerif, 12);
518 g.DrawString(title, fTitle, Brushes.Black, printArea, sf); //title
519
520 // move down
521 int titleHeight = (int)g.MeasureString(title, fTitle, printArea.Width).Height;
522 printArea.Y += titleHeight;
523 printArea.Height -= titleHeight;
524
525 // draw underline
526 g.DrawLine(Pens.Black, printArea.Location, new Point(printArea.Right, printArea.Y));
527 printArea.Y += 15;
528 printArea.Height -= 15;
529
530 // write appointment date
531 string str = "Appointment Date: " + ptRow.OldApptDate + "\n\n";
532 g.DrawString(str, fBody, Brushes.Black, printArea);
533
534 // move down
535 int strHeight = (int)g.MeasureString(str, fBody, printArea.Width).Height;
536 printArea.Y += strHeight;
537 printArea.Height -= strHeight;
538
539 //Text Direction
540 StringFormat sf2 = new StringFormat();
541 if (System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.IsRightToLeft)
542 sf2.FormatFlags = StringFormatFlags.DirectionRightToLeft;
543
544 // write missive
545 g.DrawString(letter, fBody, Brushes.Black, printArea, sf2);
546
547 //print Address in lower left corner for windowed envolopes
548 printArea.Location = new Point(e.MarginBounds.X, (int)(e.PageBounds.Height * 0.66));
549 printArea.Height = (int)(e.MarginBounds.Height * 0.20);
550 sf.Alignment = StringAlignment.Near;
551 sf.LineAlignment = StringAlignment.Center;
552 StringBuilder address = new StringBuilder(100);
553 address.AppendLine(ptRow.Name);
554 address.AppendLine(ptRow.STREET);
555 address.AppendLine(ptRow.CITY + ", " + ptRow.STATE + " " + ptRow.ZIP);
556 g.DrawString(address.ToString(), fBody, Brushes.Black, printArea, sf);
557
558 g.Dispose();
559 }
560
561 /// <summary>
562 /// Print rebook letters. Prints old and new appointments dates then the missive.
563 /// </summary>
564 /// <param name="ptRow">Strongly typed appointment row</param>
565 /// <param name="e">etc</param>
566 /// <param name="letter">Text of the letter to print</param>
567 /// <param name="title">Title to print at the top of the letter</param>
568 public virtual void PrintRebookLetter(dsRebookAppts.PatientApptsRow ptRow, PrintPageEventArgs e, string letter, string title)
569 {
570 Rectangle printArea = e.MarginBounds;
571 Graphics g = e.Graphics;
572 StringFormat sf = new StringFormat();
573 sf.Alignment = StringAlignment.Center; //for title
574 Font fTitle = new Font(FontFamily.GenericSerif, 24, FontStyle.Bold); //for title
575 Font fBody = new Font(FontFamily.GenericSerif, 12);
576 g.DrawString(title, fTitle, Brushes.Black, printArea, sf); //title
577
578 // move down
579 int titleHeight = (int)g.MeasureString(title, fTitle, printArea.Width).Height;
580 printArea.Y += titleHeight;
581 printArea.Height -= titleHeight;
582
583 // draw underline
584 g.DrawLine(Pens.Black, printArea.Location, new Point(printArea.Right, printArea.Y));
585 printArea.Y += 15;
586 printArea.Height -= 15;
587
588 // write old and new appointment dates
589 string str = "Old Appointment Date:\t\t" + ptRow.OldApptDate + "\n";
590 str += "New Appointment Date:\t\t" + ptRow.NewApptDate + "\n\n";
591 g.DrawString(str, fBody, Brushes.Black, printArea);
592
593 // move down
594 int strHeight = (int)g.MeasureString(str, fBody, printArea.Width).Height;
595 printArea.Y += strHeight;
596 printArea.Height -= strHeight;
597
598 //Text Direction
599 StringFormat sf2 = new StringFormat();
600 if (System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.IsRightToLeft)
601 sf2.FormatFlags = StringFormatFlags.DirectionRightToLeft;
602
603 // write missive
604 g.DrawString(letter, fBody, Brushes.Black, printArea, sf2);
605
606 //print Address in lower left corner for windowed envolopes
607 printArea.Location = new Point(e.MarginBounds.X, (int)(e.PageBounds.Height * 0.66));
608 printArea.Height = (int)(e.MarginBounds.Height * 0.20);
609 sf.Alignment = StringAlignment.Near;
610 sf.LineAlignment = StringAlignment.Center;
611 StringBuilder address = new StringBuilder(100);
612 address.AppendLine(ptRow.Name);
613 address.AppendLine(ptRow.STREET);
614 address.AppendLine(ptRow.CITY + ", " + ptRow.STATE + " " + ptRow.ZIP);
615 g.DrawString(address.ToString(), fBody, Brushes.Black, printArea, sf);
616
617 g.Dispose();
618 }
619
620 /// <summary>
621 /// Print message on a page; typically that there are no appointments to be found.
622 /// Or just a test message to verify that printing works.
623 /// </summary>
624 /// <param name="msg">The exact string to print.</param>
625 /// <param name="e">Print Page event args</param>
626 public virtual void PrintMessage(string msg, PrintPageEventArgs e)
627 {
628 e.Graphics.DrawString(msg, new Font(FontFamily.GenericSerif, 14),
629 Brushes.Black, e.MarginBounds);
630 e.Graphics.Dispose();
631 }
632
633 /// <summary>
634 /// Print Routing Slip
635 /// </summary>
636 /// <param name="a">Appointment Data Structure</param>
637 /// <param name="apptOrder">Order of Appointment</param>
638 /// <param name="e">etc</param>
639 public virtual void PrintRoutingSlip(CGAppointment appt, int apptOrder, PrintPageEventArgs e)
640 {
641 // setting the reference values for calculating the needed ratio of the coming page.
642 //referrenceHeight and referrenceWidth for A6 size.
643 double referrenceHeight = 383;
644 double referrenceWidth = 213;
645
646 //check if the paper is landscape or portrait. if it is landscape then new ratio need to be calculated.
647 if (e.MarginBounds.Width > e.MarginBounds.Height)
648 {
649 //landscape = true;
650 referrenceHeight = 213;
651 referrenceWidth = 383;
652 //fontRatio = ((e.MarginBounds.Height) / referrenceHeight);
653 }
654
655 //setting the font,width and height ratios
656 double fontRatio = (e.MarginBounds.Height / referrenceHeight);
657 if (fontRatio > 1.0)
658 {
659 fontRatio = fontRatio * 0.75;
660 }
661 double widthRatio = ((e.MarginBounds.Width) / referrenceWidth);
662 double heightRatio = ((e.MarginBounds.Height) / referrenceHeight);
663
664 Graphics g = e.Graphics;
665 //this is the string which is used to fill with the data and to be print on the screen.
666 string stringData;
667
668 //in portrait we used fonts that fits with the A6 paper and changed depending on the page ratio,but in the land scape we used fonts fits with the A5 paper and counted the other pages depening on the ratios.
669 Font fontTitle = new Font(FontFamily.GenericSerif, (int)(13 * fontRatio), FontStyle.Bold); //for title
670 Font fontBody = new Font(FontFamily.GenericSerif, (int)(13 * fontRatio));
671 Font fontGroupTitle = new Font(FontFamily.GenericSansSerif, (int)(13 * fontRatio), FontStyle.Bold);
672 Font fFooter = new Font(FontFamily.GenericSerif, (int)(7 * fontRatio));
673
674 StringFormat sfCenterCenter = new StringFormat()
675 {
676 Alignment = StringAlignment.Center,
677 LineAlignment = StringAlignment.Center
678 };
679
680 //set the hard margin which different for each printer and multiplied with 2
681 int HardMarginX = 0;
682 if ((int)(e.PageSettings.HardMarginX) > 0)
683 {
684 HardMarginX = ((int)(e.PageSettings.HardMarginX) * 2);
685 }
686 int HardMarginY = 0;
687 if ((int)(e.PageSettings.HardMarginY) > 0)
688 {
689 HardMarginY = ((int)(e.PageSettings.HardMarginY) * 2);
690 }
691
692 // Draw Header
693 string division = CGDocumentManager.Current.RemoteSession.User.Division.Name;
694 int divisionStringHeight = (int)g.MeasureString(division.ToString(), fontBody, e.MarginBounds.Width).Height;
695 Rectangle headerArea = new Rectangle()
696 {
697 X = (int)(5 * widthRatio),
698 Y = (int)(5 * heightRatio),
699 Height = divisionStringHeight + (int)(5 * heightRatio),
700 Width = e.PageBounds.Width - (int)(10 * widthRatio) - HardMarginX
701 };
702 g.DrawString(division, fontBody, Brushes.Black, headerArea, sfCenterCenter);
703
704
705 //use stringData to print the footer (center all the way)
706 stringData = strings.Printed + ": " + DateTime.Now.ToString();
707 int stringDataStringHeight = (int)g.MeasureString(stringData.ToString(), fFooter, e.MarginBounds.Width).Height;
708 Rectangle footerArea = new Rectangle()
709 {
710 X = headerArea.X,
711 Y = e.PageBounds.Height - stringDataStringHeight - HardMarginY - (int)(5 * heightRatio),
712 Width = headerArea.Width,
713 Height = stringDataStringHeight
714 };
715 g.DrawString(stringData, fFooter, Brushes.Black, footerArea, sfCenterCenter);
716
717
718
719 //setting the printing area bigger than the margin bounds to use more printing space on the paper.
720 Rectangle printArea = new Rectangle()
721 {
722 X = headerArea.X,
723 Y = headerArea.Y + headerArea.Height,
724 Height = footerArea.Y - (headerArea.Y + headerArea.Height) - (int)(5 * heightRatio),
725 Width = headerArea.Width
726 };
727
728
729 // if there is a need for the watermark use the following code.
730 //const int watermarkLength = 75*heightratio;
731
732 // Move down for optional form paper
733 //printArea.Y += watermarkLength;
734 //printArea.Height -= watermarkLength;
735
736 // Draw Title
737 StringFormat sfCenter = new StringFormat();
738 sfCenter.Alignment = StringAlignment.Center; //for title & header
739 string title = strings.RoutingSlip;
740 g.DrawString(title, fontTitle, Brushes.Black, printArea, sfCenter); //title
741
742 // move down
743 int titleHeight = (int)g.MeasureString(title, fontTitle, printArea.Width).Height;
744 printArea.Y += titleHeight;
745 printArea.Height -= titleHeight;
746
747 // draw underline
748 g.DrawLine(Pens.Black, printArea.Location, new Point(printArea.Right, printArea.Y));
749 printArea.Y += (int)(5 * heightRatio);
750 printArea.Height -= (int)(5 * heightRatio);
751
752 // Strings to write
753
754 StringBuilder personInformationString = new StringBuilder(500);
755 personInformationString.AppendLine(strings.Name + ":" + "\t" + appt.Patient.Name);
756 //personInformationString.AppendLine();
757 personInformationString.AppendLine(strings.ID + ":" + "\t" + appt.Patient.ID);
758 //personInformationString.AppendLine();
759 stringData = appt.Patient.DOB.ToString("dd") + " " + appt.Patient.DOB.ToString("MMM") + ", " + appt.Patient.DOB.Year;
760 personInformationString.AppendLine(strings.DOB + ":" + "\t" + stringData);
761 //personInformationString.AppendLine();
762 personInformationString.AppendLine(strings.Age + ":" + "\t" + appt.Patient.UserFriendlyAge);
763 //personInformationString.AppendLine();
764 //personInformationString.AppendLine("Sex:" + "\t" + appt.Patient.Sex.ToString());
765
766 // Strings to write
767 StringBuilder appointmentInformationString = new StringBuilder();
768 appointmentInformationString.AppendLine(strings.Clinic + ":");
769 appointmentInformationString.AppendLine(appt.Resource);
770 //appointmentInformationString.AppendLine();
771 appointmentInformationString.AppendLine(strings.AppointmentProvider + ":");
772 appointmentInformationString.AppendLine((appt.Provider == null) ? strings.none : appt.Provider.ToString()); //Appt Provider or (none) if null
773 //appointmentInformationString.AppendLine();
774 appointmentInformationString.AppendLine(strings.PatientOrder + ":" + "\t" + apptOrder);
775 appointmentInformationString.AppendLine(strings.Date + ":" + "\t" + appt.StartTime.ToShortDateString() + " " + appt.StartTime.ToShortTimeString());
776 //appointmentInformationString.AppendLine();
777 appointmentInformationString.AppendLine(strings.AppointmentNote + ":");
778 appointmentInformationString.AppendLine(String.IsNullOrWhiteSpace(appt.Note) ? strings.none : appt.Note);
779
780 //counting the width and hieght of the information inner aera for the person and appointment rectangels.
781 int InfoInnerRectangleWidth = (printArea.Width / 2 - printArea.X / 2) - (int)(10 * widthRatio);
782
783 //Counting the height of the two strings (PersontInformationStringappointment & InformationStringto)to be allocated to the InfoInnerRectangleHeight later.
784 int PersonInformationStringHeight = (int)g.MeasureString(personInformationString.ToString(), fontBody, InfoInnerRectangleWidth).Height;
785 int appointmentInformationStringHeight = (int)g.MeasureString(appointmentInformationString.ToString(), fontBody, InfoInnerRectangleWidth).Height;
786
787 int InfoInnerRectangleHeight = PersonInformationStringHeight;
788 if (appointmentInformationStringHeight > PersonInformationStringHeight)
789 {
790 InfoInnerRectangleHeight = appointmentInformationStringHeight;
791 }
792
793 // group header for the person informations.
794 stringData = strings.PtInfo;
795 StringFormat sf3 = new StringFormat(System.Threading.Thread.CurrentThread.CurrentUICulture.TextInfo.IsRightToLeft ? StringFormatFlags.DirectionRightToLeft : 0);
796 stringDataStringHeight = (int)g.MeasureString(stringData.ToString(), fontGroupTitle, InfoInnerRectangleWidth).Height;
797 g.DrawString(stringData, fontGroupTitle, Brushes.Black, new Rectangle(printArea.X, printArea.Y, InfoInnerRectangleWidth, stringDataStringHeight), sf3);
798
799 // group header for the appointment information
800 stringData = strings.ApptInfo;
801 g.DrawString(stringData, fontGroupTitle, Brushes.Black, new Rectangle((int)(printArea.X + (InfoInnerRectangleWidth + (int)(10 * widthRatio)) + printArea.X), printArea.Y, InfoInnerRectangleWidth, stringDataStringHeight), sf3);
802
803 //moving down
804 printArea.Y += stringDataStringHeight + (int)(5 * heightRatio);
805 printArea.Height -= stringDataStringHeight + (int)(5 * heightRatio);
806
807 // draw curved rectangle for the person informations.
808 Rectangle personalInfoRectangle = new Rectangle(printArea.X, printArea.Y, InfoInnerRectangleWidth + (int)(10 * widthRatio), InfoInnerRectangleHeight + (int)(10 * heightRatio));
809 using (GraphicsPath path = GetRoundedRectPath(personalInfoRectangle, 5))
810 {
811 g.DrawPath(Pens.Black, path);
812 }
813
814 // inner rectangle for drawing strings:
815 Rectangle personalInfoInnerRectangle = new Rectangle(personalInfoRectangle.X + (int)(5 * widthRatio), personalInfoRectangle.Y + (int)(5 * heightRatio), InfoInnerRectangleWidth, InfoInnerRectangleHeight);
816
817 // Draw the preson informations.
818 sf3 = new StringFormat(System.Threading.Thread.CurrentThread.CurrentUICulture.TextInfo.IsRightToLeft ? StringFormatFlags.DirectionRightToLeft : 0);
819 //sf3.SetTabStops(0, new float[] {75} );
820 sf3.SetDigitSubstitution(System.Threading.Thread.CurrentThread.CurrentUICulture.LCID, StringDigitSubstitute.Traditional);
821 g.DrawString(personInformationString.ToString(), fontBody, Brushes.Black, personalInfoInnerRectangle, sf3);
822
823 // draw curved rectangle for the appointment informations.
824 Rectangle apptInfoRectangle = new Rectangle((int)(printArea.X + personalInfoRectangle.Width + printArea.X), personalInfoRectangle.Y, personalInfoRectangle.Width, personalInfoRectangle.Height);
825 using (GraphicsPath path = GetRoundedRectPath(apptInfoRectangle, 5))
826 {
827 g.DrawPath(Pens.Black, path);
828 }
829
830 // Draw appointment informations in the inner rectangle.
831 Rectangle apptInfoInnerRectangle = new Rectangle(apptInfoRectangle.X + (int)(5 * widthRatio), apptInfoRectangle.Y + (int)(5 * heightRatio), InfoInnerRectangleWidth, InfoInnerRectangleHeight);
832 g.DrawString(appointmentInformationString.ToString(), fontBody, Brushes.Black, apptInfoInnerRectangle, sf3);
833
834 // Move Drawing Rectangle Down
835 printArea.Y += personalInfoRectangle.Height + (int)(5 * heightRatio);
836 printArea.Height -= personalInfoRectangle.Height + (int)(5 * heightRatio);
837
838 // Draw New Line
839 using (Pen dashpen = new Pen(Color.Black))
840 {
841 dashpen.DashStyle = DashStyle.Dash;
842 g.DrawLine(dashpen, printArea.Location, new Point(printArea.Right, printArea.Y));
843 }
844
845 printArea.Y += (int)(5 * heightRatio);
846 printArea.Height -= (int)(5 * heightRatio);
847
848 stringData = strings.ScratchArea;
849 g.DrawString(stringData, fontGroupTitle, Brushes.Black, printArea, sf3);
850
851 /* Per Al-Najjar, we don't want the next appointment instructions section
852 // move down
853 printArea.Y += 240;
854 printArea.Height -= 240;
855
856 using (Pen dashpen = new Pen(Color.Black))
857 {
858 dashpen.DashStyle = DashStyle.Dot;
859 g.DrawLine(dashpen, printArea.Location, new Point(printArea.Right, printArea.Y));
860 }
861
862 printArea.Y += 5;
863 printArea.Height -= 5;
864
865 stringData = strings.NextAppointmentInstructions;
866 g.DrawString(stringData, fontGroupTitle, Brushes.Black, printArea, sf3);
867 */
868
869 g.Dispose();
870
871 }
872
873 }
874 public abstract class PrintingCreator
875 {
876 public abstract Printing PrintFactory();
877 }
878
879}
Note: See TracBrowser for help on using the repository browser.