internal static void BuildReport(Library library, List <PDFDocument> pdf_documents) { FeatureTrackingManager.Instance.UseFeature(Features.Library_JSONAnnotationReport); AnnotationReportOptionsWindow.AnnotationReportOptions annotation_report_options = new AnnotationReportOptionsWindow.AnnotationReportOptions(); List <AnnotationWorkGenerator.AnnotationWork> annotation_works = AnnotationWorkGenerator.GenerateAnnotationWorks(library, pdf_documents, annotation_report_options); IEnumerable <AnnotationJSON> annotation_jsons = annotation_works.Select(annotation_work => new AnnotationJSON { fingerprint = annotation_work.pdf_document.Fingerprint, title = annotation_work.pdf_document.TitleCombined, page = annotation_work.pdf_annotation.Page, left = annotation_work.pdf_annotation.Left, top = annotation_work.pdf_annotation.Top, width = annotation_work.pdf_annotation.Width, height = annotation_work.pdf_annotation.Height, tags = annotation_work.pdf_annotation.Tags, text = annotation_work.pdf_annotation.Text, } ); string json = JsonConvert.SerializeObject(annotation_jsons, Formatting.Indented); string filename = Path.GetTempFileName() + ".json.txt"; File.WriteAllText(filename, json); Process.Start(filename); }
public static List <AnnotationWork> GenerateAnnotationWorks(Library library, List <PDFDocument> pdf_documents, AnnotationReportOptionsWindow.AnnotationReportOptions annotation_report_options) { List <AnnotationWork> annotation_works = new List <AnnotationWork>(); // The caches we will need... Dictionary <string, byte[]> library_items_highlights_cache = library.LibraryDB.GetLibraryItemsAsCache(PDFDocumentFileLocations.HIGHLIGHTS); Dictionary <string, byte[]> library_items_inks_cache = library.LibraryDB.GetLibraryItemsAsCache(PDFDocumentFileLocations.INKS); for (int j = 0; j < pdf_documents.Count; ++j) { if (j % 10 == 0) { StatusManager.Instance.UpdateStatus("AnnotationReport", "Initialising annotation report", j, pdf_documents.Count); } PDFDocument pdf_document = pdf_documents[j]; // Add the comments token if this document has some comments or abstract (and the user wants them) if (annotation_report_options.IncludeAllPapers) { if (!String.IsNullOrEmpty(pdf_document.Comments) || !String.IsNullOrEmpty(pdf_document.Abstract)) { annotation_works.Add(new AnnotationWork { library = library, pdf_document = pdf_document, pdf_annotation = null }); } } List <PDFAnnotation> pdf_annotations = new List <PDFAnnotation>(); pdf_annotations.AddRange(pdf_document.Annotations); if (library_items_highlights_cache.ContainsKey(pdf_document.Fingerprint)) { pdf_annotations.AddRange(HighlightToAnnotationGenerator.GenerateAnnotations(pdf_document, library_items_highlights_cache)); } if (library_items_inks_cache.ContainsKey(pdf_document.Fingerprint)) { pdf_annotations.AddRange(InkToAnnotationGenerator.GenerateAnnotations(pdf_document, library_items_inks_cache)); } pdf_annotations.Sort(AnnotationSorter); foreach (PDFAnnotation pdf_annotation in pdf_annotations) { if (pdf_annotation.Deleted) { continue; } // Filter by annotations if (null != annotation_report_options.filter_tags && annotation_report_options.filter_tags.Count > 0) { HashSet <string> annotation_tags = new HashSet <string>(TagTools.ConvertTagBundleToTags(pdf_annotation.Tags)); annotation_tags.IntersectWith(annotation_report_options.filter_tags); if (0 == annotation_tags.Count) { continue; } } // Filter by date ranges and creators { if (annotation_report_options.FilterByCreationDate && pdf_annotation.DateCreated.HasValue) { DateTime date_to = annotation_report_options.FilterByCreationDate_To; if (date_to != DateTime.MaxValue) { date_to = date_to.AddDays(1); } if (pdf_annotation.DateCreated.Value < annotation_report_options.FilterByCreationDate_From) { continue; } if (pdf_annotation.DateCreated.Value >= date_to) { continue; } } if (annotation_report_options.FilterByFollowUpDate) { DateTime date_to = annotation_report_options.FilterByFollowUpDate_To; if (date_to != DateTime.MaxValue) { date_to = date_to.AddDays(1); } if (!pdf_annotation.FollowUpDate.HasValue) { continue; } if (pdf_annotation.FollowUpDate.Value < annotation_report_options.FilterByFollowUpDate_From) { continue; } if (pdf_annotation.FollowUpDate.Value >= date_to) { continue; } } if (annotation_report_options.FilterByCreator) { if (pdf_annotation.Creator != annotation_report_options.FilterByCreator_Name) { continue; } } } annotation_works.Add(new AnnotationWork { library = library, pdf_document = pdf_document, pdf_annotation = pdf_annotation }); } } return(annotation_works); }
internal static AnnotationReport BuildReport(Library library, List <PDFDocument> pdf_documents, AnnotationReportOptionsWindow.AnnotationReportOptions annotation_report_options) { char NBSPACE = System.Convert.ToChar(160); AnnotationReport annotation_report = new AnnotationReport(); StandardFlowDocument flow_document = annotation_report.flow_document; // Create a list of all the work we need to do List <AnnotationWorkGenerator.AnnotationWork> annotation_works = AnnotationWorkGenerator.GenerateAnnotationWorks(library, pdf_documents, annotation_report_options); // Now build the report PDFDocument last_pdf_document = null; for (int j = 0; j < annotation_works.Count; ++j) { StatusManager.Instance.UpdateStatus("AnnotationReport", "Building annotation report", j, annotation_works.Count); AnnotationWorkGenerator.AnnotationWork annotation_work = annotation_works[j]; PDFDocument pdf_document = annotation_work.pdf_document; PDFAnnotation pdf_annotation = annotation_work.pdf_annotation; // If this is a new PDFDocument, print out the header if (last_pdf_document != pdf_document) { last_pdf_document = pdf_document; Logging.Info("Processing {0}", pdf_document.Fingerprint); if (!annotation_report_options.SuppressPDFDocumentHeader) { Span bold_title = new Span(); bold_title.FontSize = 30; bold_title.FontFamily = ThemeTextStyles.FontFamily_Header; bold_title.Inlines.Add(new LineBreak()); if (!String.IsNullOrEmpty(pdf_document.TitleCombined)) { bold_title.Inlines.Add(pdf_document.TitleCombined); bold_title.Inlines.Add(new LineBreak()); } Span bold = new Span(); bold.FontSize = 16; if (!String.IsNullOrEmpty(pdf_document.YearCombined)) { bold.Inlines.Add(pdf_document.YearCombined); bold.Inlines.Add(" · "); } if (!String.IsNullOrEmpty(pdf_document.AuthorsCombined)) { bold.Inlines.Add(pdf_document.AuthorsCombined); } if (!String.IsNullOrEmpty(pdf_document.Publication)) { Italic italic = new Italic(); italic.Inlines.Add(pdf_document.Publication); bold.Inlines.Add(new LineBreak()); bold.Inlines.Add(italic); } if (!String.IsNullOrEmpty(pdf_document.Tags)) { bold.Inlines.Add(new LineBreak()); Run run = new Run(); run.Text = "[" + pdf_document.Tags + "]"; bold.Inlines.Add(run); } bold.Inlines.Add(new LineBreak()); { bold.Inlines.Add(new LineBreak()); Span click_options = new Span(); { { Run run = new Run(" Open "); run.Background = ThemeColours.Background_Brush_Blue_VeryVeryDark; run.Foreground = Brushes.White; run.Cursor = Cursors.Hand; run.Tag = pdf_document; run.MouseDown += run_Open_MouseDown; click_options.Inlines.Add(run); } click_options.Inlines.Add(new Run(" ")); { Run run = new Run(" Cite (Author, Date) "); run.Background = ThemeColours.Background_Brush_Blue_VeryVeryDark; run.Foreground = Brushes.White; run.Cursor = Cursors.Hand; run.Tag = pdf_document; run.MouseDown += run_Cite_MouseDown_Together; click_options.Inlines.Add(run); } click_options.Inlines.Add(new Run(" ")); { Run run = new Run(" [Cite Author (Date)] "); run.Background = ThemeColours.Background_Brush_Blue_VeryVeryDark; run.Foreground = Brushes.White; run.Cursor = Cursors.Hand; run.Tag = pdf_document; run.MouseDown += run_Cite_MouseDown_Separate; click_options.Inlines.Add(run); } click_options.Inlines.Add(new LineBreak()); bold.Inlines.Add(click_options); annotation_report.AddClickOption(click_options); } } Paragraph paragraph_header = new Paragraph(); paragraph_header.Inlines.Add(bold_title); paragraph_header.Inlines.Add(bold); Section section_header = new Section(); section_header.Background = ThemeColours.Background_Brush_Blue_VeryVeryDarkToWhite; if (Colors.Transparent != pdf_document.Color) { section_header.Background = new SolidColorBrush(pdf_document.Color); } section_header.Blocks.Add(paragraph_header); flow_document.Blocks.Add(new Paragraph(new LineBreak())); flow_document.Blocks.Add(section_header); //flow_document.Blocks.Add(new Paragraph(new LineBreak())); bool have_document_details = false; // Add the paper comment if we need to if (annotation_report_options.IncludeComments) { string comment_text = pdf_document.Comments; if (!String.IsNullOrEmpty(comment_text)) { have_document_details = true; flow_document.Blocks.Add(new Paragraph(new Run("●"))); { Paragraph paragraph = new Paragraph(); { Bold header = new Bold(); header.Inlines.Add("Comments: "); paragraph.Inlines.Add(header); } { Italic italic = new Italic(); italic.Inlines.Add(comment_text); paragraph.Inlines.Add(italic); } flow_document.Blocks.Add(paragraph); } } } if (annotation_report_options.IncludeAbstract) { string abstract_text = pdf_document.Abstract; if (PDFAbstractExtraction.CANT_LOCATE != abstract_text) { have_document_details = true; flow_document.Blocks.Add(new Paragraph(new Run("●"))); { Paragraph paragraph = new Paragraph(); { Bold header = new Bold(); header.Inlines.Add("Abstract: "); paragraph.Inlines.Add(header); } { Italic italic = new Italic(); italic.Inlines.Add(abstract_text); paragraph.Inlines.Add(italic); } flow_document.Blocks.Add(paragraph); } } } if (have_document_details) { flow_document.Blocks.Add(new Paragraph(new Run("●"))); } } } // Print out the annotation if (null != pdf_annotation) { // First the header { //flow_document.Blocks.Add(new Paragraph(new Run(" ● "))); Paragraph paragraph = new Paragraph(); paragraph.Inlines.Add(new LineBreak()); { Bold coloured_blob = new Bold(); coloured_blob.Foreground = new SolidColorBrush(pdf_annotation.Color); coloured_blob.Inlines.Add(" ■ "); paragraph.Inlines.Add(coloured_blob); } { Span italic = new Span(); italic.FontSize = 16; string annotation_header = String.Format("Page {0}", pdf_annotation.Page); italic.Inlines.Add(annotation_header); Underline underline = new Underline(italic); paragraph.Inlines.Add(italic); } { Bold coloured_blob = new Bold(); coloured_blob.Foreground = new SolidColorBrush(pdf_annotation.Color); coloured_blob.Inlines.Add(" ■ "); paragraph.Inlines.Add(coloured_blob); } paragraph.Inlines.Add(new LineBreak()); // List the tags for this annotation if (!annotation_report_options.SuppressPDFAnnotationTags) { if (!String.IsNullOrEmpty(pdf_annotation.Tags)) { paragraph.Inlines.Add(" [" + pdf_annotation.Tags.Replace(";", "; ") + "] "); paragraph.Inlines.Add(new LineBreak()); } } bool is_not_synthetic_annotation = (null == pdf_annotation.Tags || (!pdf_annotation.Tags.Contains(HighlightToAnnotationGenerator.HIGHLIGHTS_TAG) && !pdf_annotation.Tags.Contains(InkToAnnotationGenerator.INKS_TAG))); { paragraph.Inlines.Add(new LineBreak()); Span click_options = new Span(); { Run run = new Run(" Open "); run.Background = ThemeColours.Background_Brush_Blue_VeryDark; run.Foreground = Brushes.White; run.Cursor = Cursors.Hand; run.Tag = annotation_work; run.MouseDown += run_AnnotationOpen_MouseDown; click_options.Inlines.Add(run); } if (is_not_synthetic_annotation) { click_options.Inlines.Add(new Run(" ")); Run run = new Run(" Edit "); run.Background = ThemeColours.Background_Brush_Blue_VeryDark; run.Foreground = Brushes.White; run.Cursor = Cursors.Hand; run.Tag = pdf_annotation; run.MouseDown += run_AnnotationEdit_MouseDown; click_options.Inlines.Add(run); } { click_options.Inlines.Add(new Run(" ")); Run run = new Run(" Cite (Author, Date) "); run.Background = ThemeColours.Background_Brush_Blue_VeryDark; run.Foreground = Brushes.White; run.Cursor = Cursors.Hand; run.Tag = pdf_document; run.MouseDown += run_Cite_MouseDown_Together; click_options.Inlines.Add(run); } { click_options.Inlines.Add(new Run(" ")); Run run = new Run(" Cite Author (Date) "); run.Background = ThemeColours.Background_Brush_Blue_VeryDark; run.Foreground = Brushes.White; run.Cursor = Cursors.Hand; run.Tag = pdf_document; run.MouseDown += run_Cite_MouseDown_Separate; click_options.Inlines.Add(run); } click_options.Inlines.Add(new LineBreak()); paragraph.Inlines.Add(click_options); annotation_report.AddClickOption(click_options); } { Run run = new Run("Waiting for processing..."); run.Foreground = Brushes.Red; paragraph.Inlines.Add(run); annotation_work.processing_error = run; } paragraph.Background = ThemeColours.Background_Brush_Blue_DarkToWhite; flow_document.Blocks.Add(paragraph); } if (!String.IsNullOrEmpty(pdf_annotation.Text)) { Paragraph paragraph = new Paragraph(); paragraph.Inlines.Add(pdf_annotation.Text); flow_document.Blocks.Add(paragraph); } { // Prepare for some annotation image if ((!annotation_report_options.ObeySuppressedImages || !pdf_annotation.AnnotationReportSuppressImage) && !annotation_report_options.SuppressAllImages) { Image image = new Image(); MouseWheelDisabler.DisableMouseWheelForControl(image); image.Source = Icons.GetAppIcon(Icons.AnnotationReportImageWaiting); BlockUIContainer image_container = new BlockUIContainer(image); Figure floater = new Figure(image_container); floater.HorizontalAnchor = FigureHorizontalAnchor.PageCenter; floater.WrapDirection = WrapDirection.None; floater.Width = new FigureLength(64); floater.Cursor = Cursors.Hand; floater.Tag = annotation_work; floater.MouseDown += Floater_MouseDown; Paragraph paragraph = new Paragraph(); paragraph.Inlines.Add(floater); annotation_work.report_image = image; annotation_work.report_floater = floater; flow_document.Blocks.Add(paragraph); } // Prepare for some annotation text if ((!annotation_report_options.ObeySuppressedText || !pdf_annotation.AnnotationReportSuppressText) && !annotation_report_options.SuppressAllText) { Paragraph paragraph = new Paragraph(); annotation_work.annotation_paragraph = paragraph; flow_document.Blocks.Add(paragraph); } } } // Add another paragraph to separate nicely { Paragraph paragraph = new Paragraph(); flow_document.Blocks.Add(paragraph); } } // Render the images in the background BackgroundRenderImages(flow_document, annotation_works, annotation_report_options); // Finito! StatusManager.Instance.ClearStatus("AnnotationReport"); return(annotation_report); }
private static void OnShowTagOptionsComplete(Library library, List <PDFDocument> pdf_documents, AnnotationReportOptionsWindow.AnnotationReportOptions annotation_report_options) { var annotation_report = BuildReport(library, pdf_documents, annotation_report_options); FlowDocumentScrollViewer viewer = new FlowDocumentScrollViewer(); viewer.Document = annotation_report.flow_document; ControlHostingWindow window = new ControlHostingWindow("Annotations", viewer); window.Show(); }
static void BackgroundRenderImages_BACKGROUND(FlowDocument flow_document, List <AnnotationWorkGenerator.AnnotationWork> annotation_works, AnnotationReportOptionsWindow.AnnotationReportOptions annotation_report_options) { Thread.Sleep(annotation_report_options.InitialRenderDelayMilliseconds); PDFDocument last_pdf_document = null; StatusManager.Instance.ClearCancelled("AnnotationReportBackground"); for (int j = 0; j < annotation_works.Count; ++j) { StatusManager.Instance.UpdateStatus("AnnotationReportBackground", "Building annotation report image", j, annotation_works.Count, true); if (StatusManager.Instance.IsCancelled("AnnotationReportBackground")) { Logging.Warn("User cancelled annotation report generation"); break; } AnnotationWorkGenerator.AnnotationWork annotation_work = annotation_works[j]; PDFDocument pdf_document = annotation_work.pdf_document; // Clear down our previously caches pages if (null != last_pdf_document && last_pdf_document != pdf_document) { if (last_pdf_document.DocumentExists) { last_pdf_document.PDFRenderer.FlushCachedPageRenderings(); } } // Remember this PDF document so we can flush it if necessary last_pdf_document = pdf_document; // Now render each image PDFAnnotation pdf_annotation = annotation_work.pdf_annotation; if (null != pdf_annotation) { try { // Clear the waiting for processing text annotation_work.processing_error.Dispatcher.Invoke(new Action(() => { annotation_work.processing_error.Text = ""; } ), DispatcherPriority.Background); if (pdf_document.DocumentExists) { // Fill in the paragraph text if (null != annotation_work.annotation_paragraph) { annotation_work.processing_error.Dispatcher.Invoke( new Action(() => BuildAnnotationWork_FillAnnotationText(pdf_document, pdf_annotation, annotation_work)), DispatcherPriority.Background); } if (null != annotation_work.report_floater) { annotation_work.processing_error.Dispatcher.Invoke(new Action(() => { try { System.Drawing.Image annotation_image = PDFAnnotationToImageRenderer.RenderAnnotation(pdf_document, pdf_annotation, 80); BitmapSource cropped_image_page = BitmapImageTools.FromImage(annotation_image); annotation_work.report_image.Source = cropped_image_page; annotation_work.report_floater.Width = new FigureLength(cropped_image_page.PixelWidth / 1); } catch (Exception ex) { Logging.Warn(ex, "There was a problem while rendering an annotation."); annotation_work.report_image.Source = Icons.GetAppIcon(Icons.AnnotationReportImageError); annotation_work.processing_error.Text = "There was a problem while rendering this annotation."; } } ), DispatcherPriority.Background); } } else { annotation_work.processing_error.Dispatcher.Invoke(new Action(() => { if (null != annotation_work.report_image) { annotation_work.report_image.Source = Icons.GetAppIcon(Icons.AnnotationReportImageError); } annotation_work.processing_error.Text = "Can't show image: The PDF does not exist locally."; } ), DispatcherPriority.Background); } } catch (Exception ex) { Logging.Error(ex, "There was an error while rendering page {0} for document {1} for the annotation report", pdf_annotation.Page, pdf_annotation.DocumentFingerprint); annotation_work.processing_error.Dispatcher.Invoke(new Action(() => { if (null != annotation_work.report_image) { annotation_work.report_image.Source = Icons.GetAppIcon(Icons.AnnotationReportImageError); } annotation_work.processing_error.Text = "Can't show image: There was an error rendering the metadata image."; } ), DispatcherPriority.Background); } } } // And flush the rendering cache of the last document if (null != last_pdf_document) { if (last_pdf_document.DocumentExists) { last_pdf_document.PDFRenderer.FlushCachedPageRenderings(); } } StatusManager.Instance.ClearStatus("AnnotationReportBackground"); }
static void BackgroundRenderImages(FlowDocument flow_document, List <AnnotationWorkGenerator.AnnotationWork> annotation_works, AnnotationReportOptionsWindow.AnnotationReportOptions annotation_report_options) { // Render the images in the background SafeThreadPool.QueueUserWorkItem(o => BackgroundRenderImages_BACKGROUND(flow_document, annotation_works, annotation_report_options)); }