diff --git a/Qiqqa/Brainstorm/Nodes/PDFAnnotationNodeContentControl.xaml.cs b/Qiqqa/Brainstorm/Nodes/PDFAnnotationNodeContentControl.xaml.cs index 4a8b7e793..67e5228da 100644 --- a/Qiqqa/Brainstorm/Nodes/PDFAnnotationNodeContentControl.xaml.cs +++ b/Qiqqa/Brainstorm/Nodes/PDFAnnotationNodeContentControl.xaml.cs @@ -24,6 +24,17 @@ public partial class PDFAnnotationNodeContentControl : UserControl, IKeyPressabl { PDFAnnotationNodeContent pdf_annotation_node_content; + // TODO: + // + // Warning CA1001 Implement IDisposable on 'PDFAnnotationNodeContentControl' because it creates + // members of the following IDisposable types: 'LibraryIndexHoverPopup'. + // If 'PDFAnnotationNodeContentControl' has previously shipped, adding new members that implement + // IDisposable to this type is considered a breaking change to existing consumers. + // + // Note from GHO: that object is already managed through the sequence of tooltip_open and tooltip_close + // handlers below and is currently not considered a memory leak risk for https://github.com/jimmejardine/qiqqa-open-source/issues/19 + // and there-abouts. + LibraryIndexHoverPopup library_index_hover_popup = null; public PDFAnnotationNodeContentControl(NodeControl node_control, PDFAnnotationNodeContent pdf_annotation_node_content) diff --git a/Qiqqa/Brainstorm/Nodes/PDFDocumentNodeContentControl.xaml.cs b/Qiqqa/Brainstorm/Nodes/PDFDocumentNodeContentControl.xaml.cs index c8f6de57d..be91efe35 100644 --- a/Qiqqa/Brainstorm/Nodes/PDFDocumentNodeContentControl.xaml.cs +++ b/Qiqqa/Brainstorm/Nodes/PDFDocumentNodeContentControl.xaml.cs @@ -28,6 +28,17 @@ public partial class PDFDocumentNodeContentControl : UserControl, IKeyPressableN NodeControl node_control; PDFDocumentNodeContent pdf_document_node_content; + // TODO: + // + // Warning CA1001 Implement IDisposable on 'PDFAnnotationNodeContentControl' because it creates + // members of the following IDisposable types: 'LibraryIndexHoverPopup'. + // If 'PDFAnnotationNodeContentControl' has previously shipped, adding new members that implement + // IDisposable to this type is considered a breaking change to existing consumers. + // + // Note from GHO: that object is already managed through the sequence of tooltip_open and tooltip_close + // handlers below and is currently not considered a memory leak risk for https://github.com/jimmejardine/qiqqa-open-source/issues/19 + // and there-abouts. + LibraryIndexHoverPopup library_index_hover_popup = null; public PDFDocumentNodeContentControl(NodeControl node_control, PDFDocumentNodeContent pdf_document_node_content) diff --git a/Qiqqa/Brainstorm/SceneManager/SceneRenderingControl.xaml.cs b/Qiqqa/Brainstorm/SceneManager/SceneRenderingControl.xaml.cs index adfbbaf55..a5869aead 100644 --- a/Qiqqa/Brainstorm/SceneManager/SceneRenderingControl.xaml.cs +++ b/Qiqqa/Brainstorm/SceneManager/SceneRenderingControl.xaml.cs @@ -351,10 +351,17 @@ private void DragDropClipboard_AddUrl(string url) || url_lower.EndsWith(".jpeg", StringComparison.CurrentCultureIgnoreCase) ) { - MemoryStream ms_image; - UrlDownloader.DownloadWithBlocking(ConfigurationManager.Instance.Proxy, url, out ms_image); - ImageNodeContent inc = new ImageNodeContent(ms_image); - AddNewNodeControl(inc, mouse_current_virtual.X, mouse_current_virtual.Y); + MemoryStream ms_image = null; + try + { + UrlDownloader.DownloadWithBlocking(ConfigurationManager.Instance.Proxy, url, out ms_image); + ImageNodeContent inc = new ImageNodeContent(ms_image); + AddNewNodeControl(inc, mouse_current_virtual.X, mouse_current_virtual.Y); + } + finally + { + ms_image.Dispose(); + } } else { diff --git a/Qiqqa/Chat/ChatControl.xaml.cs b/Qiqqa/Chat/ChatControl.xaml.cs index e8508e97a..618931495 100644 --- a/Qiqqa/Chat/ChatControl.xaml.cs +++ b/Qiqqa/Chat/ChatControl.xaml.cs @@ -179,81 +179,83 @@ class ChatRecord private void ProcessDisplayResponse(MemoryStream ms) { // Process the lines - StreamReader sr = new StreamReader(ms); - List chat_records = new List(); - { - string line; - ChatRecord last_chat_record = null; - while (null != (line = sr.ReadLine())) - { - string[] items = line.Split('\t'); - { - last_chat_record = new ChatRecord(); - last_chat_record.Timestamp = items[0]; - last_chat_record.Forum = items[1]; - last_chat_record.Username = items[2]; - last_chat_record.Comment = items[3]; - } - chat_records.Add(last_chat_record); - } - - // Record the last epoch - if (null != last_chat_record) - { - last_epoch = last_chat_record.Timestamp; - } - } - - // If there has been new chat, poll frequently - if (0 < chat_records.Count) - { - current_sleep_backoff_seconds = 1; - next_autopoll_datetime = DateTime.UtcNow.AddSeconds(current_sleep_backoff_seconds); - } - else - { - current_sleep_backoff_seconds = Math.Min(MAX_SLEEP_BACKOFF_SECONDS, 2 * current_sleep_backoff_seconds); - next_autopoll_datetime = DateTime.UtcNow.AddSeconds(current_sleep_backoff_seconds); - } - - // Update GUI - Application.Current.Dispatcher.BeginInvoke(new Action(() => - { - bool is_currently_at_scroll_bottom = ObjChatFlowDocumentScroll.VerticalOffset == ObjChatFlowDocumentScroll.ScrollableHeight; - - foreach (ChatRecord chat_record in chat_records) - { - // Is this a different user chatting? - if (null == previous_chat_record || chat_record.Username != previous_chat_record.Username || null == previous_paragraph) - { - previous_paragraph = new Paragraph(); - ObjChatFlowDocument.Blocks.Add(previous_paragraph); - - previous_paragraph.TextAlignment = ToggleTextAlignment(); - - Run username_run = new Run(chat_record.Username); - username_run.ToolTip = String.Format("{0} ({1})", chat_record.Username, chat_record.Timestamp); - username_run.FontSize = 12; - username_run.FontStyle = FontStyles.Italic; - username_run.Foreground = ThemeColours.Background_Brush_Blue_VeryVeryDark; - username_run.Cursor = Cursors.Pen; - username_run.MouseDown += username_run_MouseDown; - - previous_paragraph.Inlines.Add(username_run); - } - - previous_paragraph.Inlines.Add(new LineBreak()); - previous_paragraph.Inlines.Add(new Run(chat_record.Comment)); - - previous_chat_record = chat_record; - } - - if (is_currently_at_scroll_bottom) - { - ObjChatFlowDocumentScroll.ScrollToEnd(); - } - } - )); + using (StreamReader sr = new StreamReader(ms)) + { + List chat_records = new List(); + { + string line; + ChatRecord last_chat_record = null; + while (null != (line = sr.ReadLine())) + { + string[] items = line.Split('\t'); + { + last_chat_record = new ChatRecord(); + last_chat_record.Timestamp = items[0]; + last_chat_record.Forum = items[1]; + last_chat_record.Username = items[2]; + last_chat_record.Comment = items[3]; + } + chat_records.Add(last_chat_record); + } + + // Record the last epoch + if (null != last_chat_record) + { + last_epoch = last_chat_record.Timestamp; + } + } + + // If there has been new chat, poll frequently + if (0 < chat_records.Count) + { + current_sleep_backoff_seconds = 1; + next_autopoll_datetime = DateTime.UtcNow.AddSeconds(current_sleep_backoff_seconds); + } + else + { + current_sleep_backoff_seconds = Math.Min(MAX_SLEEP_BACKOFF_SECONDS, 2 * current_sleep_backoff_seconds); + next_autopoll_datetime = DateTime.UtcNow.AddSeconds(current_sleep_backoff_seconds); + } + + // Update GUI + Application.Current.Dispatcher.BeginInvoke(new Action(() => + { + bool is_currently_at_scroll_bottom = ObjChatFlowDocumentScroll.VerticalOffset == ObjChatFlowDocumentScroll.ScrollableHeight; + + foreach (ChatRecord chat_record in chat_records) + { + // Is this a different user chatting? + if (null == previous_chat_record || chat_record.Username != previous_chat_record.Username || null == previous_paragraph) + { + previous_paragraph = new Paragraph(); + ObjChatFlowDocument.Blocks.Add(previous_paragraph); + + previous_paragraph.TextAlignment = ToggleTextAlignment(); + + Run username_run = new Run(chat_record.Username); + username_run.ToolTip = String.Format("{0} ({1})", chat_record.Username, chat_record.Timestamp); + username_run.FontSize = 12; + username_run.FontStyle = FontStyles.Italic; + username_run.Foreground = ThemeColours.Background_Brush_Blue_VeryVeryDark; + username_run.Cursor = Cursors.Pen; + username_run.MouseDown += username_run_MouseDown; + + previous_paragraph.Inlines.Add(username_run); + } + + previous_paragraph.Inlines.Add(new LineBreak()); + previous_paragraph.Inlines.Add(new Run(chat_record.Comment)); + + previous_chat_record = chat_record; + } + + if (is_currently_at_scroll_bottom) + { + ObjChatFlowDocumentScroll.ScrollToEnd(); + } + } + )); + } } void username_run_MouseDown(object sender, MouseButtonEventArgs e) diff --git a/Qiqqa/Common/AssociatePDFWithVanillaReferenceWindow.xaml.cs b/Qiqqa/Common/AssociatePDFWithVanillaReferenceWindow.xaml.cs index f9b93a05e..31717f02b 100644 --- a/Qiqqa/Common/AssociatePDFWithVanillaReferenceWindow.xaml.cs +++ b/Qiqqa/Common/AssociatePDFWithVanillaReferenceWindow.xaml.cs @@ -66,20 +66,21 @@ void CmdWeb_Click(object sender, RoutedEventArgs e) void CmdLocal_Click(object sender, RoutedEventArgs e) { - System.Windows.Forms.OpenFileDialog dlg = new System.Windows.Forms.OpenFileDialog + using (System.Windows.Forms.OpenFileDialog dlg = new System.Windows.Forms.OpenFileDialog { CheckFileExists = true, CheckPathExists = true, Filter = "PDF Files|*.pdf", Multiselect = false, Title = "Select the PDF document you wish to associate with this Vanilla Reference." - }; - - if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) - { - FeatureTrackingManager.Instance.UseFeature(Features.Library_AttachToVanilla_Local); - pdf_document.AssociatePDFWithVanillaReference(dlg.FileName); - } + }) + { + if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + FeatureTrackingManager.Instance.UseFeature(Features.Library_AttachToVanilla_Local); + pdf_document.AssociatePDFWithVanillaReference(dlg.FileName); + } + } this.Close(); } diff --git a/Qiqqa/Common/Configuration/WebsiteAccess.cs b/Qiqqa/Common/Configuration/WebsiteAccess.cs index 0ecca1de5..1f39832eb 100644 --- a/Qiqqa/Common/Configuration/WebsiteAccess.cs +++ b/Qiqqa/Common/Configuration/WebsiteAccess.cs @@ -126,11 +126,13 @@ public static void OpenOffsiteUrl(string finalUrl) /// public static string DownloadFile(OurSiteFileKind fileType) { - WebClient web_client = new WebClient(); - web_client.Proxy = ConfigurationManager.Instance.Proxy; - string temp_file = TempFile.GenerateTempFilename("tmp"); - web_client.DownloadFile(GetOurFileUrl(fileType), temp_file); - return temp_file; + using (WebClient web_client = new WebClient()) + { + web_client.Proxy = ConfigurationManager.Instance.Proxy; + string temp_file = TempFile.GenerateTempFilename("tmp"); + web_client.DownloadFile(GetOurFileUrl(fileType), temp_file); + return temp_file; + } } /// diff --git a/Qiqqa/Common/ReadOutLoud/ReadOutLoudManager.cs b/Qiqqa/Common/ReadOutLoud/ReadOutLoudManager.cs index cef31b1b5..ecc96aa96 100644 --- a/Qiqqa/Common/ReadOutLoud/ReadOutLoudManager.cs +++ b/Qiqqa/Common/ReadOutLoud/ReadOutLoudManager.cs @@ -11,6 +11,13 @@ public class ReadOutLoudManager { public static ReadOutLoudManager Instance = new ReadOutLoudManager(); + // TODO + // + // Warning CA1001 Implement IDisposable on 'ReadOutLoudManager' because it creates members + // of the following IDisposable types: 'SpeechSynthesizer'. + // If 'ReadOutLoudManager' has previously shipped, adding new members that implement IDisposable + // to this type is considered a breaking change to existing consumers. + object read_out_loud_lock = new object(); SpeechSynthesizer speech_synthesizer; Prompt current_prompt; diff --git a/Qiqqa/Common/TagManagement/TagEditorControl.xaml.cs b/Qiqqa/Common/TagManagement/TagEditorControl.xaml.cs index f166a196f..4eeb38017 100644 --- a/Qiqqa/Common/TagManagement/TagEditorControl.xaml.cs +++ b/Qiqqa/Common/TagManagement/TagEditorControl.xaml.cs @@ -17,6 +17,13 @@ public partial class TagEditorControl : UserControl internal Feature TagFeature_Add { get; set; } internal Feature TagFeature_Remove { get; set; } + // TODO + // + // Warning CA1001 Implement IDisposable on 'TagEditorControl' because it creates members + // of the following IDisposable types: 'WeakDependencyPropertyChangeNotifier'. + // If 'TagEditorControl' has previously shipped, adding new members that implement IDisposable + // to this type is considered a breaking change to existing consumers. + WeakDependencyPropertyChangeNotifier wdpcn; public TagEditorControl() diff --git a/Qiqqa/DocumentConversionStuff/DocumentConversion.cs b/Qiqqa/DocumentConversionStuff/DocumentConversion.cs index ce03c2630..6d198fb63 100644 --- a/Qiqqa/DocumentConversionStuff/DocumentConversion.cs +++ b/Qiqqa/DocumentConversionStuff/DocumentConversion.cs @@ -42,12 +42,16 @@ public static bool Convert(string filename, string pdf_filename) private static bool ConvertorDOC(string filename, string pdf_filename) { - WordDocument word_document = new WordDocument(filename); - DocToPDFConverter converter = new DocToPDFConverter(); - PdfDocument pdf_document = converter.ConvertToPDF(word_document); + using (WordDocument word_document = new WordDocument(filename)) + { + using (DocToPDFConverter converter = new DocToPDFConverter()) + { + PdfDocument pdf_document = converter.ConvertToPDF(word_document); - pdf_document.Save(pdf_filename); - pdf_document.Close(true); + pdf_document.Save(pdf_filename); + pdf_document.Close(true); + } + } return true; } diff --git a/Qiqqa/DocumentConversionStuff/DocumentConversionControl.xaml.cs b/Qiqqa/DocumentConversionStuff/DocumentConversionControl.xaml.cs index e8ddf0fe3..b8f10174d 100644 --- a/Qiqqa/DocumentConversionStuff/DocumentConversionControl.xaml.cs +++ b/Qiqqa/DocumentConversionStuff/DocumentConversionControl.xaml.cs @@ -70,7 +70,6 @@ private void DoConvert(string[] filenames) PDFDocument pdf_document = WebLibraryManager.Instance.Library_Guest.AddNewDocumentToLibrary_SYNCHRONOUS(pdf_filename, filename, filename, null, null, null, true, false); PDFReadingControl pdf_reading_control = MainWindowServiceDispatcher.Instance.OpenDocument(pdf_document); pdf_reading_control.EnableGuestMoveNotification(); - }), DispatcherPriority.Background); } diff --git a/Qiqqa/DocumentLibrary/BundleLibrary/BundleLibraryCreation/LibraryBundleCreationControl.xaml.cs b/Qiqqa/DocumentLibrary/BundleLibrary/BundleLibraryCreation/LibraryBundleCreationControl.xaml.cs index 91979de8b..a87b9a27f 100644 --- a/Qiqqa/DocumentLibrary/BundleLibrary/BundleLibraryCreation/LibraryBundleCreationControl.xaml.cs +++ b/Qiqqa/DocumentLibrary/BundleLibrary/BundleLibraryCreation/LibraryBundleCreationControl.xaml.cs @@ -50,16 +50,18 @@ public LibraryBundleCreationControl() void CmdCreateBundle_Click(object sender, RoutedEventArgs e) { - FolderBrowserDialog dialog = new FolderBrowserDialog(); - dialog.Description = "Please select the folder into which the two Library Bundle files should be placed."; - DialogResult result = dialog.ShowDialog(); - if (result == DialogResult.OK) + using (FolderBrowserDialog dialog = new FolderBrowserDialog()) { - CreateBundle(dialog.SelectedPath.ToString()); - } - else - { - MessageBoxes.Warn("Your Library Bundle creation has been cancelled."); + dialog.Description = "Please select the folder into which the two Library Bundle files should be placed."; + DialogResult result = dialog.ShowDialog(); + if (result == DialogResult.OK) + { + CreateBundle(dialog.SelectedPath.ToString()); + } + else + { + MessageBoxes.Warn("Your Library Bundle creation has been cancelled."); + } } } diff --git a/Qiqqa/DocumentLibrary/DocumentLibraryIndex/LibraryIndex.cs b/Qiqqa/DocumentLibrary/DocumentLibraryIndex/LibraryIndex.cs index e65de2ffd..d00f7f809 100644 --- a/Qiqqa/DocumentLibrary/DocumentLibraryIndex/LibraryIndex.cs +++ b/Qiqqa/DocumentLibrary/DocumentLibraryIndex/LibraryIndex.cs @@ -29,6 +29,7 @@ public class LibraryIndex : IDisposable DateTime time_of_last_library_scan = DateTime.MinValue; Dictionary pdf_documents_in_library; + private object pdf_documents_in_library_lock = new object(); public LibraryIndex(Library library) { @@ -40,21 +41,30 @@ public LibraryIndex(Library library) if (File.Exists(Filename_DocumentProgressList)) { Logging.Info("+Loading historical progress file: {0}", Filename_DocumentProgressList); - pdf_documents_in_library = (Dictionary)SerializeFile.LoadSafely(Filename_DocumentProgressList); + lock (pdf_documents_in_library_lock) + { + pdf_documents_in_library = (Dictionary)SerializeFile.LoadSafely(Filename_DocumentProgressList); + } Logging.Info("-Loaded historical progress file: {0}", Filename_DocumentProgressList); } } catch (Exception ex) { Logging.Error(ex, "FAILED to load historical progress file \"{0}\". Will start indexing afresh.", Filename_DocumentProgressList); - pdf_documents_in_library = null; + lock (pdf_documents_in_library_lock) + { + pdf_documents_in_library = null; + } } // If there was no historical progress file, start afresh - if (null == pdf_documents_in_library) + lock (pdf_documents_in_library_lock) { - Logging.Warn("Cound not find any indexing progress, so starting from scratch."); - pdf_documents_in_library = new Dictionary(); + if (null == pdf_documents_in_library) + { + Logging.Warn("Cound not find any indexing progress, so starting from scratch."); + pdf_documents_in_library = new Dictionary(); + } } word_index_manager = new LuceneIndex(library.LIBRARY_INDEX_BASE_PATH); @@ -90,7 +100,10 @@ private void Dispose(bool disposing) this.word_index_manager = null; this.library = null; - this.pdf_documents_in_library = null; + lock (pdf_documents_in_library_lock) + { + this.pdf_documents_in_library = null; + } // Get rid of unmanaged resources } @@ -112,7 +125,7 @@ public void IncrementalBuildIndex(Daemon daemon) { Logging.Info("+Writing the index master list"); word_index_manager.WriteMasterList(); - lock (pdf_documents_in_library) + lock (pdf_documents_in_library_lock) { SerializeFile.SaveSafely(Filename_DocumentProgressList, pdf_documents_in_library); } @@ -127,7 +140,7 @@ public void ReIndexDocument(PDFDocument pdf_document) { try { - lock (pdf_documents_in_library) + lock (pdf_documents_in_library_lock) { pdf_documents_in_library.Remove(pdf_document.Fingerprint); } @@ -146,7 +159,7 @@ public void UpdateStatus() int pages_so_far = 0; int pages_to_go = 0; - lock (pdf_documents_in_library) + lock (pdf_documents_in_library_lock) { foreach (PDFDocumentInLibrary pdf_document_in_library in pdf_documents_in_library.Values) { @@ -205,7 +218,7 @@ private void RescanLibrary() int total_new_to_be_indexed = 0; - lock (pdf_documents_in_library) + lock (pdf_documents_in_library_lock) { foreach (PDFDocument pdf_document in pdf_documents) { @@ -236,7 +249,7 @@ private void RescanLibrary() } catch (Exception ex) { - Logging.Error(ex, "There was a problem with a document while rescanning the library for indexing"); + Logging.Error(ex, "There was a problem with a document while rescanning the library for indexing. Document fingerprint: {0}", pdf_document.Fingerprint); } } } @@ -263,7 +276,7 @@ private bool IncrementalBuildNextDocuments(Daemon daemon) return false; } - lock (pdf_documents_in_library) + lock (pdf_documents_in_library_lock) { // We will only attempt to process documents that have not been looked at for a while - what is that time DateTime most_recent_eligible_time_for_processing = DateTime.UtcNow.Subtract(TimeSpan.FromSeconds(DOCUMENT_INDEX_RETRY_PERIOD_SECONDS)); @@ -414,7 +427,7 @@ int NumberOfIndexedPDFDocuments { get { - lock (pdf_documents_in_library) + lock (pdf_documents_in_library_lock) { return pdf_documents_in_library.Count; } diff --git a/Qiqqa/DocumentLibrary/FolderWatching/FolderWatcher.cs b/Qiqqa/DocumentLibrary/FolderWatching/FolderWatcher.cs index 2d1182368..bca6257c8 100644 --- a/Qiqqa/DocumentLibrary/FolderWatching/FolderWatcher.cs +++ b/Qiqqa/DocumentLibrary/FolderWatching/FolderWatcher.cs @@ -13,7 +13,16 @@ public class FolderWatcher FolderWatcherManager folder_watcher_manager; Library library; HashSet tags; + + // TODO + // + // Warning CA1001 Implement IDisposable on 'FolderWatcher' because it creates members + // of the following IDisposable types: 'FileSystemWatcher'. + // If 'FolderWatcher' has previously shipped, adding new members that implement IDisposable + // to this type is considered a breaking change to existing consumers. + FileSystemWatcher file_system_watcher; + string previous_folder_to_watch; string folder_to_watch; bool folder_contents_has_changed; diff --git a/Qiqqa/DocumentLibrary/FolderWatching/FolderWatcherChooser.xaml.cs b/Qiqqa/DocumentLibrary/FolderWatching/FolderWatcherChooser.xaml.cs index 4f052b6c6..b3f829721 100644 --- a/Qiqqa/DocumentLibrary/FolderWatching/FolderWatcherChooser.xaml.cs +++ b/Qiqqa/DocumentLibrary/FolderWatching/FolderWatcherChooser.xaml.cs @@ -51,24 +51,25 @@ void CmdResetHistory_Click(object sender, RoutedEventArgs e) } void CmdAddFolder_Click(object sender, RoutedEventArgs e) - { - FolderBrowserDialog dlg = new FolderBrowserDialog + { + using (FolderBrowserDialog dlg = new FolderBrowserDialog { - Description = "Please select the folder you want to watch for new PDFs.", + Description = "Please select the folder you want to watch for new PDFs.", ShowNewFolderButton = true - }; - - if (System.Windows.Forms.DialogResult.OK == dlg.ShowDialog()) + }) { - Logging.Info("The user starting watching folder {0}", dlg.SelectedPath); - - if (string.IsNullOrEmpty(TxtFolders.Text)) + if (System.Windows.Forms.DialogResult.OK == dlg.ShowDialog()) { - TxtFolders.Text = dlg.SelectedPath; - } - else - { - TxtFolders.Text += "\r\n" + dlg.SelectedPath; + Logging.Info("The user starting watching folder {0}", dlg.SelectedPath); + + if (string.IsNullOrEmpty(TxtFolders.Text)) + { + TxtFolders.Text = dlg.SelectedPath; + } + else + { + TxtFolders.Text += "\r\n" + dlg.SelectedPath; + } } } } diff --git a/Qiqqa/DocumentLibrary/Import/Auto/EndnoteImporter.cs b/Qiqqa/DocumentLibrary/Import/Auto/EndnoteImporter.cs index 4ec5b8ae8..0b7283259 100644 --- a/Qiqqa/DocumentLibrary/Import/Auto/EndnoteImporter.cs +++ b/Qiqqa/DocumentLibrary/Import/Auto/EndnoteImporter.cs @@ -113,7 +113,6 @@ internal static EndnoteDatabaseDetails DetectEndnoteDatabaseDetails() ++edd.pdfs_found; } } - catch (Exception ex) { Logging.Warn(ex, "Problem processing Endnote record."); diff --git a/Qiqqa/DocumentLibrary/Import/Manual/ImportFromFolder.xaml.cs b/Qiqqa/DocumentLibrary/Import/Manual/ImportFromFolder.xaml.cs index 975844f98..780b96cf7 100644 --- a/Qiqqa/DocumentLibrary/Import/Manual/ImportFromFolder.xaml.cs +++ b/Qiqqa/DocumentLibrary/Import/Manual/ImportFromFolder.xaml.cs @@ -110,24 +110,25 @@ public ImportFromFolder(Library library, string folder_path) private void FolderLocationButton_Click(object sender, RoutedEventArgs e) { - FolderBrowserDialog dlg = new FolderBrowserDialog + using (FolderBrowserDialog dlg = new FolderBrowserDialog { Description = "Please select a folder. All the PDFs in the folder will be added to your document library.", ShowNewFolderButton = false - }; - string default_folder = bindable.Underlying.DefaultSelectedPath; - if (default_folder != null) + }) { - dlg.SelectedPath = default_folder; - } + string default_folder = bindable.Underlying.DefaultSelectedPath; + if (default_folder != null) + { + dlg.SelectedPath = default_folder; + } - if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) - { - bindable.Underlying.SelectedPath = dlg.SelectedPath; - bindable.NotifyPropertyChanged(() => bindable.Underlying.SelectedPath); + if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + bindable.Underlying.SelectedPath = dlg.SelectedPath; + bindable.NotifyPropertyChanged(() => bindable.Underlying.SelectedPath); + } + Logging.Debug("User selected import folder path: " + bindable.Underlying.SelectedPath); } - Logging.Debug("User selected import folder path: " + bindable.Underlying.SelectedPath); - } private void BtnCancel_OnClick(object sender, RoutedEventArgs e) diff --git a/Qiqqa/DocumentLibrary/Import/Manual/ImportFromThirdParty.xaml.cs b/Qiqqa/DocumentLibrary/Import/Manual/ImportFromThirdParty.xaml.cs index 2c46fadcb..c42b8d964 100644 --- a/Qiqqa/DocumentLibrary/Import/Manual/ImportFromThirdParty.xaml.cs +++ b/Qiqqa/DocumentLibrary/Import/Manual/ImportFromThirdParty.xaml.cs @@ -459,12 +459,17 @@ private static string GetFileNameFromDialog(string title, string defaultExt, str private static string GetFolderNameFromDialog(string title, string defaultFolder) { - FolderBrowserDialog ofd = new FolderBrowserDialog(); - ofd.Description = title; - ofd.SelectedPath = defaultFolder; + using (FolderBrowserDialog ofd = new FolderBrowserDialog()) + { + ofd.Description = title; + ofd.SelectedPath = defaultFolder; - if (System.Windows.Forms.DialogResult.OK != ofd.ShowDialog()) return null; - return ofd.SelectedPath; + if (System.Windows.Forms.DialogResult.OK != ofd.ShowDialog()) + { + return null; + } + return ofd.SelectedPath; + } } diff --git a/Qiqqa/DocumentLibrary/ImportingIntoLibrary.cs b/Qiqqa/DocumentLibrary/ImportingIntoLibrary.cs index 2cd308cc4..7b90a941e 100644 --- a/Qiqqa/DocumentLibrary/ImportingIntoLibrary.cs +++ b/Qiqqa/DocumentLibrary/ImportingIntoLibrary.cs @@ -281,7 +281,7 @@ public static void AddNewDocumentToLibraryFromInternet_SYNCHRONOUS(Library libra { int total_bytes = StreamToFile.CopyStreamToStream(response_stream, fs); Logging.Info("Saved {0} bytes to {1}", total_bytes, filename); - fs.Close(); + //fs.Close(); -- autoclosed by `using` statement } library.AddNewDocumentToLibrary_SYNCHRONOUS(filename, original_filename, download_url, null, null, null, false, false); @@ -291,9 +291,11 @@ public static void AddNewDocumentToLibraryFromInternet_SYNCHRONOUS(Library libra { if (content_type.ToLower(CultureInfo.CurrentCulture).EndsWith("html")) { - StreamReader sr = new StreamReader(response_stream); - string html = sr.ReadToEnd(); - Logging.Warn("Got this HTML instead of a PDF: {0}", html); + using (StreamReader sr = new StreamReader(response_stream)) + { + string html = sr.ReadToEnd(); + Logging.Warn("Got this HTML instead of a PDF: {0}", html); + } } MessageBoxes.Info("The document library supports only PDF files at the moment. You are trying to download something of type {0}.", content_type); diff --git a/Qiqqa/DocumentLibrary/IntranetLibraryStuff/IntranetLibraryChooserControl.xaml.cs b/Qiqqa/DocumentLibrary/IntranetLibraryStuff/IntranetLibraryChooserControl.xaml.cs index 6ea12e27b..0c0a20b1e 100644 --- a/Qiqqa/DocumentLibrary/IntranetLibraryStuff/IntranetLibraryChooserControl.xaml.cs +++ b/Qiqqa/DocumentLibrary/IntranetLibraryStuff/IntranetLibraryChooserControl.xaml.cs @@ -188,16 +188,17 @@ private void EnsureWarningFilesArePresent_TOUCH(string base_path, string filenam void ObjButtonFolderChoose_Click(object sender, RoutedEventArgs e) { - FolderBrowserDialog dlg = new FolderBrowserDialog + using (FolderBrowserDialog dlg = new FolderBrowserDialog { Description = "Please select the shared directory for your Intranet Library.", SelectedPath = TxtPath.Text, ShowNewFolderButton = true - }; - - if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) + }) { - TxtPath.Text = dlg.SelectedPath; + if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + TxtPath.Text = dlg.SelectedPath; + } } } } diff --git a/Qiqqa/DocumentLibrary/LibraryCatalog/LibraryCatalogOverviewControl.xaml.cs b/Qiqqa/DocumentLibrary/LibraryCatalog/LibraryCatalogOverviewControl.xaml.cs index 064484eb7..b609036c2 100644 --- a/Qiqqa/DocumentLibrary/LibraryCatalog/LibraryCatalogOverviewControl.xaml.cs +++ b/Qiqqa/DocumentLibrary/LibraryCatalog/LibraryCatalogOverviewControl.xaml.cs @@ -288,7 +288,6 @@ void HyperlinkPreview_ToolTipOpening(object sender, ToolTipEventArgs e) ButtonOpen.ToolTip = library_index_hover_popup; } } - catch (Exception ex) { Logging.Error(ex, "Exception while displaying document preview popup"); diff --git a/Qiqqa/DocumentLibrary/LibraryControl.xaml.cs b/Qiqqa/DocumentLibrary/LibraryControl.xaml.cs index 8badf451e..328aff1da 100644 --- a/Qiqqa/DocumentLibrary/LibraryControl.xaml.cs +++ b/Qiqqa/DocumentLibrary/LibraryControl.xaml.cs @@ -491,18 +491,19 @@ void ButtonWatchFolder_Click(object sender, RoutedEventArgs e) void ButtonAddDocuments_Click(object sender, RoutedEventArgs e) { - OpenFileDialog dlg = new OpenFileDialog + using (OpenFileDialog dlg = new OpenFileDialog { CheckFileExists = true, CheckPathExists = true, Filter = "PDF Files|*.pdf", Multiselect = true, Title = "Select the PDF documents you wish to add to your document library" - }; - - if (dlg.ShowDialog() == DialogResult.OK) + }) { - ImportingIntoLibrary.AddNewPDFDocumentsToLibrary_ASYNCHRONOUS(library, false, false, dlg.FileNames); + if (dlg.ShowDialog() == DialogResult.OK) + { + ImportingIntoLibrary.AddNewPDFDocumentsToLibrary_ASYNCHRONOUS(library, false, false, dlg.FileNames); + } } } diff --git a/Qiqqa/DocumentLibrary/LibraryIndexHoverPopup.xaml.cs b/Qiqqa/DocumentLibrary/LibraryIndexHoverPopup.xaml.cs index 6eae0ede8..4344746b7 100644 --- a/Qiqqa/DocumentLibrary/LibraryIndexHoverPopup.xaml.cs +++ b/Qiqqa/DocumentLibrary/LibraryIndexHoverPopup.xaml.cs @@ -105,14 +105,17 @@ private void DisplayThumbnail() { double IMAGE_PERCENTAGE = 0.5; - Bitmap image = (Bitmap)Image.FromStream(new MemoryStream(pdf_document.PDFRenderer.GetPageByHeightAsImage(this.page, ImageThumbnail.Height / IMAGE_PERCENTAGE))); - PDFOverlayRenderer.RenderAnnotations(image, pdf_document, page, specific_pdf_annotation); - PDFOverlayRenderer.RenderHighlights(image, pdf_document, page); - PDFOverlayRenderer.RenderInks(image, pdf_document, page); - - image = image.Clone(new RectangleF { Width = image.Width, Height = (int)Math.Round(image.Height * IMAGE_PERCENTAGE) }, image.PixelFormat); - BitmapSource image_page = BitmapImageTools.CreateBitmapSourceFromImage(image); - ImageThumbnail.Source = image_page; + using (MemoryStream ms = new MemoryStream(pdf_document.PDFRenderer.GetPageByHeightAsImage(this.page, ImageThumbnail.Height / IMAGE_PERCENTAGE))) + { + Bitmap image = (Bitmap)Image.FromStream(ms); + PDFOverlayRenderer.RenderAnnotations(image, pdf_document, page, specific_pdf_annotation); + PDFOverlayRenderer.RenderHighlights(image, pdf_document, page); + PDFOverlayRenderer.RenderInks(image, pdf_document, page); + + image = image.Clone(new RectangleF { Width = image.Width, Height = (int)Math.Round(image.Height * IMAGE_PERCENTAGE) }, image.PixelFormat); + BitmapSource image_page = BitmapImageTools.CreateBitmapSourceFromImage(image); + ImageThumbnail.Source = image_page; + } } else { diff --git a/Qiqqa/DocumentLibrary/WebLibraryStuff/WebLibraryDetailControl.xaml.cs b/Qiqqa/DocumentLibrary/WebLibraryStuff/WebLibraryDetailControl.xaml.cs index d184327a5..6f60d0c43 100644 --- a/Qiqqa/DocumentLibrary/WebLibraryStuff/WebLibraryDetailControl.xaml.cs +++ b/Qiqqa/DocumentLibrary/WebLibraryStuff/WebLibraryDetailControl.xaml.cs @@ -588,89 +588,95 @@ private void UpdateLibraryStatistics_Stats_Background_CoverFlow() Dispatcher.Invoke(new Action(() => UpdateLibraryStatistics_Stats_Background_GUI_AddAllPlaceHolders(ddwm.ddws))); // Now render each document - Font font = new Font("Times New Roman", 11.0f); - StringFormat string_format = new StringFormat + using (Font font = new Font("Times New Roman", 11.0f)) { - Alignment = StringAlignment.Center, - LineAlignment = StringAlignment.Center - }; - var color_matrix = new ColorMatrix(); - color_matrix.Matrix33 = 0.9f; - var image_attributes = new ImageAttributes(); - image_attributes.SetColorMatrix(color_matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); - - foreach (DocumentDisplayWork ddw in ddwm.ddws) - { - try + using (StringFormat string_format = new StringFormat { - Bitmap page_bitmap = (Bitmap)System.Drawing.Image.FromStream(new MemoryStream(ddw.pdf_document.PDFRenderer.GetPageByHeightAsImage(1, PREVIEW_IMAGE_HEIGHT / PREVIEW_IMAGE_PERCENTAGE))); - page_bitmap = page_bitmap.Clone(new RectangleF { Width = page_bitmap.Width, Height = (int)Math.Round(page_bitmap.Height * PREVIEW_IMAGE_PERCENTAGE) }, page_bitmap.PixelFormat); - - using (Graphics g = Graphics.FromImage(page_bitmap)) - { - int CENTER = 60; - int RADIUS = 60; + Alignment = StringAlignment.Center, + LineAlignment = StringAlignment.Center + }) + { + var color_matrix = new ColorMatrix(); + color_matrix.Matrix33 = 0.9f; + using (var image_attributes = new ImageAttributes()) + { + image_attributes.SetColorMatrix(color_matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); + foreach (DocumentDisplayWork ddw in ddwm.ddws) { - BitmapImage starburst_bi = null; - switch (ddw.starburst_color) + try { - case DocumentDisplayWork.StarburstColor.Blue: - starburst_bi = Icons.GetAppIcon(Icons.PageCornerBlue); - break; - case DocumentDisplayWork.StarburstColor.Green: - starburst_bi = Icons.GetAppIcon(Icons.PageCornerGreen); - break; - case DocumentDisplayWork.StarburstColor.Pink: - starburst_bi = Icons.GetAppIcon(Icons.PageCornerPink); - break; - default: - starburst_bi = Icons.GetAppIcon(Icons.PageCornerOrange); - break; - } - - Bitmap starburst_image = BitmapImageTools.ConvertBitmapSourceToBitmap(starburst_bi); - g.SmoothingMode = SmoothingMode.AntiAlias; - g.DrawImage( - starburst_image, - new Rectangle(CENTER - RADIUS, CENTER - RADIUS, 2 * RADIUS, 2 * RADIUS), - 0, - 0, - starburst_image.Width, - starburst_image.Height, - GraphicsUnit.Pixel, - image_attributes - ); - - } + using (MemoryStream ms = new MemoryStream(ddw.pdf_document.PDFRenderer.GetPageByHeightAsImage(1, PREVIEW_IMAGE_HEIGHT / PREVIEW_IMAGE_PERCENTAGE))) + { + Bitmap page_bitmap = (Bitmap)System.Drawing.Image.FromStream(ms); + page_bitmap = page_bitmap.Clone(new RectangleF { Width = page_bitmap.Width, Height = (int)Math.Round(page_bitmap.Height * PREVIEW_IMAGE_PERCENTAGE) }, page_bitmap.PixelFormat); + + using (Graphics g = Graphics.FromImage(page_bitmap)) + { + int CENTER = 60; + int RADIUS = 60; + + { + BitmapImage starburst_bi = null; + switch (ddw.starburst_color) + { + case DocumentDisplayWork.StarburstColor.Blue: + starburst_bi = Icons.GetAppIcon(Icons.PageCornerBlue); + break; + case DocumentDisplayWork.StarburstColor.Green: + starburst_bi = Icons.GetAppIcon(Icons.PageCornerGreen); + break; + case DocumentDisplayWork.StarburstColor.Pink: + starburst_bi = Icons.GetAppIcon(Icons.PageCornerPink); + break; + default: + starburst_bi = Icons.GetAppIcon(Icons.PageCornerOrange); + break; + } + + Bitmap starburst_image = BitmapImageTools.ConvertBitmapSourceToBitmap(starburst_bi); + g.SmoothingMode = SmoothingMode.AntiAlias; + g.DrawImage( + starburst_image, + new Rectangle(CENTER - RADIUS, CENTER - RADIUS, 2 * RADIUS, 2 * RADIUS), + 0, + 0, + starburst_image.Width, + starburst_image.Height, + GraphicsUnit.Pixel, + image_attributes + ); + } + + using (Matrix mat = new Matrix()) + { + mat.RotateAt(-50, new PointF(CENTER / 2, CENTER / 2)); + g.Transform = mat; + + string wrapped_caption = ddw.starburst_caption; + wrapped_caption = wrapped_caption.ToLower(); + wrapped_caption = Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(wrapped_caption); + wrapped_caption = wrapped_caption.Replace(" ", "\n"); + g.DrawString(wrapped_caption, font, Brushes.Black, new PointF(CENTER / 2, CENTER / 2), string_format); + } + } + + BitmapSource page_bitmap_source = BitmapImageTools.CreateBitmapSourceFromImage(page_bitmap); + + ddw.page_bitmap_source = page_bitmap_source; + } - { - Matrix mat = new Matrix(); - mat.RotateAt(-50, new PointF(CENTER / 2, CENTER / 2)); - g.Transform = mat; - - string wrapped_caption = ddw.starburst_caption; - wrapped_caption = wrapped_caption.ToLower(); - wrapped_caption = Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(wrapped_caption); - wrapped_caption = wrapped_caption.Replace(" ", "\n"); - g.DrawString(wrapped_caption, font, Brushes.Black, new PointF(CENTER / 2, CENTER / 2), string_format); + Dispatcher.Invoke(new Action(() => UpdateLibraryStatistics_Stats_Background_GUI_FillPlaceHolder(ddw))); + } + catch (Exception ex) + { + Logging.Warn(ex, "There was a problem loading a preview image for document {0}", ddw.pdf_document.Fingerprint); + } } } - - BitmapSource page_bitmap_source = BitmapImageTools.CreateBitmapSourceFromImage(page_bitmap); - - ddw.page_bitmap_source = page_bitmap_source; - - Dispatcher.Invoke(new Action(() => UpdateLibraryStatistics_Stats_Background_GUI_FillPlaceHolder(ddw))); - } - - catch (Exception ex) - { - Logging.Warn(ex, "There was a problem loading a preview image for document {0}", ddw.pdf_document.Fingerprint); } } - if (0 == ddwm.ddws.Count) { Dispatcher.BeginInvoke(new Action(() => @@ -956,20 +962,22 @@ internal void CustomiseIcon() private void GenericCustomiseChooser(string title, string filename) { - var dialog = new OpenFileDialog(); - dialog.Filter = "Image files|*.jpeg;*.jpg;*.png;*.gif;*.bmp" + "|" + "All files|*.*"; - dialog.CheckFileExists = true; - dialog.Multiselect = false; - dialog.Title = title; - if (DialogResult.OK == dialog.ShowDialog()) - { - // Copy the new file into place - File.Delete(filename); - File.Copy(dialog.FileName, filename); - } - else + using (var dialog = new OpenFileDialog()) { - File.Delete(filename); + dialog.Filter = "Image files|*.jpeg;*.jpg;*.png;*.gif;*.bmp" + "|" + "All files|*.*"; + dialog.CheckFileExists = true; + dialog.Multiselect = false; + dialog.Title = title; + if (DialogResult.OK == dialog.ShowDialog()) + { + // Copy the new file into place + File.Delete(filename); + File.Copy(dialog.FileName, filename); + } + else + { + File.Delete(filename); + } } UpdateLibraryStatistics(); diff --git a/Qiqqa/Documents/PDF/PDFAnnotationToImageRenderer.cs b/Qiqqa/Documents/PDF/PDFAnnotationToImageRenderer.cs index e947f208b..1b7579f45 100644 --- a/Qiqqa/Documents/PDF/PDFAnnotationToImageRenderer.cs +++ b/Qiqqa/Documents/PDF/PDFAnnotationToImageRenderer.cs @@ -10,13 +10,16 @@ class PDFAnnotationToImageRenderer { public static Image RenderAnnotation(PDFDocument pdf_document, PDFAnnotation pdf_annotation, float dpi) { - Image image = Image.FromStream(new MemoryStream(pdf_document.PDFRenderer.GetPageByDPIAsImage(pdf_annotation.Page, dpi))); - PDFOverlayRenderer.RenderHighlights(image, pdf_document, pdf_annotation.Page); - PDFOverlayRenderer.RenderInks(image, pdf_document, pdf_annotation.Page); + using (MemoryStream ms = new MemoryStream(pdf_document.PDFRenderer.GetPageByDPIAsImage(pdf_annotation.Page, dpi))) + { + Image image = Image.FromStream(ms); + PDFOverlayRenderer.RenderHighlights(image, pdf_document, pdf_annotation.Page); + PDFOverlayRenderer.RenderInks(image, pdf_document, pdf_annotation.Page); - // We rescale in the Drawing.Bitmap world because the WPF world uses so much memory - Image cropped_image = BitmapImageTools.CropImageRegion(image, pdf_annotation.Left, pdf_annotation.Top, pdf_annotation.Width, pdf_annotation.Height); - return cropped_image; + // We rescale in the Drawing.Bitmap world because the WPF world uses so much memory + Image cropped_image = BitmapImageTools.CropImageRegion(image, pdf_annotation.Left, pdf_annotation.Top, pdf_annotation.Width, pdf_annotation.Height); + return cropped_image; + } } } } diff --git a/Qiqqa/Documents/PDF/PDFControls/MetadataControls/TweetControl.xaml.cs b/Qiqqa/Documents/PDF/PDFControls/MetadataControls/TweetControl.xaml.cs index eb786a82a..ff2642089 100644 --- a/Qiqqa/Documents/PDF/PDFControls/MetadataControls/TweetControl.xaml.cs +++ b/Qiqqa/Documents/PDF/PDFControls/MetadataControls/TweetControl.xaml.cs @@ -142,32 +142,33 @@ private void CreatePaperBibTeXTweet() void GenerateRtfCitationSnippet_OnBibliographyReady(CSLProcessorOutputConsumer ip) { if (ip.success) - { - System.Windows.Forms.RichTextBox rich_text_box = new System.Windows.Forms.RichTextBox(); - rich_text_box.Rtf = ip.GetRtf(); - string text = rich_text_box.Text; - - text = text.Trim(); - text = text.Replace(";", ","); - if (text.StartsWith("1.\t")) text = text.Substring(3); - if (text.StartsWith("1 \t")) text = text.Substring(3); - if (text.StartsWith("1\t")) text = text.Substring(2); - - if (text.Length > 32) + { + using (System.Windows.Forms.RichTextBox rich_text_box = new System.Windows.Forms.RichTextBox()) { - string POSTAMBLE_QIQQA_TWITTER = " @Qiqqa"; - string POSTAMBLE_QIQQA_URL = " http://www.qiqqa.com"; - int POSTAMBLE_QIQQA_URL_SHORTENED_LENGTH = 22; - string PREAMBLE_CHECK_OUT = "Check out "; - - if (text.Length < 140 - POSTAMBLE_QIQQA_TWITTER.Length) text = text + POSTAMBLE_QIQQA_TWITTER; - if (text.Length < 140 - POSTAMBLE_QIQQA_URL_SHORTENED_LENGTH) text = text + POSTAMBLE_QIQQA_URL; - if (text.Length < 140 - PREAMBLE_CHECK_OUT.Length) text = PREAMBLE_CHECK_OUT + text; - - TxtTweet.Text = text; + rich_text_box.Rtf = ip.GetRtf(); + string text = rich_text_box.Text; + + text = text.Trim(); + text = text.Replace(";", ","); + if (text.StartsWith("1.\t")) text = text.Substring(3); + if (text.StartsWith("1 \t")) text = text.Substring(3); + if (text.StartsWith("1\t")) text = text.Substring(2); + + if (text.Length > 32) + { + string POSTAMBLE_QIQQA_TWITTER = " @Qiqqa"; + string POSTAMBLE_QIQQA_URL = " http://www.qiqqa.com"; + int POSTAMBLE_QIQQA_URL_SHORTENED_LENGTH = 22; + string PREAMBLE_CHECK_OUT = "Check out "; + + if (text.Length < 140 - POSTAMBLE_QIQQA_TWITTER.Length) text = text + POSTAMBLE_QIQQA_TWITTER; + if (text.Length < 140 - POSTAMBLE_QIQQA_URL_SHORTENED_LENGTH) text = text + POSTAMBLE_QIQQA_URL; + if (text.Length < 140 - PREAMBLE_CHECK_OUT.Length) text = PREAMBLE_CHECK_OUT + text; + + TxtTweet.Text = text; + } } } - else { Logging.Warn("There was a problem generating a citation snippet to tweet, so ignoring..."); diff --git a/Qiqqa/Documents/PDF/PDFControls/Page/Camera/PDFCameraLayer.xaml.cs b/Qiqqa/Documents/PDF/PDFControls/Page/Camera/PDFCameraLayer.xaml.cs index 7745ed483..a097a8188 100644 --- a/Qiqqa/Documents/PDF/PDFControls/Page/Camera/PDFCameraLayer.xaml.cs +++ b/Qiqqa/Documents/PDF/PDFControls/Page/Camera/PDFCameraLayer.xaml.cs @@ -87,27 +87,30 @@ private CroppedBitmap GetSnappedImage(Point mouse_up_point, Point mouse_down_poi { CroppedBitmap cropped_image_page = null; - PngBitmapDecoder decoder = new PngBitmapDecoder(new MemoryStream(pdf_renderer_control_stats.pdf_document.PDFRenderer.GetPageByDPIAsImage(page, 150)), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); - BitmapSource image_page = decoder.Frames[0]; - if (null != image_page) + using (MemoryStream ms = new MemoryStream(pdf_renderer_control_stats.pdf_document.PDFRenderer.GetPageByDPIAsImage(page, 150))) { - double left = Math.Min(mouse_up_point.X, mouse_down_point.X) * image_page.PixelWidth / this.ActualWidth; - double top = Math.Min(mouse_up_point.Y, mouse_down_point.Y) * image_page.PixelHeight / this.ActualHeight; - double width = Math.Abs(mouse_up_point.X - mouse_down_point.X) * image_page.PixelWidth / this.ActualWidth; - double height = Math.Abs(mouse_up_point.Y - mouse_down_point.Y) * image_page.PixelHeight / this.ActualHeight; + PngBitmapDecoder decoder = new PngBitmapDecoder(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); + BitmapSource image_page = decoder.Frames[0]; + if (null != image_page) + { + double left = Math.Min(mouse_up_point.X, mouse_down_point.X) * image_page.PixelWidth / this.ActualWidth; + double top = Math.Min(mouse_up_point.Y, mouse_down_point.Y) * image_page.PixelHeight / this.ActualHeight; + double width = Math.Abs(mouse_up_point.X - mouse_down_point.X) * image_page.PixelWidth / this.ActualWidth; + double height = Math.Abs(mouse_up_point.Y - mouse_down_point.Y) * image_page.PixelHeight / this.ActualHeight; - left = Math.Max(left, 0); - top = Math.Max(top, 0); - width = Math.Min(width, image_page.PixelWidth - left); - height = Math.Min(height, image_page.PixelHeight - top); + left = Math.Max(left, 0); + top = Math.Max(top, 0); + width = Math.Min(width, image_page.PixelWidth - left); + height = Math.Min(height, image_page.PixelHeight - top); - if (0 < width && 0 < height) - { - cropped_image_page = new CroppedBitmap(image_page, new Int32Rect((int)left, (int)top, (int)width, (int)height)); + if (0 < width && 0 < height) + { + cropped_image_page = new CroppedBitmap(image_page, new Int32Rect((int)left, (int)top, (int)width, (int)height)); + } } - } - return cropped_image_page; + return cropped_image_page; + } } internal override void Dispose() diff --git a/QiqqaOCR/OCREngine.cs b/QiqqaOCR/OCREngine.cs index ebfa64d72..f5b1407bd 100644 --- a/QiqqaOCR/OCREngine.cs +++ b/QiqqaOCR/OCREngine.cs @@ -157,101 +157,93 @@ public static WordList DoOCR(string pdf_filename, int page_number) { Logging.Info("+Rendering page"); SoraxPDFRenderer renderer = new SoraxPDFRenderer(pdf_filename, pdf_user_password, pdf_user_password); - Bitmap bitmap = (Bitmap)Image.FromStream(new MemoryStream(renderer.GetPageByDPIAsImage(page_number, 200))); - - Logging.Info("-Rendering page"); - - Logging.Info("Startup directory is {0}", Environment.CurrentDirectory); - Logging.Info("Language is '{0}'", language); - - Tesseract ocr = null; - - try + using (MemoryStream ms = new MemoryStream(renderer.GetPageByDPIAsImage(page_number, 200))) { - ocr = new Tesseract(); - ocr.Init(null, language, false); - - Logging.Info("+Doing OCR"); - - // Build a list of all the rectangles to process - PDFRegionLocator pdf_region_locator = new PDFRegionLocator(bitmap); - PDFRegionLocator.Region last_region = pdf_region_locator.regions[0]; - List rectangles = new List(); - foreach (PDFRegionLocator.Region region in pdf_region_locator.regions) - { - if (false) { } - else if (last_region.state == PDFRegionLocator.SegmentState.BLANKS) - { - // LHS - { - Rectangle rectangle = new Rectangle(0, last_region.y, bitmap.Width / 2, region.y - last_region.y); - rectangles.Add(rectangle); - } - // RHS - { - Rectangle rectangle = new Rectangle(bitmap.Width / 2, last_region.y, bitmap.Width / 2, region.y - last_region.y); - rectangles.Add(rectangle); - } - } - else if (last_region.state == PDFRegionLocator.SegmentState.PIXELS) - { - // Full column - { - Rectangle rectangle = new Rectangle(0, last_region.y, bitmap.Width, region.y - last_region.y); - rectangles.Add(rectangle); - } - } - - last_region = region; - } - - // DEBUG CODE: Draw in the region rectangles - //{ - // Graphics g = Graphics.FromImage(bitmap); - // foreach (Rectangle rectangle in rectangles) - // { - // g.DrawRectangle(Pens.Black, rectangle); - // } - - // bitmap.Save(@"C:\temp\aaaaaa.png", ImageFormat.Png); - //} - - // Do the OCR on each of the rectangles - WordList word_list = new WordList(); - foreach (Rectangle rectangle in rectangles) - { - if (0 == rectangle.Width || 0 == rectangle.Height) - { - Logging.Info("Skipping zero extent rectangle {0}", rectangle.ToString()); - continue; - } - - Logging.Info("Doing OCR for region {0}", rectangle.ToString()); - List result = ocr.DoOCR(bitmap, rectangle); - Logging.Info("Got {0} words", result.Count); - word_list.AddRange(ConvertToWordList(result, rectangle, bitmap)); - } - - Logging.Info("-Doing OCR"); - - - Logging.Info("Found {0} words", word_list.Count); - - //Logging.Info("+Reordering words for columns"); - //WordList word_list_ordered = ColumnWordOrderer.ReorderWords(word_list); - //Logging.Info("-Reordering words for columns"); - //word_list_ordered.WriteToFile(ocr_output_filename); - - return word_list; - } - finally - { - // Warning CA2000 call System.IDisposable.Dispose on object 'new MemoryStream(renderer.GetPageByDPIAsImage(page_number, 200F))' - // before all references to it are out of scope. - bitmap.Dispose(); - // Warning CA2000 call System.IDisposable.Dispose on object 'ocr' before all references to it are out of scope. - ocr?.Dispose(); - } + Bitmap bitmap = (Bitmap)Image.FromStream(ms); + + Logging.Info("-Rendering page"); + + Logging.Info("Startup directory is {0}", Environment.CurrentDirectory); + Logging.Info("Language is '{0}'", language); + + using (Tesseract ocr = new Tesseract()) + { + ocr.Init(null, language, false); + + Logging.Info("+Doing OCR"); + + // Build a list of all the rectangles to process + PDFRegionLocator pdf_region_locator = new PDFRegionLocator(bitmap); + PDFRegionLocator.Region last_region = pdf_region_locator.regions[0]; + List rectangles = new List(); + foreach (PDFRegionLocator.Region region in pdf_region_locator.regions) + { + if (false) { } + else if (last_region.state == PDFRegionLocator.SegmentState.BLANKS) + { + // LHS + { + Rectangle rectangle = new Rectangle(0, last_region.y, bitmap.Width / 2, region.y - last_region.y); + rectangles.Add(rectangle); + } + // RHS + { + Rectangle rectangle = new Rectangle(bitmap.Width / 2, last_region.y, bitmap.Width / 2, region.y - last_region.y); + rectangles.Add(rectangle); + } + } + else if (last_region.state == PDFRegionLocator.SegmentState.PIXELS) + { + // Full column + { + Rectangle rectangle = new Rectangle(0, last_region.y, bitmap.Width, region.y - last_region.y); + rectangles.Add(rectangle); + } + } + + last_region = region; + } + + // DEBUG CODE: Draw in the region rectangles + //{ + // Graphics g = Graphics.FromImage(bitmap); + // foreach (Rectangle rectangle in rectangles) + // { + // g.DrawRectangle(Pens.Black, rectangle); + // } + + // bitmap.Save(@"C:\temp\aaaaaa.png", ImageFormat.Png); + //} + + // Do the OCR on each of the rectangles + WordList word_list = new WordList(); + foreach (Rectangle rectangle in rectangles) + { + if (0 == rectangle.Width || 0 == rectangle.Height) + { + Logging.Info("Skipping zero extent rectangle {0}", rectangle.ToString()); + continue; + } + + Logging.Info("Doing OCR for region {0}", rectangle.ToString()); + List result = ocr.DoOCR(bitmap, rectangle); + Logging.Info("Got {0} words", result.Count); + word_list.AddRange(ConvertToWordList(result, rectangle, bitmap)); + } + + Logging.Info("-Doing OCR"); + + + Logging.Info("Found {0} words", word_list.Count); + + //Logging.Info("+Reordering words for columns"); + //WordList word_list_ordered = ColumnWordOrderer.ReorderWords(word_list); + //Logging.Info("-Reordering words for columns"); + //word_list_ordered.WriteToFile(ocr_output_filename); + + return word_list; + } + } } private static WordList ConvertToWordList(List results, Rectangle rectangle, Bitmap bitmap)