A Palaso.IProgress-compatible progress dialog which does the work in the background
Inheritance: System.Windows.Forms.Form
Ejemplo n.º 1
0
 public void LaunchDemoDialog()
 {
     using (var dlg = new ProgressDialogBackground())
     {
         dlg.ShowAndDoWork((progress,args) => CommandLineRunner.Run("PalasoUIWindowsForms.TestApp.exe", "CommandLineRunnerTest", null, string.Empty, 60, progress
         ,(s)=>
             {
                 progress.WriteStatus(s);
                 progress.WriteVerbose(s);
             }));
     }
 }
Ejemplo n.º 2
0
 public void DoUpdatesOfAllBooks()
 {
     using (var dlg = new ProgressDialogBackground())
     {
         dlg.ShowAndDoWork((progress, args) => DoUpdatesOfAllBooks(progress));
     }
 }
Ejemplo n.º 3
0
        public void DoChecksOfAllBooksBackgroundWork(ProgressDialogBackground dialog, string pathToFolderOfReplacementImages)
        {
            var bookInfos = TheOneEditableCollection.GetBookInfos();
            var count = bookInfos.Count();
            if (count == 0)
                return;

            foreach (var bookInfo in bookInfos)
            {
                //not allowed in this thread: dialog.ProgressBar.Value++;
                dialog.Progress.ProgressIndicator.PercentCompleted += 100/count;

                var book = _bookServer.GetBookFromBookInfo(bookInfo);

                dialog.Progress.WriteMessage("Checking " + book.TitleBestForUserDisplay);
                book.CheckBook(dialog.Progress, pathToFolderOfReplacementImages);
                dialog.ProgressString.WriteMessage("");
            }
            dialog.ProgressBar.Value++;
        }
Ejemplo n.º 4
0
 public void DoChecksOfAllBooks()
 {
     using (var dlg = new ProgressDialogBackground())
     {
         dlg.ShowAndDoWork((progress, args) => DoChecksOfAllBooksBackgroundWork(dlg,null));
         if (dlg.Progress.ErrorEncountered || dlg.Progress.WarningsEncountered)
         {
             MessageBox.Show("Bloom will now open a list of problems it found.");
             var path = Path.GetTempFileName() + ".txt";
             File.WriteAllText(path, dlg.ProgressString.Text);
             System.Diagnostics.Process.Start(path);
         }
         else
         {
             MessageBox.Show("Bloom didn't find any problems.");
         }
     }
 }
Ejemplo n.º 5
0
        public void AttemptMissingImageReplacements(string pathToFolderOfReplacementImages=null)
        {
            using (var dlg = new ProgressDialogBackground())
            {
                dlg.ShowAndDoWork((progress, args) => DoChecksOfAllBooksBackgroundWork(dlg, pathToFolderOfReplacementImages));
                if (dlg.Progress.ErrorEncountered || dlg.Progress.WarningsEncountered)
                {
                    MessageBox.Show("There were some problems. Bloom will now open a log of the attempt to replace missing images.");
                }
                else
                {
                    MessageBox.Show("There are no more missing images. Bloom will now open a log of what it did.");
                }

                var path = Path.GetTempFileName() + ".txt";
                File.WriteAllText(path, dlg.ProgressString.Text);
                System.Diagnostics.Process.Start(path);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Makes the image png if it's not a jpg, makes white transparent, compresses it, and saves in the book's folder.
        /// Replaces any file with the same name.
        /// </summary>
        /// <returns>The name of the file, now in the book's folder.</returns>
        private string ProcessAndCopyImage(PalasoImage imageInfo, string bookFolderPath)
        {
            var isJpeg = ShouldSaveAsJpeg(imageInfo);
            try
            {

                    using (Bitmap image = new Bitmap(imageInfo.Image))
                        //nb: there are cases (undefined) where we get out of memory if we are not operating on a copy
                    {
                        //photographs don't work if you try to make the white transparent
                        if (!isJpeg && image is Bitmap)
                        {
                            ((Bitmap) image).MakeTransparent(Color.White);
                                //make white look realistic against background
                        }

                        string imageFileName = GetImageFileName(bookFolderPath, imageInfo, isJpeg);
                        var dest = Path.Combine(bookFolderPath, imageFileName);
                        if (File.Exists(dest))
                        {
                            try
                            {
                                File.Delete(dest);
                            }
                            catch (System.IO.IOException error)
                            {
                                throw new ApplicationException("Bloom could not replace the image " + imageFileName +
                                                               ", probably because Bloom itself has it locked.");
                            }
                        }
                        image.Save(dest, isJpeg ? ImageFormat.Jpeg : ImageFormat.Png);
                        if (!isJpeg)
                        {
                            using (var dlg = new ProgressDialogBackground())
                            {
                                dlg.ShowAndDoWork((progress, args) => ImageUpdater.CompressImage(dest, progress));
                            }
                        }
                        imageInfo.Metadata.Write(dest);

                        return imageFileName;
                }
            }
            catch (System.IO.IOException)
            {
                throw; //these are informative on their own
            }
            catch (Exception error)
            {
                if (!string.IsNullOrEmpty(imageInfo.FileName) && File.Exists(imageInfo.OriginalFilePath))
                {
                    var megs = new System.IO.FileInfo(imageInfo.OriginalFilePath).Length / (1024 * 1000);
                    if (megs > 2)
                    {
                        var msg = string.Format("Bloom was not able to prepare that picture for including in the book. \r\nThis is a rather large image to be adding to a book --{0} Megs--.", megs);
                        if(isJpeg)
                        {
                            msg += "\r\nNote, this file is a jpeg, which is normally used for photographs, not line-drawings (png, tiff, bmp). Bloom can handle smallish jpegs, large ones are difficult to handle, especialy if memory is limitted.";
                        }
                        throw new ApplicationException(msg, error);
                    }
                }

                throw new ApplicationException("Bloom was not able to prepare that picture for including in the book. Is it too large, or an odd format?\r\n" + imageInfo.FileName, error);
            }
        }
Ejemplo n.º 7
0
        private void MakeSimplePdf(string inputHtmlPath, string outputPdfPath, string paperSizeName, bool landscape, DoWorkEventArgs doWorkEventArgs)
        {
            var customSizes = new Dictionary<string, string>();
            customSizes.Add("Halfletter", "--page-width 8.5 --page-height 5.5");
            string pageSizeArguments;
            if(!customSizes.TryGetValue(paperSizeName, out pageSizeArguments))
            {
                pageSizeArguments = "--page-size " + paperSizeName; ; //this works too " --page-width 14.8cm --page-height 21cm"
            }

            //wkhtmltopdf chokes on stuff like chinese file names, even if we put the console code page to UTF 8 first (CHCP 65001)
            //so now, we just deal in temp files
            using(var tempInput = TempFile.WithExtension(".htm"))
            {
                File.Delete(tempInput.Path);
                var source = File.ReadAllText(inputHtmlPath);
                //hide all placeholders

                File.WriteAllText(tempInput.Path, source.Replace("placeholder.png", "").Replace("placeHolder.png", ""));
                //File.Copy(inputHtmlPath, tempInput.Path);
                var tempOutput = TempFile.WithExtension(".pdf"); //we don't want to dispose of this
                File.Delete(tempOutput.Path);

                /*--------------------------------DEVELOPERS -----------------------------
                 *
                 *	Are you trying to debug a disparity between the HTML preview and
                 *	the PDF output, which should be identical? Some notes:
                 *
                 * 1) Wkhtmltopdf requires different handling of file names for the local
                 * file system than firefox. So if you open this html, do so in Chrome
                 * instead of Firefox.
                 *
                 * 2) Wkhtmltopdf violates the HTML requirement that classes are case
                 * sensitive. So it could be that it is using a rule you forgot you
                 * had, and which is not being triggered by the better browsers.
                 *
                 */
                string exePath = FindWkhtmlToPdf();

                var arguments = string.Format(
                    "--no-background " +
                    //without this, we get a thin line on the right side, which turned into a line in the middle when made into a booklet. You could only see it on paper or by zooming in.
                    " --print-media-type " +
                    pageSizeArguments +
                    (landscape ? " -O Landscape " : "") +
            #if DEBUG
                    " --debug-javascript " +
            #endif

                    "  --margin-bottom 0mm  --margin-top 0mm  --margin-left 0mm  --margin-right 0mm " +
                    "--disable-smart-shrinking --zoom {0} \"{1}\" \"{2}\"",
                    GetZoomBasedOnScreenDPISettings().ToString(),
                    Path.GetFileName(tempInput.Path), tempOutput.Path);

                ExecutionResult result = null;
                using (var dlg = new ProgressDialogBackground())
                {

                    /* This isn't really working yet (Aug 2012)... I put a day's work into getting Palaso.CommandLineRunner to
                     * do asynchronous reading of the
                     * nice progress that wkhtml2pdf puts out, and feeding it to the UI. It worked find with a sample utility
                     * (PalasoUIWindowsForms.TestApp.exe). But try as I might, it seems
                     * that the Process doesn't actually deliver wkhtml2pdf's outputs to me until it's all over.
                     * If I run wkhtml2pdf from a console, it gives the progress just fine, as it works.
                     * So there is either a bug in Palaso.CommandLineRunner & friends, or.... ?
                     */

                    //this proves that the ui part here is working... it's something about the wkhtml2pdf that we're not getting the updates in real time...
                    //		dlg.ShowAndDoWork(progress => result = CommandLineRunner.Run("PalasoUIWindowsForms.TestApp.exe", "CommandLineRunnerTest", null, string.Empty, 60, progress
                    dlg.ShowAndDoWork((progress,args) =>
                                        {
                                            progress.WriteStatus("Making PDF...");
                                            //this is a trick... since we are so far failing to get
                                            //the progress out of wkhtml2pdf until it is done,
                                            //we at least have this indicator which on win 7 does
                                            //grow from 0 to the set percentage with some animation

                                            //nb: Later, on a 100page doc, I did get good progress at the end
                                            progress.ProgressIndicator.PercentCompleted = 70;
                                            result = CommandLineRunner.Run(exePath, arguments, null, Path.GetDirectoryName(tempInput.Path),
                                                                           5*60, progress
                                                                           , (s) =>
                                                                                {
                                                                                    progress.WriteStatus(s);

                                                                                    try
                                                                                    {
                                                                                        //this will hopefully avoid the exception below (which we'll swallow anyhow)
                                                                                        if (((BackgroundWorker) args.Argument).IsBusy)
                                                                                        {
                                                                                            //this wakes up the dialog, which then calls the Refresh() we need
                                                                                            try
                                                                                            {
                                                                                                ((BackgroundWorker)args.Argument).ReportProgress(100);
                                                                                            }
                                                                                            catch (Exception)
                                                                                            {
                                                                                                //else swallow; we've gotten this error:
                                                                                                //"This operation has already had OperationCompleted called on it and further calls are illegal"
                                                                                                #if DEBUG
                                                                                                throw;
                                                                                                #endif
                                                                                            }
                                                                                        }
                                                                                        else
                                                                                        {
                                                                                            #if DEBUG
                                                                                            Debug.Fail("Wanna look into this? Why is the process still reporting back?");
                                                                                            #endif
                                                                                        }
                                                                                    }
                                                                                    catch (Exception)
                                                                                    {
            #if DEBUG
                                                                                        throw;
            #endif
                                                                                        //swallow an complaints about it already being completed (bl-233)
                                                                                    }
                                                                                });
                                        });
                }

                //var progress = new CancellableNullProgress(doWorkEventArgs);

                Debug.WriteLine(result.StandardError);
                Debug.WriteLine(result.StandardOutput);

                if (!File.Exists(tempOutput.Path))
                    throw new ApplicationException("Bloom was not able to create the PDF.\r\n\r\nDetails: Wkhtml2pdf did not produce the expected document.");

                try
                {
                    File.Move(tempOutput.Path, outputPdfPath);
                }
                catch (IOException e)
                {
                    //I can't figure out how it happened (since GetPdfPath makes sure the file name is unique),
                    //but we had a report (BL-211) of that move failing.
                    throw new ApplicationException(
                            string.Format("Bloom tried to save the file to {0}, but Windows said that it was locked. Please try again.\r\n\r\nDetails: {1}",
                                          outputPdfPath, e.Message));

                }

            }
        }
Ejemplo n.º 8
0
        public void AttemptMissingImageReplacements(string pathToFolderOfReplacementImages=null)
        {
            using (var dlg = new ProgressDialogBackground())
            {
                dlg.ShowAndDoWork((progress, args) => DoChecksOfAllBooksBackgroundWork(dlg, pathToFolderOfReplacementImages));
                if (dlg.Progress.ErrorEncountered || dlg.Progress.WarningsEncountered)
                {
                    MessageBox.Show("There were some problems. Bloom will now open a log of the attempt to replace missing images.");
                }
                else
                {
                    MessageBox.Show("There are no more missing images. Bloom will now open a log of what it did.");
                }

                var path = Path.GetTempFileName() + ".txt";
                RobustFile.WriteAllText(path, dlg.ProgressString.Text);
                try
                {
                    PathUtilities.OpenFileInApplication(path);
                }
                catch (System.OutOfMemoryException)
                {
                    // This has happened at least once.  See https://silbloom.myjetbrains.com/youtrack/issue/BL-3431.
                    MessageBox.Show("Bloom ran out of memory trying to open the log.  You should quit and restart the program.  (Your books should all be okay.)");
                }
            }
        }