using ImageMagick; using Microsoft.WindowsAPICodePack.Dialogs; using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Reflection; using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace PDFWorkflowManager { public partial class MainForm : Form { // Language Dictionary #region Language Dictionary Dictionary languageCodes = new Dictionary { {"Afrikaans","af"}, {"Amharic","am"}, {"Arabic","ar"}, {"Assamese","as"}, {"Azerbaijani","az"}, {"Belarusian","be"}, {"Bengali","bn"}, {"Bokmal","nb"}, {"Bulgarian","bg"}, {"Catalan","ca"}, {"Chinese(Simplified)","zh-CN"}, {"Chinese(Traditional)","zh-TW"}, {"Croatian","hr"}, {"Czech","cs"}, {"Danish","da"}, {"Dutch","nl"}, {"English","en"}, {"Estonian","et"}, {"Finnish","fi"}, {"French","fr"}, {"German","de"}, {"Greek","el"}, {"Gujarati","gu"}, {"Hebrew","he"}, {"Hindi","hi"}, {"Hungarian","hu"}, {"Icelandic","is"}, {"Indonesian","id"}, {"Italian","it"}, {"Japanese","ja"}, {"Kannada","kn"}, {"Korean","ko"}, {"Latvian","lv"}, {"Lithuanian","lt"}, {"Malayalam","ml"}, {"Marathi","mr"}, {"Nepali","ne"}, {"Norwegian","no"}, {"Oriya","or"}, {"Polish","pl"}, {"Portuguese","pt"}, {"Punjabi","pa"}, {"Romanian","ro"}, {"Russian","ru"}, {"Slovak","sk"}, {"Slovenian","sl"}, {"Spanish","es"}, {"Swahili","sw"}, {"Swedish","sv"}, {"Tamil","ta"}, {"Telugu","te"}, {"Thai","th"}, {"Tibetan","bo"}, {"Turkish","tr"}, {"Ukrainian","uk"}, {"Urdu","ur"}, {"Vietnamese","vi"} }; Dictionary trainLanguage = new Dictionary { {"Afrikaans","afr"}, {"Amharic","amh"}, {"Arabic","ara"}, {"Assamese","asm"}, {"Azerbaijani","aze"}, {"Belarusian","bel"}, {"Bengali","ben"}, {"Bokmal","nb"}, {"Bulgarian","bul"}, {"Catalan","ca"}, {"Chinese(Simplified)","chi_sim"}, {"Chinese(Traditional)","chi_tra"}, {"Croatian","chr"}, {"Czech","ces"}, {"Danish","dan"}, {"Dutch","nld"}, {"English","eng"}, {"Estonian","est"}, {"Finnish","fin"}, {"French","fra"}, {"German","deu"}, {"Greek","ell"}, {"Gujarati","guj"}, {"Hebrew","heb"}, {"Hindi","hin"}, {"Hungarian","hun"}, {"Icelandic","isl"}, {"Indonesian","ind"}, {"Italian","ita"}, {"Japanese","jpn"}, {"Kannada","kan"}, {"Korean","kor"}, {"Latvian","lav"}, {"Lithuanian","lit"}, {"Malayalam","mal"}, {"Marathi","mar"}, {"Nepali","nep"}, {"Norwegian","nor"}, {"Oriya","ori"}, {"Polish","pol"}, {"Portuguese","por"}, {"Punjabi","pan"}, {"Romanian","ron"}, {"Russian","rus"}, {"Slovak","slk"}, {"Slovenian","slv"}, {"Spanish","spa"}, {"Swahili","swa"}, {"Swedish","swe"}, {"Tamil","tam"}, {"Telugu","tel"}, {"Thai","tha"}, {"Tibetan","bod"}, {"Turkish","tur"}, {"Ukrainian","ukr"}, {"Urdu","urd"}, {"Vietnamese","vie"} }; #endregion // Path where banner pages are located private string strExeFilePath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); private SemaphoreSlim semaphore = new SemaphoreSlim(1); string bannerPage = ""; private string loadedProjectFilePath = string.Empty; private string workDir = Properties.Settings.Default.WorkDir; private string workOutDir = Properties.Settings.Default.WorkOutDir; private string origsDir = Properties.Settings.Default.OrigsDir; private string tempDir = Properties.Settings.Default.TempDir; private string strPostProcessor = Properties.Settings.Default.PostProcessor; private string strExtension = "tif"; private string bannerPageA5 = "banner_a5.pdf"; public MainForm() { InitializeComponent(); txtPostProcessor.Text = strPostProcessor; cmbBanner.SelectedIndex = Properties.Settings.Default.Banner; txtPDFAuthor.Text = Properties.Settings.Default.PDFMetaAuthor; radioSortNormal.Checked = true; // cmbLanguage Populate #region cmbLanguage foreach (KeyValuePair train in trainLanguage) { cmbLanguage.Items.Add(new { Text = train.Key, Value = train.Value }); } //cmbLanguage.Items.Add(new { Text = "Afrikaans", Value = "afr" }); //cmbLanguage.Items.Add(new { Text = "Amharic", Value = "amh" }); //cmbLanguage.Items.Add(new { Text = "Arabic", Value = "ara" }); //cmbLanguage.Items.Add(new { Text = "Assamese", Value = "asm" }); //cmbLanguage.Items.Add(new { Text = "Azerbaijani", Value = "aze" }); //cmbLanguage.Items.Add(new { Text = "Belarusian", Value = "bel" }); //cmbLanguage.Items.Add(new { Text = "Bengali", Value = "ben" }); //cmbLanguage.Items.Add(new { Text = "Bokmal", Value = "nob" }); //cmbLanguage.Items.Add(new { Text = "Bulgarian", Value = "bul" }); //cmbLanguage.Items.Add(new { Text = "Catalan", Value = "cat" }); //cmbLanguage.Items.Add(new { Text = "Chinese (Simplified)", Value = "chi_sim" }); //cmbLanguage.Items.Add(new { Text = "Chinese (Traditional)", Value = "chi_tra" }); //cmbLanguage.Items.Add(new { Text = "Croatian", Value = "hrv" }); //cmbLanguage.Items.Add(new { Text = "Czech", Value = "ces" }); //cmbLanguage.Items.Add(new { Text = "Danish", Value = "dan" }); //cmbLanguage.Items.Add(new { Text = "Dutch", Value = "nld" }); //cmbLanguage.Items.Add(new { Text = "English", Value = "eng" }); //cmbLanguage.Items.Add(new { Text = "Estonian", Value = "est" }); //cmbLanguage.Items.Add(new { Text = "Finnish", Value = "fin" }); //cmbLanguage.Items.Add(new { Text = "French", Value = "fra" }); //cmbLanguage.Items.Add(new { Text = "German", Value = "deu" }); //cmbLanguage.Items.Add(new { Text = "Greek", Value = "ell" }); //cmbLanguage.Items.Add(new { Text = "Gujarati", Value = "guj" }); //cmbLanguage.Items.Add(new { Text = "Hebrew", Value = "heb" }); //cmbLanguage.Items.Add(new { Text = "Hindi", Value = "hin" }); //cmbLanguage.Items.Add(new { Text = "Hungarian", Value = "hun" }); //cmbLanguage.Items.Add(new { Text = "Icelandic", Value = "isl" }); //cmbLanguage.Items.Add(new { Text = "Indonesian", Value = "ind" }); //cmbLanguage.Items.Add(new { Text = "Italian", Value = "ita" }); //cmbLanguage.Items.Add(new { Text = "Japanese", Value = "jpn" }); //cmbLanguage.Items.Add(new { Text = "Kannada", Value = "kan" }); //cmbLanguage.Items.Add(new { Text = "Korean", Value = "kor" }); //cmbLanguage.Items.Add(new { Text = "Latvian", Value = "lav" }); //cmbLanguage.Items.Add(new { Text = "Lithuanian", Value = "lit" }); //cmbLanguage.Items.Add(new { Text = "Malayalam", Value = "mal" }); //cmbLanguage.Items.Add(new { Text = "Marathi", Value = "mar" }); //cmbLanguage.Items.Add(new { Text = "Nepali", Value = "nep" }); //cmbLanguage.Items.Add(new { Text = "Norwegian", Value = "nor" }); //cmbLanguage.Items.Add(new { Text = "Oriya", Value = "ori" }); //cmbLanguage.Items.Add(new { Text = "Polish", Value = "pol" }); //cmbLanguage.Items.Add(new { Text = "Portuguese", Value = "por" }); //cmbLanguage.Items.Add(new { Text = "Punjabi", Value = "pan" }); //cmbLanguage.Items.Add(new { Text = "Romanian", Value = "ron" }); //cmbLanguage.Items.Add(new { Text = "Russian", Value = "rus" }); //cmbLanguage.Items.Add(new { Text = "Slovak", Value = "slk" }); //cmbLanguage.Items.Add(new { Text = "Slovenian", Value = "slv" }); //cmbLanguage.Items.Add(new { Text = "Spanish", Value = "spa" }); //cmbLanguage.Items.Add(new { Text = "Swahili", Value = "swa" }); //cmbLanguage.Items.Add(new { Text = "Swedish", Value = "swe" }); //cmbLanguage.Items.Add(new { Text = "Tamil", Value = "tam" }); //cmbLanguage.Items.Add(new { Text = "Telugu", Value = "tel" }); //cmbLanguage.Items.Add(new { Text = "Thai", Value = "tha" }); //cmbLanguage.Items.Add(new { Text = "Tibetan", Value = "tib" }); //cmbLanguage.Items.Add(new { Text = "Turkish", Value = "tur" }); //cmbLanguage.Items.Add(new { Text = "Ukrainian", Value = "ukr" }); //cmbLanguage.Items.Add(new { Text = "Urdu", Value = "urd" }); //cmbLanguage.Items.Add(new { Text = "Vietnamese", Value = "vie" }); cmbLanguage.DisplayMember = "Text"; cmbLanguage.ValueMember = "Value"; cmbLanguage.SelectedIndex = cmbLanguage.FindStringExact("English"); #endregion btnMakePDF.Enabled = true; //public string txtPostProcessor.text = ""; } // Handle Ctrl+S key press to save metadata protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { // Check if the user pressed Control + S if (keyData == (Keys.Control | Keys.S)) { // Trigger the saveToolStripMenuItem_Click event saveToolStripMenuItem_Click(this, EventArgs.Empty); return true; // Indicate that the key press was handled } return base.ProcessCmdKey(ref msg, keyData); } // Select Project Directory private void btnProjectDir_Click(object sender, EventArgs e) { CommonOpenFileDialog dialog = new CommonOpenFileDialog(); if (Directory.Exists(txtProjectDir.Text)) { dialog.InitialDirectory = @txtProjectDir.Text; } else { dialog.RestoreDirectory = true; } dialog.IsFolderPicker = true; if (dialog.ShowDialog() == CommonFileDialogResult.Ok) { txtProjectDir.Text = dialog.FileName; // Clear up pictures try { if (pictureBox1.Image != null) { pictureBox1.Image.Dispose(); pictureBox1.Image = null; pictureBox1.Invalidate(); } else { pictureBox1.Image = null; pictureBox1.Invalidate(); } if (pictureBox2.Image != null) { pictureBox2.Image.Dispose(); pictureBox2.Image = null; pictureBox2.Invalidate(); } else { pictureBox2.Image = null; pictureBox2.Invalidate(); } GC.Collect(); GC.WaitForPendingFinalizers(); } catch { MessageBox.Show("Could not clear preview images.", "Error clearing preview images.", MessageBoxButtons.OK, MessageBoxIcon.Error); } txtProjectDir.ReadOnly = true; checkSimplex.Enabled = true; } check_input_dir(); } // Check input dir for origs dir and files private void check_input_dir() { Cursor.Current = Cursors.WaitCursor; if (!Directory.Exists(Path.Combine(txtProjectDir.Text, Properties.Settings.Default.OrigsDir))) { MessageBox.Show("Origs dir not found.", "Origs dir not found.", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } else if (Directory.GetFiles(Path.Combine(txtProjectDir.Text, Properties.Settings.Default.OrigsDir), "*.tif").Length == 0 && Directory.GetFiles(Path.Combine(txtProjectDir.Text, Properties.Settings.Default.OrigsDir), "*.tiff").Length == 0 && Directory.GetFiles(Path.Combine(txtProjectDir.Text, Properties.Settings.Default.OrigsDir), "*.png").Length == 0) { MessageBox.Show("Origs files not found.", "Error no TIF files found.", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (Directory.Exists(Path.Combine(txtProjectDir.Text, Properties.Settings.Default.OrigsDir)) && !Directory.Exists(Path.Combine(txtProjectDir.Text, Properties.Settings.Default.WorkDir))) { // Replace the selected code block with this version try { string[] strOrigFiles = Directory.GetFiles(Path.Combine(txtProjectDir.Text, Properties.Settings.Default.OrigsDir), "*.tif*"); if (File.Exists(strOrigFiles[0])) { using (var memoryStream = new MemoryStream(File.ReadAllBytes(strOrigFiles[0]))) using (var bitmap = new Bitmap(memoryStream)) { // Create a copy of the bitmap to ensure the file is released pictureBox1.Image = new Bitmap(bitmap); } // At this point, the file is fully released } } catch { MessageBox.Show("Could not load preview image from Origs directory.", "Error loading preview image.", MessageBoxButtons.OK, MessageBoxIcon.Error); } } else if (Directory.Exists(Path.Combine(txtProjectDir.Text, Properties.Settings.Default.WorkDir))) { btnCopyPathWorkDir.Enabled = true; btnConvertToPDF.Enabled = true; // Replace the selected code block with this version try { string[] strWorkFiles = Directory.GetFiles(Path.Combine(txtProjectDir.Text, Properties.Settings.Default.WorkDir), "*.tif"); if (strWorkFiles.Length > 0) { using (var memoryStream = new MemoryStream(File.ReadAllBytes(strWorkFiles[0]))) using (var bitmap = new Bitmap(memoryStream)) { pictureBox1.Image = new Bitmap(bitmap); } // Release file handle so tempCopyPath is writeable GC.Collect(); GC.WaitForPendingFinalizers(); } } catch { MessageBox.Show("Could not load preview image from Work directory.", "Error loading preview image.", MessageBoxButtons.OK, MessageBoxIcon.Error); } if (Directory.Exists(Path.Combine(txtProjectDir.Text, Properties.Settings.Default.WorkOutDir))) { try { string[] strOutFiles = Directory.GetFiles(Path.Combine(txtProjectDir.Text, Properties.Settings.Default.WorkOutDir), "*.tif"); if (strOutFiles.Length > 0) { string tempCopyPath = Path.Combine(tempDir, "preview_out.tif"); File.Copy(strOutFiles[0], tempCopyPath, true); using (var memoryStream = new MemoryStream(File.ReadAllBytes(tempCopyPath))) using (var bitmap = new Bitmap(memoryStream)) { pictureBox2.Image = new Bitmap(bitmap); } // Release file handle so tempCopyPath is writeable GC.Collect(); GC.WaitForPendingFinalizers(); File.Delete(tempCopyPath); } } catch { MessageBox.Show("Could not load preview image from Work\\out directory.", "Error loading preview image.", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } if (File.Exists(txtProjectDir.Text + @"\run_simplex_sorting_script.txt")) { checkSimplex.Checked = true; } else { checkSimplex.Checked = false; } // Try and get resolution, and set banner pages string[] strFiles = Directory.GetFiles(Path.Combine(txtProjectDir.Text, Properties.Settings.Default.OrigsDir), "*.tif"); int sourceFileCount = strFiles.Length; if (sourceFileCount > 0) { var image = new MagickImage(strFiles[0]); image.Read(strFiles[0]); try { // Set resolution if (image.Density.X == 600 && image.Density.Y == 600) { cmbResolution.SelectedIndex = cmbResolution.FindStringExact("600"); } else if (image.Density.X == 300 && image.Density.Y == 300) { cmbResolution.SelectedIndex = cmbResolution.FindStringExact("300"); } // Set Banner if (Properties.Settings.Default.Banner != 2) { if ((image.Width > 4000 || image.Height > 5500) && (cmbResolution.SelectedItem.ToString() == "600")) { cmbBanner.SelectedIndex = 0; } else // if ((image.Width > 1860 || image.Height > 2631) && (cmbResolution.SelectedItem.ToString() == "300")) { cmbBanner.SelectedIndex = 1; } } } catch { } Cursor.Current = Cursors.Default; } btnCalcPageCount.Enabled = true; btnPrepareWorkDir.Enabled = true; panelBanner.Enabled = true; panelSort.Enabled = true; groupMetadata.Enabled = true; groupExport.Enabled = true; groupPDF.Enabled = true; workDir = Path.Combine(txtProjectDir.Text, Properties.Settings.Default.WorkDir); workOutDir = Path.Combine(txtProjectDir.Text, Properties.Settings.Default.WorkOutDir); origsDir = Path.Combine(txtProjectDir.Text, Properties.Settings.Default.OrigsDir); tempDir = Path.Combine(txtProjectDir.Text, Properties.Settings.Default.TempDir); try { watcherOut.Path = workOutDir; watcherOut.EnableRaisingEvents = true; } catch { } } private void btnPrepareWorkDir_Click(object sender, EventArgs e) { watcherOut.EnableRaisingEvents = false; string[] strFiles = Directory.GetFiles(origsDir, "*.tif"); int sourceFileCount = strFiles.Length; if (sourceFileCount == 0) { strFiles = Directory.GetFiles(origsDir, "*.png"); sourceFileCount = strFiles.Length; } int odd = 1; int even = sourceFileCount; Directory.CreateDirectory(workDir); toolStripProgressBar1.Maximum = sourceFileCount; string fileName = ""; string fileExtension = Path.GetExtension(strFiles[0]); if (checkSimplex.Checked == true) { for (int i = 0; i < sourceFileCount; i++) { if (odd < sourceFileCount) { fileName = odd.ToString().PadLeft(4, '0'); odd += 2; } else if (even > 0) { fileName = even.ToString().PadLeft(4, '0'); even -= 2; } File.Copy(strFiles[i], Path.Combine(workDir, fileName + fileExtension), true); } } else { foreach (string newPath in strFiles) { File.Copy(newPath, newPath.Replace(origsDir, workDir), true); } } int destinationFileCount = Directory.GetFiles(workDir, "*.tif").Length; toolStripProgressBar1.Value = destinationFileCount; if (sourceFileCount > destinationFileCount) { toolStripStatusLabel1.Text = "ERROR: " + destinationFileCount + " out of " + sourceFileCount + " files were copied"; } toolStripStatusLabel1.Text = destinationFileCount + " copied. Work dir is ready."; btnCopyPathWorkDir.Enabled = true; btnConvertToPDF.Enabled = true; try { string[] strWorkFiles = Directory.GetFiles(workDir, "*.tif"); byte[] imageBytes = File.ReadAllBytes(strWorkFiles[0]); using (MemoryStream memoryStream = new MemoryStream(imageBytes)) { using (Bitmap bitmap = new Bitmap(memoryStream)) { pictureBox1.Image = new Bitmap(bitmap); } } } catch { } try { Directory.CreateDirectory(workOutDir); } catch { MessageBox.Show("Could not create Work\\out directory.", "Error creating Work\\out directory.", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void btnCopyPathWorkDir_Click(object sender, EventArgs e) { Clipboard.SetText(workDir); toolStripStatusLabel1.Text = "Path copied to clipboard."; ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.UseShellExecute = false; startInfo.RedirectStandardOutput = true; startInfo.CreateNoWindow = true; startInfo.FileName = Properties.Settings.Default.ScanTailor; var process = Process.Start(startInfo); //using (var process = Process.Start(startInfo)) //{ // process.WaitForExit(); //} } private void checkSimplex_CheckedChanged(object sender, EventArgs e) { int sourceFileCount = Directory.GetFiles(origsDir, "*.tif").Length; if (sourceFileCount % 2 > 0 && checkSimplex.Checked == true) { btnPrepareWorkDir.BackColor = Color.Red; toolStripStatusLabel1.Text = "Odd amount of files, check your scans."; } else { btnPrepareWorkDir.BackColor = Color.Transparent; toolStripStatusLabel1.Text = ""; } } private void quitToolStripMenuItem_Click(object sender, EventArgs e) { Application.Exit(); } private string prepCopyToTempOutdir(int sourceFileCount, string[] strFiles) { string tempSortDir = Path.Combine(tempDir, "sort"); Directory.CreateDirectory(tempSortDir); int downCount = sourceFileCount; int upCount = 1; // Make this to a function if (radioSortMagazine.Checked == true) { for (int i = 0; i < sourceFileCount;) { File.Copy(strFiles[i], Path.Combine(tempSortDir, downCount.ToString().PadLeft(4, '0') + ".tif"), true); i++; downCount--; File.Copy(strFiles[i], Path.Combine(tempSortDir, upCount.ToString().PadLeft(4, '0') + ".tif"), true); i++; upCount++; File.Copy(strFiles[i], Path.Combine(tempSortDir, upCount.ToString().PadLeft(4, '0') + ".tif"), true); i++; upCount++; File.Copy(strFiles[i], Path.Combine(tempSortDir, downCount.ToString().PadLeft(4, '0') + ".tif"), true); i++; downCount--; } // fixme why sleep? Thread.Sleep(1000); } else if (radioSortFlatBed.Checked == true) { for (int i = 1; i < sourceFileCount;) { File.Copy(strFiles[i], Path.Combine(tempSortDir, upCount.ToString().PadLeft(4, '0') + ".tif"), true); i++; upCount++; } File.Copy(strFiles[0], Path.Combine(tempSortDir, upCount.ToString().PadLeft(4, '0') + ".tif"), true); // fixme why sleep? Thread.Sleep(1000); } else if (radioSortNormal.Checked == true) { for (int i = 0; i < sourceFileCount;) { File.Copy(strFiles[i], Path.Combine(tempSortDir, upCount.ToString().PadLeft(4, '0') + ".tif"), true); i++; upCount++; } } return tempSortDir; } static void convertToJpeg(string sourceFileName, string destinationFileName, int compressionLevel, int dpi = 300) { try { using (Image sourceImage = Image.FromFile(sourceFileName)) { // Calculate new dimensions based on DPI float scaleFactor = dpi / sourceImage.HorizontalResolution; int newWidth = (int)(sourceImage.Width * scaleFactor); int newHeight = (int)(sourceImage.Height * scaleFactor); using (var newImage = new Bitmap(newWidth, newHeight)) { newImage.SetResolution(dpi, dpi); // Draw the source image onto the new bitmap with the new dimensions using (Graphics graphics = Graphics.FromImage(newImage)) { graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; graphics.DrawImage(sourceImage, 0, 0, newWidth, newHeight); } // Set encoding parameters for JPEG EncoderParameters encoderParameters = new EncoderParameters(1); encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, compressionLevel); // Get the JPEG codec ImageCodecInfo jpegCodec = GetEncoderInfo(ImageFormat.Jpeg); // Save the image in JPEG format with specified compression level newImage.Save(destinationFileName, jpegCodec, encoderParameters); } } } catch (Exception) { } } static ImageCodecInfo GetEncoderInfo(ImageFormat format) { foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageDecoders()) { if (codec.FormatID == format.Guid) { return codec; } } return null; } private async Task convertToPdf(string[] strFiles, string outputDir, string selectedLanguage) { ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.UseShellExecute = false; startInfo.RedirectStandardOutput = true; startInfo.CreateNoWindow = true; // TODO make this configurable startInfo.FileName = Properties.Settings.Default.TesserAct; string outputFile = ""; toolStripProgressBar1.Maximum = strFiles.Count(); toolStripProgressBar1.Value = 0; toolStripStatusLabel1.Text = "Converting files to pdf."; Task convertpdf = Task.Run(() => { Parallel.ForEach(strFiles, inputFile => { outputFile = Path.GetFileNameWithoutExtension(inputFile); startInfo.Arguments = "\"" + inputFile + "\"" + " " + "\"" + Path.Combine(outputDir, outputFile) + "\"" + " -l " + selectedLanguage + " pdf txt"; using (var process = Process.Start(startInfo)) { process.WaitForExit(); } if (toolStripProgressBar1.Control.InvokeRequired) { toolStripProgressBar1.Control.Invoke((MethodInvoker)delegate { toolStripProgressBar1.Value++; }); } else { toolStripProgressBar1.Value++; } }); }); await Task.WhenAll(convertpdf); Thread.Sleep(1000); // Parallel doesn't always return full result, we pick up the missing and process them again single threaded /* if (Directory.GetFiles(sourceDir, "*." + strExtension).Length != outFiles.Length) { string[] arrayInFiles = new string[inFiles.Length]; string[] arrayOutFiles = new string[outFiles.Length]; for (int i = 0; i < inFiles.Length; i++) { arrayInFiles[i] = Path.GetFileNameWithoutExtension(inFiles[i]); } for (int i = 0; i < outFiles.Length; i++) { arrayOutFiles[i] = Path.GetFileNameWithoutExtension(outFiles[i]); } string[] difference = arrayInFiles.Except(arrayOutFiles).ToArray(); foreach (string item in difference) { startInfo.Arguments = "\"" + Path.Combine(sourceDir, item + "." + strExtension) + "\"" + " " + "\"" + Path.Combine(outputDir, item) + "\"" + " -l " + selectedLanguage + " pdf txt"; using (var process = Process.Start(startInfo)) { process.WaitForExit(); } } if (Directory.GetFiles(sourceDir, "*." + strExtension).Length != Directory.GetFiles(outputDir, "*.pdf").Length) { MessageBox.Show("Not all files were converted to PDF"); } } */ } private async Task prepConvertToTempOutdir(string[] strFiles) { try { await semaphore.WaitAsync(); string tempJpg300Dir = Path.Combine(tempDir, "jpg300"); string tempJpg150Dir = Path.Combine(tempDir, "jpg150"); Directory.CreateDirectory(tempJpg300Dir); Directory.CreateDirectory(tempJpg150Dir); string outputFile = ""; int filecount = strFiles.Count() * 2; toolStripProgressBar1.Maximum = filecount; toolStripProgressBar1.Value = 0; toolStripStatusLabel1.Text = "Converting files to jpg."; List tasks = new List(); await Task.Run(() => { Parallel.ForEach(strFiles, async inputFile => { outputFile = Path.Combine(tempJpg300Dir, Path.GetFileNameWithoutExtension(inputFile) + ".jpg"); convertToJpeg(inputFile, outputFile, 85, 300); //Interlocked.Increment(ref toolStripProgressBar1.Value); //UpdateProgressBar(); }); }); await Task.Run(() => { Parallel.ForEach(strFiles, async inputFile => { outputFile = Path.Combine(tempJpg150Dir, Path.GetFileNameWithoutExtension(inputFile) + ".jpg"); convertToJpeg(inputFile, outputFile, 85, 150); //Interlocked.Increment(ref toolStripProgressBar1.Value); //UpdateProgressBar(); }); }); await Task.WhenAll(tasks); } finally { semaphore.Release(); // Release semaphore } } private void UpdateProgressBar() { if (toolStripProgressBar1.Control.InvokeRequired) { toolStripProgressBar1.Control.Invoke((MethodInvoker)delegate { toolStripProgressBar1.Value++; }); } else { toolStripProgressBar1.Value++; } } private async void btnConvertToPDF_Click(object sender, EventArgs e) { try { string[] strFiles = Directory.GetFiles(workOutDir, "*.tif"); int sourceFileCount = strFiles.Length; string outputDir = Path.Combine(tempDir, "output"); Directory.CreateDirectory(outputDir); string sourceDir = workOutDir; var selectedLanguage = "eng"; if (checkLanguage.Checked == true) { var language = (dynamic)cmbLanguage.SelectedItem; selectedLanguage = language.Value; } else { string[] langArray = txtLanguages.Text.Split(new string[] { "; " }, StringSplitOptions.RemoveEmptyEntries); selectedLanguage = String.Join("+", trainLanguage .Where(kv => langArray .Contains(kv.Key)) .Select(kv => kv.Value) ); } sourceDir = prepCopyToTempOutdir(sourceFileCount, strFiles); strFiles = Directory.GetFiles(sourceDir, "*." + strExtension); string jpg150dir = ""; if (chkMagazines.Checked == true) { await prepConvertToTempOutdir(strFiles); sourceDir = Path.Combine(tempDir, "jpg300"); jpg150dir = Path.Combine(tempDir, "jpg150"); // convert to jpg function strExtension = "jpg"; } strFiles = Directory.GetFiles(sourceDir, "*." + strExtension); await convertToPdf(strFiles, outputDir, selectedLanguage); try { string[] strFiles150 = Directory.GetFiles(jpg150dir, "*." + strExtension); if (strFiles.Count() == strFiles150.Count()) { strFiles150 = Directory.GetFiles(jpg150dir, "*." + strExtension); await convertToPdf(strFiles150, jpg150dir, selectedLanguage); } } catch { } string[] inFiles = Directory.GetFiles(sourceDir, "*." + strExtension); string[] outFiles = Directory.GetFiles(outputDir, "*.pdf"); txtPageCount.Text = inFiles.Length.ToString(); btnMakePDF.Enabled = true; btnMakePDF.Enabled = true; toolStripStatusLabel1.Text = "Converting files to pdf. Done!"; strExtension = "tif"; // reset to tiff extension } catch { strExtension = "tif"; // reset to tiff extension MessageBox.Show("No supported files in Work\\out directory!", "No supported files found!", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } private void btnCalcPageCount_Click(object sender, EventArgs e) { try { string[] outFiles = Directory.GetFiles(workOutDir, "*." + strExtension); txtPageCount.Text = outFiles.Length.ToString(); } catch { } } private void btnMakePDF_Click(object sender, EventArgs e) { if (!File.Exists(txtProjectDir.Text + @"\" + txtFileName.Text + ".txt")) { saveMetadata(); } try { toolStripProgressBar1.Maximum = 1; toolStripStatusLabel1.Text = "Creating final pdf."; toolStripProgressBar1.Value = 0; string outputDir = Path.Combine(tempDir, "output"); string tempFile = Path.Combine(tempDir, "_" + ".pdf"); string tempFile150 = Path.Combine(tempDir, "_150" + ".pdf"); // PDF 1.5 -> 1.7 + Metadata (gswin64c) if (!Directory.Exists(tempDir)) { Directory.CreateDirectory(tempDir); } if (cmbBanner.SelectedItem.ToString() == "A4") { bannerPage = "banner_a4.pdf"; } else if (cmbBanner.SelectedItem.ToString() == "A5") { bannerPage = "banner_a5.pdf"; } else { bannerPage = ""; } // Gather PDF's to one single, add banner page (pdf toolkit server) ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.UseShellExecute = false; startInfo.RedirectStandardOutput = true; startInfo.CreateNoWindow = true; // TODO make this configurable startInfo.FileName = Properties.Settings.Default.PDFtk; startInfo.Arguments = "\"" + Path.Combine(outputDir, "*.pdf") + "\" " + bannerPage + " cat output " + "\"" + tempFile + "\""; using (var process = Process.Start(startInfo)) { process.WaitForExit(); } if (Directory.Exists(Path.Combine(tempDir, "jpg150"))) { string bannera5 = Path.Combine(strExeFilePath, bannerPageA5); startInfo.FileName = Properties.Settings.Default.PDFtk; startInfo.Arguments = "\"" + Path.Combine(Path.Combine(tempDir, "jpg150", "*.pdf")) + "\" \"" + bannera5 + "\" cat output " + "\"" + tempFile150 + "\""; using (var process = Process.Start(startInfo)) { process.WaitForExit(); } } // Create Thumbnail string[] outFiles = Directory.GetFiles(Path.Combine(tempDir, "sort"), "*.tif"); createThumbNail(outFiles[0]); textToOcrFile(outputDir); generatePDFMetadata(); updatePDFMetaData(tempFile); if (File.Exists(tempFile150)) { updatePDFMetaData(tempFile150, "150"); } toolStripStatusLabel1.Text = "Creating final pdf. Done."; toolStripProgressBar1.Value = 1; File.Delete(tempFile); string md5string = GetMD5(Path.Combine(txtProjectDir.Text, txtFileName.Text + ".pdf")) + " *" + txtFileName.Text + ".pdf"; string sha1string = GetSHA1(Path.Combine(txtProjectDir.Text, txtFileName.Text + ".pdf")) + " *" + txtFileName.Text + ".pdf"; File.WriteAllText(Path.Combine(txtProjectDir.Text, txtFileName.Text + ".pdf.md5"), md5string); File.WriteAllText(Path.Combine(txtProjectDir.Text, txtFileName.Text + ".pdf.sha1"), sha1string); } catch (Exception ex) { MessageBox.Show("No pdf files converted!, convert your files to PDF", "No supported files found! " + ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } File.Delete(Path.Combine(tempDir, "pdfmetadata.txt")); } private void updatePDFMetaData(string tempFile, string modifier = "") { string filename = txtFileName.Text; if (modifier != "") { filename = txtFileName.Text.Replace(cmbResolution.Text, modifier); } ProcessStartInfo updatePDF = new ProcessStartInfo(); updatePDF.UseShellExecute = false; updatePDF.RedirectStandardOutput = true; updatePDF.CreateNoWindow = true; updatePDF.FileName = Properties.Settings.Default.GhostScript; updatePDF.Arguments = "-dBATCH -dNOPAUSE -dAutoRotatePages=/None -sDEVICE=pdfwrite -sOutputFile=\"" + Path.Combine(txtProjectDir.Text, filename + ".pdf") + "\" \"" + tempFile + "\" \"" + Path.Combine(tempDir, "pdfmetadata.txt") + "\""; //updatePDF.Arguments = "-dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=\"" + Path.Combine(txtProjectDir.Text, txtFileName.Text + ".pdf") + "\" \"" + tempFile + "\" -c\" " + generatePDFMetadata() + "\""; using (var process = Process.Start(updatePDF)) { process.WaitForExit(120000); } } private void generatePDFMetadata() { string dateTimeNow = DateTime.Now.ToString("yyyyMMddHHmmss"); string pdfMetaData = $"[ /Title ({txtTitle.Text})\r\n"; pdfMetaData += $" /Author (" + txtPDFAuthor.Text + ")\r\n"; pdfMetaData += $" /Subject ({txtType.Text})\r\n"; pdfMetaData += $" /Keywords ({txtPDFKeywords.Text})\r\n"; pdfMetaData += $" /ModDate (D:{dateTimeNow})\r\n"; pdfMetaData += $" /CreationDate (D:{dateTimeNow})\r\n"; pdfMetaData += " /Creator (PDF Workflow Manager)\r\n"; pdfMetaData += " /Producer (PDF Workflow Manager from retro-commodore.eu)\r\n"; pdfMetaData += " /DOCINFO pdfmark\r\n"; File.WriteAllText(Path.Combine(tempDir, "pdfmetadata.txt"), pdfMetaData); //return pdfMetaData; } private void settingsToolStripMenuItem_Click(object sender, EventArgs e) { SettingsForm sf = new SettingsForm(); sf.ShowDialog(); } private void btnCalcTimeSpent_Click(object sender, EventArgs e) { string[] origFiles = Directory.GetFiles(origsDir, "*.tif"); int count = origFiles.Length; var startOrig = new FileInfo(origFiles[0]); var endOrig = new FileInfo(origFiles[count - 1]); string startTimeFile = startOrig.LastWriteTime.ToString(); string endTimeFile = endOrig.LastWriteTime.ToString(); double scanDuration = DateTime.Parse(endTimeFile).Subtract(DateTime.Parse(startTimeFile)).TotalMinutes; var startDir = new FileInfo(origsDir); string startTimeDir = startDir.CreationTime.ToString(); string dateTimeNow = DateTime.Now.ToString(); double processDuration = DateTime.Parse(dateTimeNow).Subtract(DateTime.Parse(startTimeDir)).TotalMinutes; double totalTime = Math.Ceiling(scanDuration + processDuration); if (totalTime > 480) { txtTimeSpent.Text = "Get time manually"; } else { txtTimeSpent.Text = totalTime.ToString(); } } private void btnSaveMeta_Click(object sender, EventArgs e) { saveMetadata(); } private void updateFileName(object sender, EventArgs e) { string fileName = ""; string company = txtPublisher.Text.Replace(" ", ""); string title = txtTitle.Text.Replace(" ", "_"); btnSaveMeta.Enabled = true; if (company.Length > 0) { fileName += company + "_"; } fileName += title; var selectedItem = (dynamic)cmbLanguage.SelectedItem; if (selectedItem != null) { var selectedValue = selectedItem.Value; if (selectedValue != "eng") { fileName += "_(" + languageCodes[cmbLanguage.Text] + ")" + $"[{cmbResolution.SelectedItem}dpi][ocr]"; } else { fileName += $"_[{cmbResolution.SelectedItem}dpi][ocr]"; } } else { cmbLanguage.SelectedIndex = cmbLanguage.FindStringExact("English"); } txtFileName.Text = fileName; } // Save Metadata private void saveMetadata() { string selectedLanguage = "eng"; if (checkLanguage.Checked == true) { selectedLanguage = cmbLanguage.Text; } else { selectedLanguage = txtLanguages.Text; } string textFileContents; textFileContents = "url: " + txtFileName.Text + ".pdf\r\n"; textFileContents += "text: " + txtFileName.Text + ".ocr.txt\r\n"; textFileContents += "title: " + txtTitle.Text + "\r\n"; textFileContents += "language: " + selectedLanguage + "\r\n"; textFileContents += "type: " + txtType.Text + "\r\n"; textFileContents += "company: " + txtPublisher.Text + "\r\n"; textFileContents += "author: " + txtAuthor.Text + "\r\n"; textFileContents += "isbn: " + txtISBN.Text + "\r\n"; textFileContents += "date: " + txtDate.Text + "\r\n"; textFileContents += "pagecount: " + txtPageCount.Text + "\r\n"; textFileContents += "resolution: " + cmbResolution.SelectedItem + "\r\n"; textFileContents += "photocopy: " + checkPhotocopy.Checked + "\r\n"; textFileContents += "replace: " + checkReplace.Checked + "\r\n"; textFileContents += "partnumber: " + txtPartnumber.Text + "\r\n"; textFileContents += "quality: " + trackBar1.Value + "\r\n"; textFileContents += "contributor: " + txtContributor.Text + "\r\n"; textFileContents += "scener: " + txtContributorURL.Text + "\r\n"; textFileContents += "postprocessor: " + txtPostProcessor.Text + "\r\n"; textFileContents += "timespent: " + txtTimeSpent.Text + "\r\n"; //textFileContents += " : " + .Text + "\r\n"; File.WriteAllText(txtProjectDir.Text + @"\" + txtFileName.Text + ".txt", textFileContents); } // Grab all the exported textfiles and combine them to one private void textToOcrFile(string strOutputDir) { string[] txtFiles = Directory.GetFiles(strOutputDir, "*.txt"); string strOcrText = ""; //if (Directory.GetFiles(workOutDir, "*.tif").Length == txtFiles.Length) //{ foreach (string ocrFile in txtFiles) { strOcrText += File.ReadAllText(ocrFile) + "\r\n\r\n\r\n"; } //} File.WriteAllText(Path.Combine(txtProjectDir.Text, txtFileName.Text + ".ocr.txt"), strOcrText); } private void createThumbNail(string fileName) { using (var image = new MagickImage(fileName)) { var size = new MagickGeometry(240, 340); size.IgnoreAspectRatio = false; image.Resize(size); image.Write(Path.Combine(txtProjectDir.Text, txtFileName.Text + ".jpg")); } } private void radioBannerA4_CheckedChanged(object sender, EventArgs e) { bannerPage = " \"" + Path.Combine(strExeFilePath, "banner_a4.pdf") + "\" "; } private void radioBannerA5_CheckedChanged(object sender, EventArgs e) { bannerPage = " \"" + Path.Combine(strExeFilePath, "banner_a5.pdf") + "\" "; } private void radioBannerNone_CheckedChanged(object sender, EventArgs e) { bannerPage = ""; } private void radioSortNormal_CheckedChanged(object sender, EventArgs e) { //sortNormal = true; string[] strFiles = Directory.GetFiles(workOutDir, "*.tif"); if (File.Exists(strFiles[0])) { pictureBox2.Image = new Bitmap(strFiles[0]); } } private void radioSortMagazine_CheckedChanged(object sender, EventArgs e) { //sortNormal = false; string[] strFiles = Directory.GetFiles(workOutDir, "*.tif"); if (File.Exists(strFiles[1])) { pictureBox2.Image = new Bitmap(strFiles[1]); } } private void radioSortFlatBed_CheckedChanged(object sender, EventArgs e) { //sortNormal = false; string[] strFiles = Directory.GetFiles(workOutDir, "*.tif"); if (File.Exists(strFiles[1])) { pictureBox2.Image = new Bitmap(strFiles[1]); } } private static string GetMD5(string file) { using (var md5 = MD5.Create()) { using (var stream = File.OpenRead(file)) { var hash = md5.ComputeHash(stream); return BitConverter.ToString(hash).Replace("-", "").ToLower(); } } } private static string GetSHA1(string file) { using (var sha1 = SHA1.Create()) { using (var stream = File.OpenRead(file)) { var hash = sha1.ComputeHash(stream); return BitConverter.ToString(hash).Replace("-", "").ToLower(); } } } private void checkLanguages_Clicked(object sender, EventArgs e) { cmbLanguage.Enabled = false; checkLanguage.Checked = false; checkLanguages.Checked = true; } private void checkLanguage_Clicked(object sender, EventArgs e) { cmbLanguage.Enabled = true; checkLanguages.Checked = false; checkLanguage.Checked = true; } private void btnLanguages_Click(object sender, EventArgs e) { cmbLanguage.Enabled = false; checkLanguage.Checked = false; checkLanguages.Checked = true; LanguagesForm form = new LanguagesForm(trainLanguage, txtLanguages.Text); form.ShowDialog(); txtLanguages.Text = form.resultText; } private void watcherOut_Created(object sender, FileSystemEventArgs e) { try { string[] strOutFiles = Directory.GetFiles(workOutDir, "*.tif"); byte[] imageBytes = File.ReadAllBytes(strOutFiles[0]); using (MemoryStream memoryStream = new MemoryStream(imageBytes)) { using (Bitmap bitmap = new Bitmap(memoryStream)) { pictureBox2.Image = new Bitmap(bitmap); } } } catch { } watcherOut.EnableRaisingEvents = false; } private void watcherOut_Changed(object sender, FileSystemEventArgs e) { try { string[] strOutFiles = Directory.GetFiles(workOutDir, "*.tif"); byte[] imageBytes = File.ReadAllBytes(strOutFiles[0]); using (MemoryStream memoryStream = new MemoryStream(imageBytes)) { using (Bitmap bitmap = new Bitmap(memoryStream)) { pictureBox2.Image = new Bitmap(bitmap); } } } catch { } watcherOut.EnableRaisingEvents = false; } private void aboutToolStripMenuItem_Click(object sender, EventArgs e) { var assembly = Assembly.GetExecutingAssembly(); var version = assembly.GetName().Version.ToString(); var copyrightAttr = assembly .GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false) .OfType() .FirstOrDefault(); var copyright = copyrightAttr?.Copyright ?? "Copyright info not found"; MessageBox.Show( $"PDF Workflow Manager v{version}\r\n\r\n{copyright}", "Version", MessageBoxButtons.OK, MessageBoxIcon.Information ); } private void btnDisposePics_Click(object sender, EventArgs e) { // Clear up pictures try { if (pictureBox1.Image != null) { pictureBox1.Image.Dispose(); pictureBox1.Image = null; } if (pictureBox2.Image != null) { pictureBox2.Image.Dispose(); pictureBox2.Image = null; } } catch { } } private void button1_Click_1(object sender, EventArgs e) { if (Directory.Exists(tempDir)) { Directory.Delete(tempDir, true); } } private void btnDeleteCacheWork_Click(object sender, EventArgs e) { if (Directory.Exists(workOutDir + "\\cache")) { Directory.Delete(workOutDir + "\\cache", true); } if (Directory.Exists(workDir)) { DirectoryInfo di = new DirectoryInfo(workDir); foreach (FileInfo file in di.GetFiles()) { file.Delete(); } } } private void txtProjectDir_Leave(object sender, EventArgs e) { // Use OrigsDir from settings instead of txtOrigsDir if (Directory.Exists(Path.Combine(txtProjectDir.Text, Properties.Settings.Default.OrigsDir))) { check_input_dir(); } } private void loadToolStripMenuItem_Click(object sender, EventArgs e) { using (OpenFileDialog openFileDialog = new OpenFileDialog()) { openFileDialog.Filter = "PDF Project Files (*.pdfproj)|*.pdfproj|All Files (*.*)|*.*"; openFileDialog.Title = "Open PDF Project File"; openFileDialog.Multiselect = false; if (openFileDialog.ShowDialog() == DialogResult.OK) { loadedProjectFilePath = openFileDialog.FileName; // Store the loaded file path var lines = File.ReadAllLines(loadedProjectFilePath); var dict = new Dictionary(); foreach (var line in lines) { var parts = line.Split(new[] { '=' }, 2); if (parts.Length == 2) dict[parts[0]] = parts[1]; } txtFileName.Text = dict.ContainsKey("FileName") ? dict["FileName"] : ""; txtTitle.Text = dict.ContainsKey("Title") ? dict["Title"] : ""; cmbLanguage.SelectedIndex = cmbLanguage.FindStringExact(dict.ContainsKey("Language") ? dict["Language"] : ""); txtLanguages.Text = dict.ContainsKey("Languages") ? dict["Languages"] : ""; txtType.Text = dict.ContainsKey("Type") ? dict["Type"] : ""; txtPublisher.Text = dict.ContainsKey("Publisher") ? dict["Publisher"] : ""; txtAuthor.Text = dict.ContainsKey("Author") ? dict["Author"] : ""; txtISBN.Text = dict.ContainsKey("ISBN") ? dict["ISBN"] : ""; txtDate.Text = dict.ContainsKey("Date") ? dict["Date"] : ""; txtPageCount.Text = dict.ContainsKey("PageCount") ? dict["PageCount"] : ""; cmbResolution.SelectedIndex = cmbResolution.FindStringExact(dict.ContainsKey("Resolution") ? dict["Resolution"] : ""); checkPhotocopy.Checked = dict.ContainsKey("Photocopy") ? dict["Photocopy"] == "True" : false; checkReplace.Checked = dict.ContainsKey("Replace") ? dict["Replace"] == "True" : false; txtPartnumber.Text = dict.ContainsKey("Partnumber") ? dict["Partnumber"] : ""; if (int.TryParse(dict.ContainsKey("Quality") ? dict["Quality"] : "4", out int quality)) trackBar1.Value = Math.Max(trackBar1.Minimum, Math.Min(trackBar1.Maximum, quality)); txtContributor.Text = dict.ContainsKey("Contributor") ? dict["Contributor"] : ""; txtContributorURL.Text = dict.ContainsKey("ContributorURL") ? dict["ContributorURL"] : ""; txtPostProcessor.Text = dict.ContainsKey("PostProcessor") ? dict["PostProcessor"] : ""; txtTimeSpent.Text = dict.ContainsKey("TimeSpent") ? dict["TimeSpent"] : ""; txtPDFAuthor.Text = dict.ContainsKey("PDFMetaAuthor") ? dict["PDFMetaAuthor"] : ""; txtPDFKeywords.Text = dict.ContainsKey("PDFKeywords") ? dict["PDFKeywords"] : ""; cmbBanner.SelectedIndex = cmbBanner.FindStringExact(dict.ContainsKey("Banner") ? dict["Banner"] : ""); chkMagazines.Checked = dict.ContainsKey("Magazine") ? dict["Magazine"] == "True" : false; checkSimplex.Checked = dict.ContainsKey("Simplex") ? dict["Simplex"] == "True" : false; txtProjectDir.Text = dict.ContainsKey("ProjectDir") ? dict["ProjectDir"] : ""; // MessageBox.Show("Loaded file: " + loadedProjectFilePath, "File Loaded", MessageBoxButtons.OK, MessageBoxIcon.Information); toolStripStatusLabel1.Text = "Project file loaded: "; } } } private void saveAsToolStripMenuItem_Click(object sender, EventArgs e) { using (SaveFileDialog saveFileDialog = new SaveFileDialog()) { // Set the initial directory to the value of txtProjectDir.Text if it is set if (!string.IsNullOrWhiteSpace(txtProjectDir.Text)) { saveFileDialog.InitialDirectory = txtProjectDir.Text; saveFileDialog.FileName = Path.GetFileName(txtProjectDir.Text); // Suggest directory name as the file name } saveFileDialog.Filter = "PDF Project Files (*.pdfproj)|*.pdfproj|All Files (*.*)|*.*"; saveFileDialog.Title = "Save PDF Project File"; saveFileDialog.DefaultExt = "pdfproj"; saveFileDialog.AddExtension = true; if (saveFileDialog.ShowDialog() == DialogResult.OK) { string selectedFile = saveFileDialog.FileName; // Collect all form data var lines = new List { "FileName=" + txtFileName.Text, "Title=" + txtTitle.Text, "Language=" + cmbLanguage.Text, "Languages=" + txtLanguages.Text, "Type=" + txtType.Text, "Publisher=" + txtPublisher.Text, "Author=" + txtAuthor.Text, "ISBN=" + txtISBN.Text, "Date=" + txtDate.Text, "PageCount=" + txtPageCount.Text, "Resolution=" + cmbResolution.Text, "Photocopy=" + checkPhotocopy.Checked, "Replace=" + checkReplace.Checked, "Partnumber=" + txtPartnumber.Text, "Quality=" + trackBar1.Value, "Contributor=" + txtContributor.Text, "ContributorURL=" + txtContributorURL.Text, "PostProcessor=" + txtPostProcessor.Text, "TimeSpent=" + txtTimeSpent.Text, "PDFMetaAuthor=" + txtPDFAuthor.Text, "PDFKeywords=" + txtPDFKeywords.Text, "Banner=" + cmbBanner.Text, "Magazine=" + chkMagazines.Checked, "Simplex=" + checkSimplex.Checked, "ProjectDir=" + txtProjectDir.Text }; File.WriteAllLines(selectedFile, lines); // MessageBox.Show("Saved file: " + selectedFile, "File Saved", MessageBoxButtons.OK, MessageBoxIcon.Information); toolStripStatusLabel1.Text = "File saved: " + selectedFile; } } } private void newToolStripMenuItem_Click(object sender, EventArgs e) { // Reset all input fields to default values txtFileName.Text = ""; txtTitle.Text = ""; cmbLanguage.SelectedIndex = cmbLanguage.FindStringExact("English"); txtLanguages.Text = ""; txtType.Text = ""; txtPublisher.Text = ""; txtAuthor.Text = ""; txtISBN.Text = ""; txtDate.Text = ""; txtPageCount.Text = ""; cmbResolution.SelectedIndex = cmbResolution.FindStringExact("600"); checkPhotocopy.Checked = false; checkReplace.Checked = false; txtPartnumber.Text = ""; trackBar1.Value = 4; txtContributor.Text = ""; txtContributorURL.Text = ""; txtPostProcessor.Text = strPostProcessor; txtTimeSpent.Text = ""; txtPDFAuthor.Text = Properties.Settings.Default.PDFMetaAuthor; txtPDFKeywords.Text = ""; cmbBanner.SelectedIndex = Properties.Settings.Default.Banner; chkMagazines.Checked = false; checkSimplex.Checked = false; txtProjectDir.Text = ""; // Clear up pictures try { if (pictureBox1.Image != null) { pictureBox1.Image.Dispose(); pictureBox1.Image = null; } if (pictureBox2.Image != null) { pictureBox2.Image.Dispose(); pictureBox2.Image = null; } } catch { } // Optionally reset status bar and progress bar toolStripStatusLabel1.Text = ""; toolStripProgressBar1.Value = 0; } private void HandleWorkOutDirFileEvent() { try { string[] strOutFiles = Directory.GetFiles(workOutDir, "*.tif"); if (strOutFiles.Length > 0) { using (var memoryStream = new MemoryStream(File.ReadAllBytes(strOutFiles[0]))) using (var bitmap = new Bitmap(memoryStream)) { pictureBox2.Image = new Bitmap(bitmap); } // Release file handle so file is writeable GC.Collect(); GC.WaitForPendingFinalizers(); } } catch { // Optionally log or handle error } } private void saveToolStripMenuItem_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(loadedProjectFilePath)) { // Overwrite the loaded file SaveProjectToFile(loadedProjectFilePath); // MessageBox.Show("File saved successfully: " + loadedProjectFilePath, "File Saved", MessageBoxButtons.OK, MessageBoxIcon.Information); toolStripStatusLabel1 .Text = "Project saved: " + loadedProjectFilePath; } else { // No file loaded, prompt to save as a new file saveAsToolStripMenuItem_Click(sender, e); } } private void SaveProjectToFile(string filePath) { // Collect all form data var lines = new List { "FileName=" + txtFileName.Text, "Title=" + txtTitle.Text, "Language=" + cmbLanguage.Text, "Languages=" + txtLanguages.Text, "Type=" + txtType.Text, "Publisher=" + txtPublisher.Text, "Author=" + txtAuthor.Text, "ISBN=" + txtISBN.Text, "Date=" + txtDate.Text, "PageCount=" + txtPageCount.Text, "Resolution=" + cmbResolution.Text, "Photocopy=" + checkPhotocopy.Checked, "Replace=" + checkReplace.Checked, "Partnumber=" + txtPartnumber.Text, "Quality=" + trackBar1.Value, "Contributor=" + txtContributor.Text, "ContributorURL=" + txtContributorURL.Text, "PostProcessor=" + txtPostProcessor.Text, "TimeSpent=" + txtTimeSpent.Text, "PDFMetaAuthor=" + txtPDFAuthor.Text, "PDFKeywords=" + txtPDFKeywords.Text, "Banner=" + cmbBanner.Text, "Magazine=" + chkMagazines.Checked, "Simplex=" + checkSimplex.Checked, "ProjectDir=" + txtProjectDir.Text }; File.WriteAllLines(filePath, lines); } } }