/// <summary> /// Deep clone, but does not copy the OnPDFAnnotationListChanged subscribers. /// </summary> public object Clone() { var clone = new PDFAnnotationList(); foreach (var annotation in annotations) { clone.AddUpdatedAnnotation((PDFAnnotation)annotation.Clone()); } return(clone); }
public PDFAnnotationList GetAnnotations(Dictionary <string, byte[]> library_items_annotations_cache) { if (null == annotations) { annotations = new PDFAnnotationList(); PDFAnnotationSerializer.ReadFromDisk(this, annotations, library_items_annotations_cache); annotations.OnPDFAnnotationListChanged += annotations_OnPDFAnnotationListChanged; } return(annotations); }
internal PDFDocument(WebLibraryDetail web_library_detail, DictionaryBasedObject dictionary, PDFAnnotationList prefetched_annotations_for_document = null) { this.library = new TypedWeakReference <WebLibraryDetail>(web_library_detail); this.dictionary = dictionary; // process any prefetched annotations that we may have as usual: if (prefetched_annotations_for_document != null) { annotations = prefetched_annotations_for_document; lock (access_lock) { dirtyNeedsReindexing = (prefetched_annotations_for_document.Count > 0); } } }
/// <summary> /// NB: only call this as part of document creation. /// </summary> public void CloneMetaData(PDFDocument existing_pdf_document) { bindable = null; Logging.Info("Cloning metadata from {0}", existing_pdf_document.Title); dictionary = (DictionaryBasedObject)existing_pdf_document.dictionary.Clone(); annotations = (PDFAnnotationList)existing_pdf_document.Annotations.Clone(); highlights = (PDFHightlightList)existing_pdf_document.Highlights.Clone(); inks = (PDFInkList)existing_pdf_document.Inks.Clone(); SaveToMetaData(); // Copy the citations PDFDocumentCitationManager.CloneFrom(existing_pdf_document.PDFDocumentCitationManager); // Now clear out the references for the annotations and highlights, so that when they are reloaded the events are resubscribed annotations = null; highlights = null; inks = null; }
/// <summary> /// Throws exception when metadata could not be converted to a valid PDFDocument instance. /// </summary> /// <param name="library"></param> /// <param name="data"></param> /// <param name="library_items_annotations_cache"></param> /// <returns></returns> public static PDFDocument LoadFromMetaData(WebLibraryDetail web_library_detail, string fingerprint, byte[] data, PDFAnnotationList prefetched_annotations_for_document = null) { WPFDoEvents.AssertThisCodeIs_NOT_RunningInTheUIThread(); ASSERT.Test(!String.IsNullOrEmpty(fingerprint)); DictionaryBasedObject dictionary = PDFMetadataSerializer.ReadFromStream(data); // Recover partially damaged record: if there's no fingerprint in the dictionary, add the given one: string id = dictionary["Fingerprint"] as string; if (String.IsNullOrEmpty(id)) { Logging.Error("Library '{1}' corrupted? Sanity check: the document record for document fingerprint {0} lacked a fingerprint as part of the mandatory metadata. This has been fixed now.", fingerprint, web_library_detail.DescriptiveTitle); dictionary["Fingerprint"] = fingerprint; id = fingerprint; } // extra verification / sanity check: this will catch some very obscure DB corruption, or rather **manual editing**! ;-) if (id != fingerprint || true) { // see which of them makes the most sense... And DO remember that Qiqqa fingeerprint hashes are variable-length, due to an old systemic bug! Regex re = new Regex(@"^[a-zA-Z0-9]{20,}(?:_REF)?$"); bool id_is_possibly_legal = re.IsMatch(id); bool key_is_possibly_legal = re.IsMatch(fingerprint); // if the entry in the record itself is legal, run with that one. Otherwise, fall back to using the DB record KEY. if (id_is_possibly_legal) { Logging.Error("Library '{2}' corrupted? Sanity check: given fingerprint '{0}' does not match the fingerprint '{1}' obtained from the DB metadata record. Running with the fingerprint specified in the metadata record.", fingerprint, id, web_library_detail.DescriptiveTitle); } else { Logging.Error("Library '{2}' corrupted? Sanity check: given fingerprint '{0}' does not match the fingerprint '{1}' obtained from the DB metadata record. Running with the fingerprint specified as database record KEY, since the other fingerprint does not look like a LEGAL fingerprint.", fingerprint, id, web_library_detail.DescriptiveTitle); dictionary["Fingerprint"] = fingerprint; id = fingerprint; } } PDFDocument pdf_document = new PDFDocument(web_library_detail, dictionary, prefetched_annotations_for_document); // thread-UNSAFE access is permitted as the PDF has just been created and // is NOT known to the outside world (i.e. beyond the scope of this function) // so there's no thread-safety risk yet. _ = pdf_document.GetAnnotations(); return(pdf_document); }