This is an automated email from the git hooks/post-receive script. New commit to branch feature/9928_Ordre_incorrect_impression in repository faxtomail. See https://gitlab.nuiton.org/codelutin/faxtomail.git commit c32f7e228562459bac91dbe20534c57c250509f2 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Wed Jun 6 16:57:47 2018 +0200 refs #9928 : Ordre incorrect lors de l'impression --- .../swing/actions/PrintOnDefaultPrinterAction.java | 32 ++- .../content/pdfeditor/PDFEditorUIHandler.java | 2 +- .../faxtomail/ui/swing/util/FaxToMailUIUtil.java | 291 ++++++++++++--------- .../i18n/faxtomail-ui-swing_fr_FR.properties | 2 + 4 files changed, 194 insertions(+), 133 deletions(-) diff --git a/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/actions/PrintOnDefaultPrinterAction.java b/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/actions/PrintOnDefaultPrinterAction.java index 1b54343d..1926d430 100644 --- a/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/actions/PrintOnDefaultPrinterAction.java +++ b/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/actions/PrintOnDefaultPrinterAction.java @@ -34,10 +34,13 @@ import com.franciaflex.faxtomail.services.service.EmailService; import com.franciaflex.faxtomail.ui.swing.content.demande.DemandeUIModel; import com.franciaflex.faxtomail.ui.swing.util.AbstractFaxToMailUIHandler; import com.franciaflex.faxtomail.ui.swing.util.FaxToMailUIUtil; +import com.google.common.base.Function; import com.google.common.base.Strings; import com.google.common.collect.HashMultimap; +import com.google.common.collect.Lists; import com.google.common.collect.Multimap; +import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -77,7 +80,7 @@ public class PrintOnDefaultPrinterAction extends AbstractFaxToMailAction { @Override public void doAction() throws Exception { FaxToMailUser currentUser = getContext().getCurrentUser(); - AbstractFaxToMailUIHandler handler = (AbstractFaxToMailUIHandler) getHandler(); + final AbstractFaxToMailUIHandler handler = (AbstractFaxToMailUIHandler) getHandler(); int printedFileNb = 0; Multimap<DemandeUIModel, AttachmentFile> nonPrintedAttachment = HashMultimap.create(); @@ -96,6 +99,8 @@ public class PrintOnDefaultPrinterAction extends AbstractFaxToMailAction { FaxToMailServiceContext serviceContext = getContext().newServiceContext(); EmailService emailService = serviceContext.getEmailService(); + List<File> filesToPrint = Lists.newArrayList(); + for (DemandeUIModel demandeUIModel : orderedDemands) { if(!handler.isActionEnabled(demandeUIModel, MailAction.PRINT)) { @@ -116,20 +121,15 @@ public class PrintOnDefaultPrinterAction extends AbstractFaxToMailAction { Email email = demandeUIModel.toEntity(); final AttachmentFile demandDetailAttachment = emailService.getEmailDetailAsAttachment(email); // print details - if (FaxToMailUIUtil.print(demandDetailAttachment, true, getContext().getConfig())) { - printedFiles.add(demandDetailAttachment.getFilename()); - - } else { - nonPrintedAttachment.put(demandeUIModel, demandDetailAttachment); - } + filesToPrint.add(FaxToMailUIUtil.preparePrint(demandDetailAttachment)); + printedFiles.add(demandDetailAttachment.getFilename()); } for (AttachmentFile attachmentFile : attachmentsToPrintByDemand.get(demandeUIModel)) { if (attachmentFile != null) { - boolean printable = FaxToMailUIUtil.isFileTypeEditable(attachmentFile.getFilename()); - if (printable && FaxToMailUIUtil.print(attachmentFile, true, getContext().getConfig())) { + if (FaxToMailUIUtil.isFileTypeEditable(attachmentFile.getFilename())) { + filesToPrint.add(FaxToMailUIUtil.preparePrint(attachmentFile)); printedFiles.add(attachmentFile.getFilename()); - } else { nonPrintedAttachment.put(demandeUIModel, attachmentFile); } @@ -151,10 +151,18 @@ public class PrintOnDefaultPrinterAction extends AbstractFaxToMailAction { // print another page for non printed attachments if (!nonPrintedAttachment.isEmpty()) { String errorPageContent = generateErrorPageStream(nonPrintedAttachment); - FaxToMailUIUtil.printText("nonprintedattachement", errorPageContent, true, getContext().getConfig()); + filesToPrint.add(FaxToMailUIUtil.preparePrintText(errorPageContent)); } - handler.showInformationMessage(t("faxtomail.print.success.message", printedFileNb)); + FaxToMailUIUtil.printWithPdfRenderer(t("faxtomail.print.jobName"), filesToPrint, true, getContext().getConfig(), new Function<Integer, Void>() { + @Override + public Void apply(Integer input) { + handler.showInformationMessage(t("faxtomail.print.success.message", input)); + return null; + } + }); + handler.showInformationMessage(t("faxtomail.print.inProgress.message")); + } @Override diff --git a/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/pdfeditor/PDFEditorUIHandler.java b/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/pdfeditor/PDFEditorUIHandler.java index 74b1c506..b2ced43a 100644 --- a/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/pdfeditor/PDFEditorUIHandler.java +++ b/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/content/pdfeditor/PDFEditorUIHandler.java @@ -723,7 +723,7 @@ public class PDFEditorUIHandler extends AbstractFaxToMailUIHandler<PDFEditorUIMo public void print() { PDFEditorUIModel model = getModel(); AttachmentFile attachmentFile = model.getNotNullFile(); - boolean print = FaxToMailUIUtil.print(attachmentFile, false, getContext().getConfig()); + boolean print = FaxToMailUIUtil.print(attachmentFile, false, getContext().getConfig(), null); // TODO kmorin 20140702 à mettre dans une action ou avec un loading ou qqchose // j'ai essayé une action vite fait mais ca ferme l'éditeur à la fin de l'action diff --git a/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/util/FaxToMailUIUtil.java b/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/util/FaxToMailUIUtil.java index 671826eb..7e2bc380 100644 --- a/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/util/FaxToMailUIUtil.java +++ b/faxtomail-ui-swing/src/main/java/com/franciaflex/faxtomail/ui/swing/util/FaxToMailUIUtil.java @@ -123,8 +123,10 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutionException; import java.util.regex.Pattern; import static org.nuiton.i18n.I18n.t; @@ -438,60 +440,71 @@ public final class FaxToMailUIUtil extends ApplicationUIUtil { * @param defaultPrinter if {@code true}, do not display print dialog and print with default printer * @return true if file has been printed, false otherwise */ - public static boolean print(AttachmentFile attachmentFile, boolean defaultPrinter, FaxToMailConfiguration config) { - boolean result; + public static boolean print(AttachmentFile attachmentFile, boolean defaultPrinter, FaxToMailConfiguration config, Function<Integer, Void> callBack) { + + File file = preparePrint(attachmentFile); + + return printWithPdfRenderer(attachmentFile.getFilename(), Collections.singletonList(file), defaultPrinter, config, callBack); + } + + /** + * preparation de l'impression d'un attachment file. + * + * @param attachmentFile + * @return File to print + */ + public static File preparePrint(AttachmentFile attachmentFile) { + File file; try { - File file; if (!FaxToMailUIUtil.isFileAPDF(attachmentFile)) { file = convertFileToPdf(attachmentFile); } else { - file = attachmentFile.getFile(); + file = File.createTempFile("faxtomail-", ".tmp"); + FileUtils.copyFile(attachmentFile.getFile(), file); } - result = printWithPdfRenderer(attachmentFile.getFilename(), file, defaultPrinter, config); - } catch (IOException | DocumentException e) { throw new ApplicationTechnicalException( t("jaxx.application.error.cannot.print"), e); } - return result; + return file; } /** * Imprime du texte. * - * @param printName print job name * @param text text to print - * @param defaultPrinter if {@code true}, do not display print dialog and print with default printer - * @return true if file has been printed, false otherwise - */ - public static void printText(String printName, String text, boolean defaultPrinter, FaxToMailConfiguration config) { + * @return File to print + **/ + public static File preparePrintText(String text) { // convert text content to inputstream byte[] content = text.getBytes(StandardCharsets.UTF_8); + File file; try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(content)){ - File file = convertFileToPdf(byteArrayInputStream, FileType.TEXT); - - printWithPdfRenderer(printName, file, defaultPrinter, config); + file = convertFileToPdf(byteArrayInputStream, FileType.TEXT); } catch (IOException | DocumentException e) { throw new ApplicationTechnicalException( t("jaxx.application.error.cannot.print"), e); } + return file; } /** * Imprime un attachment file. * * @param printName print job name - * @param file file to print + * @param files files to print * @param defaultPrinter if {@code true}, do not display print dialog and print with default printer * @return true if file has been printed, false otherwise */ - protected static boolean printWithPdfRenderer(final String printName, final File file, - final boolean defaultPrinter, - final FaxToMailConfiguration config) { + public static boolean printWithPdfRenderer(final String printName, + final List<File> files, + final boolean defaultPrinter, + final FaxToMailConfiguration config, + final Function<Integer, Void> callBack) { final PrinterJob printJob = PrinterJob.getPrinterJob(); printJob.setJobName(printName); @@ -500,120 +513,158 @@ public final class FaxToMailUIUtil extends ApplicationUIUtil { final PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet(); final boolean result = defaultPrinter || printJob.printDialog(attributes); - //Use SwingWorker so that printing does not block UI (cf. #9786) - SwingWorker worker = new SwingWorker<Void, Void>() { - @Override - public Void doInBackground() { - - if (result) { - try (FileInputStream fis = new FileInputStream(file)) { - try (PDDocument pdDocument = PDDocument.load(fis)) { - - final PDFRenderer renderer = new PDFRenderer(pdDocument); - final int numOfPages = pdDocument.getNumberOfPages(); - - printJob.setPrintable(new Printable() { - public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) { - try { - if (pageIndex >= numOfPages) { - return NO_SUCH_PAGE; - } - - //get back margin - int marginMillimeter = config.getDefaultPrintMargin(); - - //Init pageFormat with margin from conf (do not use default params) - Paper paper = pageFormat.getPaper(); - double margin = marginMillimeter * 2.83465; // convert millimeters to points - paper.setImageableArea(margin, margin, paper.getWidth() - margin * 2, paper.getHeight() - - margin * 2); - pageFormat.setPaper(paper); - - double paperWidth = (int) pageFormat.getImageableWidth(); - double paperHeight = (int) pageFormat.getImageableHeight(); - int paperX = (int) pageFormat.getImageableX(); - int paperY = (int) pageFormat.getImageableY(); - - if (log.isDebugEnabled()) { - log.debug("page width " + paperWidth); - log.debug("page height " + paperHeight); - log.debug("page x " + paperX); - log.debug("page y " + paperY); - } - - BufferedImage image = renderer.renderImageWithDPI(pageIndex, 300); - - int imageWidth = image.getWidth(); - int imageHeight = image.getHeight(); - double widthRatio = paperWidth / imageWidth; - double heightRatio = paperHeight / imageHeight; - - if (log.isDebugEnabled()) { - log.debug("width ratio : " + widthRatio); - log.debug("height ratio : " + heightRatio); - } - - int width; - int height; - // if the image is smaller than the page - if (widthRatio >= 1 && heightRatio >= 1) { - width = imageWidth; - height = imageHeight; - - } else { - double minRatio = Math.min(widthRatio, heightRatio); - width = (int) (minRatio * imageWidth); - height = (int) (minRatio * imageHeight); - } - - if (log.isDebugEnabled()) { - log.debug("image width : " + width); - log.debug("image height : " + height); - } - - //use full size - graphics.setClip(paperX, paperY, width, height); - graphics.drawImage(image, paperX, paperY, width, height, null); - - return PAGE_EXISTS; - - } catch (Exception e) { - if (log.isErrorEnabled()) { - log.error("error while printing", e); - } - return NO_SUCH_PAGE; - } - } - }); + if (result) { - printJob.print(attributes); - } catch (PrinterException ex) { - if (log.isErrorEnabled()) { - log.error("can't print", ex); - } + //Use SwingWorker so that printing does not block UI (cf. #9786) + + SwingWorker worker = new SwingWorker<Integer, Void>() { + @Override + public Integer doInBackground() { + + FilesPrintable filesPrintable = new FilesPrintable(files, config.getDefaultPrintMargin()); + printJob.setPrintable(filesPrintable); + + try { + + printJob.print(attributes); + + } catch (PrinterException ex) { + if (log.isErrorEnabled()) { + log.error("can't print", ex); + } + } - } catch (IOException e) { + if (log.isInfoEnabled()) { + log.info(filesPrintable.getCountPages() + " fichiers ont été imprimés"); + } + + return filesPrintable.getCountPages(); + } + + @Override + protected void done() { + super.done(); + if (callBack != null) { + Integer countPages = 0; + try { + countPages = get(); + } catch (InterruptedException | ExecutionException e) { if (log.isErrorEnabled()) { - log.error("", e); + log.error("Error on finish print", e); } } - } catch (IOException e) { - if (log.isErrorEnabled()) { - log.error("", e); - } + callBack.apply(countPages); } } + }; + worker.execute(); + } - return null; - } + return result; + } - }; + protected static class FilesPrintable implements Printable { - worker.execute(); + protected final Iterator<File> filesToPrint; + protected final int marginMillimeter; - return result; + protected PDFRenderer currentRenderer; + protected PDDocument pdDocument; + protected int countPages; + protected int pageIndexFile; + + public FilesPrintable(Iterable<File> filesToPrint, int marginMillimeter) { + this.filesToPrint = filesToPrint.iterator(); + this.marginMillimeter = marginMillimeter; + this.countPages = 0; + this.pageIndexFile = 0; + } + + public int getCountPages() { + return countPages; + } + + @Override + public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { + try { + if (pageIndex >= countPages) { + IOUtils.closeQuietly(pdDocument); + if (filesToPrint.hasNext()) { + pdDocument = PDDocument.load(filesToPrint.next()); + currentRenderer = new PDFRenderer(pdDocument); + pageIndexFile = countPages; + countPages += pdDocument.getNumberOfPages(); + } else { + return Printable.NO_SUCH_PAGE; + } + } + + //Init pageFormat with margin from conf (do not use default params) + Paper paper = pageFormat.getPaper(); + double margin = marginMillimeter * 2.83465; // convert millimeters to points + paper.setImageableArea(margin, margin, paper.getWidth() - margin * 2, paper.getHeight() + - margin * 2); + pageFormat.setPaper(paper); + + double paperWidth = (int) pageFormat.getImageableWidth(); + double paperHeight = (int) pageFormat.getImageableHeight(); + int paperX = (int) pageFormat.getImageableX(); + int paperY = (int) pageFormat.getImageableY(); + + if (log.isDebugEnabled()) { + log.debug("page width " + paperWidth); + log.debug("page height " + paperHeight); + log.debug("page x " + paperX); + log.debug("page y " + paperY); + } + + BufferedImage image = currentRenderer.renderImageWithDPI(pageIndex - pageIndexFile, 300); + + int imageWidth = image.getWidth(); + int imageHeight = image.getHeight(); + double widthRatio = paperWidth / imageWidth; + double heightRatio = paperHeight / imageHeight; + + if (log.isDebugEnabled()) { + log.debug("width ratio : " + widthRatio); + log.debug("height ratio : " + heightRatio); + } + + int width; + int height; + // if the image is smaller than the page + if (widthRatio >= 1 && heightRatio >= 1) { + width = imageWidth; + height = imageHeight; + + } else { + double minRatio = Math.min(widthRatio, heightRatio); + width = (int) (minRatio * imageWidth); + height = (int) (minRatio * imageHeight); + } + + if (log.isDebugEnabled()) { + log.debug("image width : " + width); + log.debug("image height : " + height); + } + + //use full size + graphics.setClip(paperX, paperY, width, height); + graphics.drawImage(image, paperX, paperY, width, height, null); + + return Printable.PAGE_EXISTS; + + } catch (Exception e) { + if (log.isErrorEnabled()) { + log.error("error while printing", e); + } + IOUtils.closeQuietly(pdDocument); + throw new PrinterException("Error while printing : " + e.getMessage()); + } + } } + public static File convertFileToPdf(AttachmentFile attachmentFile) throws IOException, DocumentException { File file = attachmentFile.getFile(); FileType type; diff --git a/faxtomail-ui-swing/src/main/resources/i18n/faxtomail-ui-swing_fr_FR.properties b/faxtomail-ui-swing/src/main/resources/i18n/faxtomail-ui-swing_fr_FR.properties index 17b9ef35..138bfb71 100644 --- a/faxtomail-ui-swing/src/main/resources/i18n/faxtomail-ui-swing_fr_FR.properties +++ b/faxtomail-ui-swing/src/main/resources/i18n/faxtomail-ui-swing_fr_FR.properties @@ -278,6 +278,8 @@ faxtomail.pdfEditor.button.zoomIn=Agrandir faxtomail.pdfEditor.button.zoomOut=Réduire faxtomail.pdfEditor.convertToPdf.error=Erreur lors de la conversion en PDF faxtomail.pdfEditor.readPdf.error=Erreur lors de la lecture du PDF +faxtomail.print.inProgress.message=Impression en cours ... +faxtomail.print.jobName=Demandes faxtomail.print.success.message=%s fichiers ont été imprimés faxtomail.quantitiesByRange.button.text=OK faxtomail.quantitiesByRange.title=Quantités par gamme -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.