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

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

Updated printing code to use the one provided by EHS. Now prints on A6 paper. Works as well with Letter and A4.

File size: 44.4 KB
RevLine 
[772]1using System;
2using System.Drawing.Printing;
3using System.Drawing;
[1110]4using System.Text;
5using System.Drawing.Drawing2D;
6using System.Linq;
[772]7using System.Data;
8
9namespace IndianHealthService.ClinicalScheduling
10{
[1112]11 public partial class Printing
[1469]12 {
[772]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>
[788]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>
[772]23 /// <remarks>beg and end have no effect on operation--they are there for documentation for user only</remarks>
[1110]24 public virtual void PrintAppointments(dsPatientApptDisplay2 ds, PrintPageEventArgs e, DateTime beg, DateTime end, int resourceToPrint, ref int apptPrinting, int pageNumber)
[772]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);
[1469]35
[772]36 //Center Alignment for some stuff
37 StringFormat sf = new StringFormat();
38 sf.Alignment = StringAlignment.Center;
[1469]39
[788]40 //Header
[772]41 g.DrawString("Confidential Patient Information", f8, Brushes.Black, e.PageBounds, sf);
[1469]42
[788]43 //Footer
44 sf.Alignment = StringAlignment.Center;
45 sf.LineAlignment = StringAlignment.Far;
46 g.DrawString("Page " + pageNumber, f8, Brushes.Black, e.PageBounds, sf);
47
[772]48 //Typical manipulable print area
49 Rectangle printArea = e.MarginBounds;
[1112]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
[788]72 //resource we want to print
[772]73 dsPatientApptDisplay2.BSDXResourceRow r = ds.BSDXResource[resourceToPrint];
[1469]74
[788]75 //header
[772]76 string toprint;
[1112]77 if (beg.Date == end.Date) toprint = "Appointments for " + r.RESOURCE_NAME + " on " + beg.ToLongDateString();
[772]78 else toprint = "Appointments for " + r.RESOURCE_NAME + " from " + beg.ToShortDateString() + " to "
79 + end.ToShortDateString();
80 g.DrawString(toprint, f14bold, Brushes.Black, printArea);
[1469]81
[788]82 //Move print area down
[1112]83 int titleHeight = (int)g.MeasureString(toprint, f14bold, printArea.Size).Height;
84 printArea.Height -= titleHeight;
85 printArea.Y += titleHeight;
[788]86
87 //Draw Line
[772]88 g.DrawLine(new Pen(Brushes.Black, 0), printArea.X, printArea.Y, printArea.X + printArea.Width, printArea.Y);
[1469]89
[788]90 //Move print area down
[1469]91 printArea.Y += 5;
[788]92 printArea.Height -= 5;
[1469]93
[788]94 System.Data.DataRow[] appts = r.GetChildRows(ds.Relations[0]); //ds has only one relation
[772]95
[788]96 StringFormat sf2 = new StringFormat(); //sf to hold tab stops
[1469]97 sf2.SetTabStops(50, new float[] { 100, 250, 25 });
[772]98
[788]99 //appt printed starts at zero
100 while (apptPrinting < appts.Length)
[772]101 {
[788]102 dsPatientApptDisplay2.PatientApptsRow a = (dsPatientApptDisplay2.PatientApptsRow)appts[apptPrinting];
[1469]103
104 StringBuilder apptPrintStr = new StringBuilder(200);
[900]105 apptPrintStr.AppendLine(a.ApptDate.ToString() + "\t" + a.Name + " (" + a.Sex + ")" + "\t" + "DOB: " + a.DOB.ToShortDateString() + "\t" + "ID: " + a.HRN);
[788]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
[1469]112 // but don't increment the appointment to print since we haven't printed it yet.
113 // i.e. apptPrinting stays the same.
[788]114 {
115 e.HasMorePages = true;
116 break;
117 }
[1469]118
[788]119 //otherwise print it
120 g.DrawString(apptPrintStr.ToString(), f10, Brushes.Black, printArea, sf2);
[1469]121
[788]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++;
[772]137 }
[1131]138
139
140 g.Dispose();
[772]141 }
[788]142
143 /// <summary>
[1110]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 {
[1469]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
[1110]173 Graphics g = e.Graphics;
[1469]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()
[1110]184 {
[1469]185 Alignment = StringAlignment.Near,
186 LineAlignment = StringAlignment.Near
[1110]187 };
[1469]188
189 StringFormat sfCenterCenter = new StringFormat()
[1112]190 {
[1469]191 Alignment = StringAlignment.Center,
192 LineAlignment = StringAlignment.Center
[1112]193 };
[1110]194
[1469]195 StringFormat sfCenterFar = new StringFormat()
196 {
197 Alignment = StringAlignment.Far,
198 LineAlignment = StringAlignment.Near
199 };
[1112]200
[1469]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);
[1110]203
[1469]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)
[1110]208 {
[1469]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.ConnectInfo.DivisionName;
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
[1110]228 };
[1469]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);
[1110]242
[1469]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;
[1131]254
255 // Move down for optional form paper
[1469]256 //printArea.Y += watermarkLength;
257 //printArea.Height -= watermarkLength;
[1131]258
[1469]259 //// Draw Title
260 //StringFormat sfCenter = new StringFormat();
261 //sfCenter.Alignment = StringAlignment.Center; //for title & header
[1110]262
[1469]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;
[1110]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));
[1469]274 printArea.Y += (int)(10 * heightRatio);
275 printArea.Height -= (int)(10 * heightRatio);
[1110]276
[1469]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)
[1110]312 {
[1469]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 {
[1110]320 g.DrawPath(Pens.Black, path);
321 }
322
323 // inner rectangle for drawing strings:
[1469]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} );
[1110]328
[1469]329 g.DrawString(personInformationString.ToString(), fontBody, Brushes.Black, personalInfoInnerRectangle, sf3);
[1112]330
[1469]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))
[1110]334 {
335 g.DrawPath(Pens.Black, path);
336 }
337
338
[1469]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);
[1110]342
343 // Move Drawing Rectangle Down
[1469]344 printArea.Y += personalInfoRectangle.Height + (int)(5 * heightRatio);
345 printArea.Height -= personalInfoRectangle.Height + (int)(5 * heightRatio);
[1110]346
347 // Draw New Line
348 g.DrawLine(Pens.Black, printArea.Location, new Point(printArea.Right, printArea.Y));
[1469]349 printArea.Y += (int)(5 * heightRatio);
350 printArea.Height -= (int)(5 * heightRatio);
[1110]351
352 // Draw new Title
[1469]353 stringData = strings.ClinicInstructions;
354 titleHeight = (int)g.MeasureString(stringData, fontTitle, printArea.Width).Height;
355 g.DrawString(stringData, fontTitle, Brushes.Black, printArea, sf3); //title
[1110]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
[1112]367 if (String.IsNullOrWhiteSpace(ltrTxt)) ltrTxt = strings.NoInstructionsProvided;
[1469]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);
[1110]394
[1469]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);
[1110]407
[1469]408 string noteStringData = strings.Notes;
409 int noteTitleHeight = (int)g.MeasureString(noteStringData, fontTitle, printArea.Width).Height;
[1110]410
[1469]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 }
[1110]417
418
419 }
[1131]420 g.Dispose();
[1110]421 }
422
423
424 private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
425 {
426 int diameter = 2 * radius;
[1469]427
[1110]428 Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
429 GraphicsPath path = new GraphicsPath();
[1469]430
[1110]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>
[788]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>
[1110]451 public virtual void PrintReminderLetter(dsPatientApptDisplay2.PatientApptsRow ptRow, PrintPageEventArgs e, string letter, string title)
[788]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;
[1469]466
[788]467 // draw underline
468 g.DrawLine(Pens.Black, printArea.Location, new Point(printArea.Right, printArea.Y));
469 printArea.Y += 15;
470 printArea.Height -= 15;
[789]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
[900]481 //Text Direction
482 StringFormat sf2 = new StringFormat();
483 if (System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.IsRightToLeft)
484 sf2.FormatFlags = StringFormatFlags.DirectionRightToLeft;
485
[788]486 // write missive
[900]487 g.DrawString(letter, fBody, Brushes.Black, printArea, sf2);
[788]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);
[1131]499
500 g.Dispose();
[788]501 }
[1469]502
[788]503 /// <summary>
[789]504 /// Cancellation Letter to be given or mailed to the patient
[788]505 /// </summary>
[789]506 /// <param name="ptRow">Strongly typed PatientApptsRow to pass (just one ApptRow)</param>
[788]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>
[1110]510 public virtual void PrintCancelLetter(dsRebookAppts.PatientApptsRow ptRow, PrintPageEventArgs e, string letter, string title)
[788]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
[789]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
[900]539 //Text Direction
540 StringFormat sf2 = new StringFormat();
541 if (System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.IsRightToLeft)
542 sf2.FormatFlags = StringFormatFlags.DirectionRightToLeft;
[1469]543
[788]544 // write missive
[900]545 g.DrawString(letter, fBody, Brushes.Black, printArea, sf2);
[788]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);
[1131]557
558 g.Dispose();
[788]559 }
560
[789]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>
[1110]568 public virtual void PrintRebookLetter(dsRebookAppts.PatientApptsRow ptRow, PrintPageEventArgs e, string letter, string title)
[789]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
[900]598 //Text Direction
599 StringFormat sf2 = new StringFormat();
600 if (System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.IsRightToLeft)
601 sf2.FormatFlags = StringFormatFlags.DirectionRightToLeft;
602
[789]603 // write missive
[900]604 g.DrawString(letter, fBody, Brushes.Black, printArea, sf2);
[789]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
[1131]617 g.Dispose();
[789]618 }
619
620 /// <summary>
621 /// Print message on a page; typically that there are no appointments to be found.
[804]622 /// Or just a test message to verify that printing works.
[789]623 /// </summary>
624 /// <param name="msg">The exact string to print.</param>
625 /// <param name="e">Print Page event args</param>
[1110]626 public virtual void PrintMessage(string msg, PrintPageEventArgs e)
[788]627 {
628 e.Graphics.DrawString(msg, new Font(FontFamily.GenericSerif, 14),
629 Brushes.Black, e.MarginBounds);
[1131]630 e.Graphics.Dispose();
[788]631 }
[804]632
633 /// <summary>
634 /// Print Routing Slip
635 /// </summary>
636 /// <param name="a">Appointment Data Structure</param>
[1156]637 /// <param name="apptOrder">Order of Appointment</param>
[804]638 /// <param name="e">etc</param>
[1112]639 public virtual void PrintRoutingSlip(CGAppointment appt, int apptOrder, PrintPageEventArgs e)
[804]640 {
[1469]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
[1112]664 Graphics g = e.Graphics;
[1469]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.ConnectInfo.DivisionName;
694 int divisionStringHeight = (int)g.MeasureString(division.ToString(), fontBody, e.MarginBounds.Width).Height;
[1112]695 Rectangle headerArea = new Rectangle()
696 {
[1469]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
[1112]701 };
[1469]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;
[1112]708 Rectangle footerArea = new Rectangle()
709 {
[1469]710 X = headerArea.X,
711 Y = e.PageBounds.Height - stringDataStringHeight - HardMarginY - (int)(5 * heightRatio),
712 Width = headerArea.Width,
713 Height = stringDataStringHeight
[1112]714 };
[1469]715 g.DrawString(stringData, fFooter, Brushes.Black, footerArea, sfCenterCenter);
[1112]716
717
718
[1469]719 //setting the printing area bigger than the margin bounds to use more printing space on the paper.
720 Rectangle printArea = new Rectangle()
[1112]721 {
[1469]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
[1112]726 };
727
728
[1469]729 // if there is a need for the watermark use the following code.
730 //const int watermarkLength = 75*heightratio;
[1131]731
732 // Move down for optional form paper
[1469]733 //printArea.Y += watermarkLength;
734 //printArea.Height -= watermarkLength;
[1131]735
[1112]736 // Draw Title
[1469]737 StringFormat sfCenter = new StringFormat();
738 sfCenter.Alignment = StringAlignment.Center; //for title & header
[1131]739 string title = strings.RoutingSlip;
[1469]740 g.DrawString(title, fontTitle, Brushes.Black, printArea, sfCenter); //title
[804]741
742 // move down
[1469]743 int titleHeight = (int)g.MeasureString(title, fontTitle, printArea.Width).Height;
[804]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));
[1469]749 printArea.Y += (int)(5 * heightRatio);
750 printArea.Height -= (int)(5 * heightRatio);
[804]751
[1469]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)
[1112]789 {
[1469]790 InfoInnerRectangleHeight = appointmentInformationStringHeight;
[1112]791 }
[804]792
[1469]793 // group header for the person informations.
794 stringData = strings.PtInfo;
[1131]795 StringFormat sf3 = new StringFormat(System.Threading.Thread.CurrentThread.CurrentUICulture.TextInfo.IsRightToLeft ? StringFormatFlags.DirectionRightToLeft : 0);
[1469]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);
[804]798
[1469]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);
[1131]802
[1469]803 //moving down
804 printArea.Y += stringDataStringHeight + (int)(5 * heightRatio);
805 printArea.Height -= stringDataStringHeight + (int)(5 * heightRatio);
[804]806
[1469]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))
[1112]810 {
811 g.DrawPath(Pens.Black, path);
812 }
813
[1469]814 // inner rectangle for drawing strings:
815 Rectangle personalInfoInnerRectangle = new Rectangle(personalInfoRectangle.X + (int)(5 * widthRatio), personalInfoRectangle.Y + (int)(5 * heightRatio), InfoInnerRectangleWidth, InfoInnerRectangleHeight);
[1112]816
[1469]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);
[1112]822
[1469]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 }
[1112]829
[1469]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
[1112]834 // Move Drawing Rectangle Down
[1469]835 printArea.Y += personalInfoRectangle.Height + (int)(5 * heightRatio);
836 printArea.Height -= personalInfoRectangle.Height + (int)(5 * heightRatio);
[1112]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
[1469]845 printArea.Y += (int)(5 * heightRatio);
846 printArea.Height -= (int)(5 * heightRatio);
[1112]847
[1469]848 stringData = strings.ScratchArea;
849 g.DrawString(stringData, fontGroupTitle, Brushes.Black, printArea, sf3);
850
[1156]851 /* Per Al-Najjar, we don't want the next appointment instructions section
[1112]852 // move down
[1131]853 printArea.Y += 240;
854 printArea.Height -= 240;
[1112]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
[1469]865 stringData = strings.NextAppointmentInstructions;
866 g.DrawString(stringData, fontGroupTitle, Brushes.Black, printArea, sf3);
[1156]867 */
[1112]868
869 g.Dispose();
870
[1110]871 }
[804]872
[772]873 }
[1110]874 public abstract class PrintingCreator
875 {
876 public abstract Printing PrintFactory();
877 }
878
879}
Note: See TracBrowser for help on using the repository browser.