/// <summary>c /// Commits the pdf to a stream. /// </summary> /// <param name="outstream">Outstream.</param> public static void Export(ScreenshotReport report, Stream outstream) { // Create the document to export. var document = new PdfFixedDocument(); // Add the first page. var page = document.Pages.Add(); // Init the document fonts var title = new PdfStandardFont(PdfStandardFontFace.HelveticaBold, 18); var subtitle = new PdfStandardFont(PdfStandardFontFace.HelveticaBold, 14); var header = new PdfStandardFont(PdfStandardFontFace.HelveticaBold, 12); var content = new PdfStandardFont(PdfStandardFontFace.Helvetica, 12); double ml, mt, mr, mb; // Margins ml = mt = mr = mb = 18; double pw = page.Width - (ml + mr); // Bounds // 0,0 is top left with positive x going right, and positive y going down. Lower // approaches the orgin whilst higher extends away from the orgin approaching infinity. var headerBounds = NewRect(ml, mt, pw, 50); // ux, uy, lx, ly var cx = page.Width / 2; var imageBounds = NewRect(ml, headerBounds.URY, cx - mr - ml, page.Height - headerBounds.Height - mt - mb); var contentBounds = NewRect(cx + mr, headerBounds.URY, cx - mr - ml, page.Height - headerBounds.Height - mt - mb); // Draw the page DrawHeader(report, page, headerBounds, title, subtitle); DrawScreenshot(report, page, imageBounds); DrawContent(report, page, contentBounds, header, content); // Commit document.Save(outstream); }
/// <summary> /// Draws the screenshot png. /// </summary> /// <param name="page">Page.</param> /// <param name="bounds">Bounds.</param> private static void DrawScreenshot(ScreenshotReport report, PdfPage page, PdfStandardRectangle bounds) { var l = bounds.LLX; var t = bounds.LLY; var ms = new MemoryStream(report.screenshot); var png = new PdfPngImage(ms); var whP = png.Width / (double)png.Height; // TODO [email protected]: If, for some strange reason, the height and width are stupid // disproprtional, the bottom of the image will hang of the page. // What I'm saying is: this bitch needs clipping. var w = bounds.Width; var h = ((double)w * (double)png.Height) / (double)png.Width; page.Graphics.DrawImage(png, l, t, w, h); }
/// <summary> /// Draws the header of the screenshot report. /// </summary> private static void DrawHeader(ScreenshotReport report, PdfPage page, PdfStandardRectangle bounds, PdfStandardFont title, PdfStandardFont subtitle) { var layout = NewLayout(PdfStringHorizontalAlign.Center); layout.Height = bounds.Height; layout.Width = bounds.Width; var pen = NewPen(); var g = page.Graphics; var l = bounds.LLX; var r = bounds.URX; layout.X = l; layout.Y = bounds.LLY; g.DrawString(report.title, NewAppearance(title), layout); layout.Y += PdfTextEngine.GetStringHeight("Dg", title, layout.Width); g.DrawString(report.subtitle, NewAppearance(subtitle), layout); layout.Y += PdfTextEngine.GetStringHeight("Dg", title, layout.Width); g.DrawLine(pen, l, layout.Y - 1, r, layout.Y - 1); }
/// <summary> /// Saves the screentshot report to the application's screenshot archive. /// </summary> private async void SaveScreenshotReport() { var pd = new ProgressDialog(this); pd.SetTitle(GetString(Resource.String.saving)); pd.SetMessage(GetString(Resource.String.please_wait)); pd.Indeterminate = true; pd.Show(); var task = Task.Factory.StartNew(() => { var report = new ScreenshotReport(); report.screenshot = screenshot; report.title = GetString(Resource.String.app_name) + " " + GetString(Resource.String.report_screenshot); report.subtitle = nameView.Text; // report.created = createdDate; report.notes = notesView.Text; report.tableData = new string[, ] { { GetString(Resource.String.date), createdDate.ToShortDateString() + " " + createdDate.ToShortTimeString() }, { GetString(Resource.String.app_version), ion.version }, { GetString(Resource.String.location_address_1), addressView1.Text }, { GetString(Resource.String.location_address_2), addressView2.Text }, { GetString(Resource.String.location_city), cityView.Text }, { GetString(Resource.String.location_state_province_region), stateView.Text }, { GetString(Resource.String.location_country), countryView.Text }, { GetString(Resource.String.zip), zipView.Text }, }; try { // TODO [email protected]: throw error if already exists var dir = ion.screenshotReportFolder; var file = dir.GetFile(report.subtitle + ".pdf", EFileAccessResponse.CreateIfMissing); using (var stream = file.OpenForWriting()) { ScreenshotReportPdfExporter.Export(report, stream); } return(new Result()); } catch (Exception e) { Log.E(this, "Failed to create screenshot pdf report", e); return(new Result(GetString(Resource.String.report_screenshot_error_export_failed))); } }); var result = await task; pd.Dismiss(); if (result.success) { Alert(Resource.String.report_screenshot_saved); } else { var err = new IONAlertDialog(this, "ERROR"); err.SetMessage(result.errorReason); err.SetNegativeButton(Resource.String.cancel, (obj, args) => { var d = obj as Dialog; if (d != null) { d.Dismiss(); } }); err.Show(); } Finish(); }
/// <summary> /// Draws the reports contents to the page. /// </summary> /// <param name="page">Page.</param> /// <param name="bounds">Bounds.</param> private static void DrawContent(ScreenshotReport report, PdfPage page, PdfStandardRectangle bounds, PdfStandardFont header, PdfStandardFont content) { var g = page.Graphics; var table = BuildReportContentTable(report.tableData, header, content); var xoffset = 0.0; var yoffset = 0.0; for (int c = 0; c < table.length; c++) { var col = table[c]; yoffset = 0.0; for (int r = 0; r < col.length; r++) { var l = NewLayout(); l.X = bounds.LLX + xoffset + (5 * c); l.Y = bounds.LLY + yoffset; l.Width = col.columnWidth; l.Height = col.rowHeight; g.DrawString(table[c][r], col.appearance, l); yoffset += col.rowHeight; } xoffset += col.columnWidth; } { var l = NewLayout(); l.X = bounds.LLX; l.Y = bounds.LLY + yoffset; l.Width = bounds.Width; l.Height = bounds.URY - l.Y; g.DrawString(report.notes, NewAppearance(content), l); } /* * var yoffset = 0.0; * var xoffset = 0.0; * * for (int c = 0; c < table.length; c++) { * var col = table[c]; * * if (c > 0) { * xoffset += col.columnWidth; * } * * var layout = NewLayout(); * layout.Width = col.columnWidth; * layout.Y = bounds.LLY; * layout.X = bounds.LLX + xoffset; * * for (int r = 0; r < col.length; r++) { * g.DrawString(col[r], col.appearance, layout); * layout.Y += col.rowHeight; * if (layout.Y > yoffset) { * yoffset = layout.Y; * } * } * } * * var looks = NewAppearance(content); * var l = NewLayout(); * l.X = bounds.LLX; * l.Y = yoffset; * l.Width = bounds.Width; * l.Height = bounds.Height - (bounds.LLY - yoffset); * * g.DrawString(report.notes, looks, l); */ }
private Result SaveScreenshot() { var report = new ScreenshotReport(); ///save date in original format for localization later //report.created = date; report.title = Strings.Report.SCREENSHOT_TITLE; //report.subtitle = reportTitle.value; report.subtitle = subtitle; //report.notes = notes.value; report.notes = notes.value; report.screenshot = image.AsPNG().ToArray(); //if (report.subtitle == null || report.subtitle.Equals("")) { // return new Result(Strings.Errors.SCREENSHOT_MISSING_TITLE); //} if (string.IsNullOrEmpty(subtitle)) { return(new Result(Strings.Errors.SCREENSHOT_MISSING_TITLE)); } /// adding an extra spot to manually add the localized date /// return here for possible raw data storage for different /// exporting formats //var data = new string[items.Count + 1, 2]; var data = new string[7, 2]; data[0, 0] = Strings.DATE; data[0, 1] = date.ToLocalTime().ToShortDateString(); //for (int i = 1; i <= items.Count; i++) { // var item = items[i - 1]; // data[i, 0] = item.header; // data[i, 1] = item.value; //} data[1, 0] = "App Version"; data[1, 1] = appversion; data[2, 0] = "Address Line 1"; data[2, 1] = address1; data[3, 0] = "Address Line 2"; data[3, 1] = address2; data[4, 0] = "City"; data[4, 1] = city; data[5, 0] = "State/Province/Region"; data[5, 1] = state; data[6, 0] = "ZIP/Postal Code"; data[6, 1] = zipcode; report.tableData = data; try { var dir = AppState.context.screenshotReportFolder; var file = dir.GetFile(report.subtitle + ".pdf", EFileAccessResponse.CreateIfMissing); using (var stream = file.OpenForWriting()) { ScreenshotReportPdfExporter.Export(report, stream); } } catch (Exception e) { // TODO [email protected]: this needs a user-friendly dialog that will post on catch Log.E(this, "Failed to export pdf", e); } return(new Result()); }