diff --git a/org.adempiere.base.process/src/org/idempiere/process/ImportCSVProcess.java b/org.adempiere.base.process/src/org/idempiere/process/ImportCSVProcess.java index 2ca4b50fc4..265a979d5f 100644 --- a/org.adempiere.base.process/src/org/idempiere/process/ImportCSVProcess.java +++ b/org.adempiere.base.process/src/org/idempiere/process/ImportCSVProcess.java @@ -150,10 +150,8 @@ protected void importFile(String filePath, IGridTabImporter csvImporter, GridTab File outFile = csvImporter.fileImport(activeTab, childTabs, m_file_istream, Charset.forName(m_importTemplate.getCharacterSet()), p_ImportMode, processUI); // TODO: Potential improvement - traverse the outFile and call addLog with the results - if (processUI != null) - processUI.download(outFile); - else if( getProcessInfo() != null ){ - ProcessInfo m_pi = getProcessInfo(); + ProcessInfo m_pi = getProcessInfo(); + if( m_pi != null ){ m_pi.setExport(true); m_pi.setExportFile(outFile); m_pi.setExportFileExtension("csv"); diff --git a/org.adempiere.base/src/org/adempiere/util/IProcessUI.java b/org.adempiere.base/src/org/adempiere/util/IProcessUI.java index b6c0d38084..195f0f2dc2 100644 --- a/org.adempiere.base/src/org/adempiere/util/IProcessUI.java +++ b/org.adempiere.base/src/org/adempiere/util/IProcessUI.java @@ -116,8 +116,11 @@ default public void askForInput(String message, MLookup lookup, int displayType, } /** - * add to list of file available for download after process end + * Add to list of file available for download after process end
+ * While this API is limited to processes with user interfaces, consider using {@link SvrProcess#addDownloadFile(File)} for broader support,
+ * as it move downloadFiles from {@link AbstractProcessDialog#downloadFiles} to {@link ProcessInfo#downloadFiles} * @param file + * @deprecated (since="12", forRemoval = true) */ public void download(File file); diff --git a/org.adempiere.base/src/org/compiere/model/MSysConfig.java b/org.adempiere.base/src/org/compiere/model/MSysConfig.java index 4b3277f1e2..dcc92840f5 100644 --- a/org.adempiere.base/src/org/compiere/model/MSysConfig.java +++ b/org.adempiere.base/src/org/compiere/model/MSysConfig.java @@ -172,6 +172,7 @@ public class MSysConfig extends X_AD_SysConfig public static final String PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CREDIT_CARD = "PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CREDIT_CARD"; public static final String PAYMENT_SELECTION_MANUAL_ASK_INVOKE_GENERATE = "PAYMENT_SELECTION_MANUAL_ASK_INVOKE_GENERATE"; public static final String PDF_FONT_DIR = "PDF_FONT_DIR"; + public static final String PROCESS_SHOW_SEPARATE_DOWNLOAD_DIALOG = "PROCESS_SHOW_SEPARATE_DOWNLOAD_DIALOG"; public static final String ProductUOMConversionRateValidate = "ProductUOMConversionRateValidate"; public static final String ProductUOMConversionUOMValidate = "ProductUOMConversionUOMValidate"; public static final String PROJECT_ID_PASSWORD = "PROJECT_ID_PASSWORD"; diff --git a/org.adempiere.base/src/org/compiere/process/ProcessInfo.java b/org.adempiere.base/src/org/compiere/process/ProcessInfo.java index e8ed29e9ba..fde0c219d8 100644 --- a/org.adempiere.base/src/org/compiere/process/ProcessInfo.java +++ b/org.adempiere.base/src/org/compiere/process/ProcessInfo.java @@ -192,9 +192,30 @@ public ProcessInfo (String Title, int AD_Process_ID) private String showHelp = null; private int m_AD_Scheduler_ID = 0; + /** + * Files for download by user
+ * The file path for download is also stored in the {@link ProcessInfoLog#m_P_Msg} with the {@link ProcessInfoLog#getPInstanceLogType} set to {@link X_AD_PInstance_Log#PINSTANCELOGTYPE_FilePath} + **/ + private List downloadFiles = new ArrayList<>(); /** For scheduler: true to notify scheduler recipients with process execution result using AD_Scheduler.R_MailTexT_ID mail template (if define). Default is true. **/ private boolean isNotifyRecipients = true; + + /** + * @return list of files for user download + */ + public List getDownloadFiles() + { + return downloadFiles; + } + /** + * add to list of file available for download after process end + * @param file + */ + public void addDownloadFiles(File file) + { + downloadFiles.add(file); + } public int getLanguageID() { return languageID; diff --git a/org.adempiere.base/src/org/idempiere/process/TranslationImpExp.java b/org.adempiere.base/src/org/idempiere/process/TranslationImpExp.java index 0536653bfe..fe7c910fb3 100644 --- a/org.adempiere.base/src/org/idempiere/process/TranslationImpExp.java +++ b/org.adempiere.base/src/org/idempiere/process/TranslationImpExp.java @@ -185,7 +185,7 @@ protected String doIt() throws Exception { zipper.setProject(new Project()); zipper.setOwningTarget(new Target()); zipper.execute(); - processUI.download(destZipFile); + getProcessInfo().addDownloadFiles(destZipFile); } } finally { // Cleanup when temp folder diff --git a/org.adempiere.pipo/src/org/adempiere/pipo2/PackOutProcess.java b/org.adempiere.pipo/src/org/adempiere/pipo2/PackOutProcess.java index 965c901c1f..7e6cc6f032 100644 --- a/org.adempiere.pipo/src/org/adempiere/pipo2/PackOutProcess.java +++ b/org.adempiere.pipo/src/org/adempiere/pipo2/PackOutProcess.java @@ -149,8 +149,7 @@ protected String doIt() throws java.lang.Exception throw e; } - if (processUI != null) - processUI.download(new File(exportFile)); + getProcessInfo().addDownloadFiles(new File(exportFile)); return "Exported="+processedCount + " File=" + exportFile; } // doIt diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java index 13dd8c1929..9ee71e7687 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java @@ -4359,7 +4359,7 @@ private void updateUI(ProcessInfo pi) { } - if (m_logs != null && m_logs.length > 0) { + if ((m_logs != null && m_logs.length > 0) || pi.getDownloadFiles().size() > 0) { ProcessInfoDialog dialog = ProcessInfoDialog.showProcessInfo(pi, curWindowNo, getComponent(), false); dialog.addEventListener(DialogEvents.ON_WINDOW_CLOSE, e -> focusToActivePanel()); } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java index 3f0c40b0a3..e7bacf13d5 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java @@ -31,12 +31,14 @@ import java.util.Properties; import java.util.logging.Level; +import javax.activation.MimetypesFileTypeMap; import javax.servlet.ServletRequest; import org.adempiere.webui.ClientInfo; import org.adempiere.webui.ISupportMask; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.adwindow.ADWindow; +import org.adempiere.webui.component.DynamicMediaLink; import org.adempiere.webui.component.Mask; import org.adempiere.webui.component.Window; import org.adempiere.webui.desktop.IDesktop; @@ -74,6 +76,7 @@ import org.compiere.util.Ini; import org.compiere.util.Language; import org.compiere.util.Util; +import org.zkoss.util.media.AMedia; import org.zkoss.web.servlet.Servlets; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Desktop; @@ -81,7 +84,9 @@ import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zul.A; import org.zkoss.zul.Button; +import org.zkoss.zul.Vlayout; import org.zkoss.zul.impl.InputElement; import com.lowagie.text.DocumentException; @@ -993,4 +998,33 @@ public static void detachInputElement(Component parent) { } } } + + /** + * Construct a panel that includes links for downloading files, and attach this panel to the parent component.
+ * In case of error show error message on link text + * @param files + * @param parent + */ + public static void appendDownloadLinkForFiles(File [] files, Component parent) { + if (files.length == 0) + return; + + // append link for download file + Vlayout fileDownloadPanel = new Vlayout(); + fileDownloadPanel.setStyle("padding-top: 10px; padding-bottom: 10px;"); + parent.appendChild(fileDownloadPanel); + for (File downloadFile : files) { + A downloadLink = null; + try { + AMedia media = new AMedia(downloadFile, MimetypesFileTypeMap.getDefaultFileTypeMap().getContentType(downloadFile), null); + downloadLink = new DynamicMediaLink(); + ((DynamicMediaLink)downloadLink).setMedia(media); + downloadLink.setStyle("margin: 5px;"); + downloadLink.setLabel(media.getName()); + } catch (FileNotFoundException e) { + downloadLink = new A(e.getMessage()); + } + fileDownloadPanel.appendChild(downloadLink); + } + } } // AEnv diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AbstractProcessDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AbstractProcessDialog.java index eb388180f6..10010f26b9 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AbstractProcessDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AbstractProcessDialog.java @@ -16,7 +16,6 @@ import java.io.File; import java.io.FileInputStream; -import java.util.ArrayList; import java.util.List; import java.util.Properties; import java.util.concurrent.Future; @@ -51,7 +50,6 @@ import org.adempiere.webui.util.ZKUpdateUtil; import org.adempiere.webui.util.ZkContextRunnable; import org.adempiere.webui.window.Dialog; -import org.adempiere.webui.window.MultiFileDownloadDialog; import org.adempiere.webui.window.SimplePDFViewer; import org.compiere.Adempiere; import org.compiere.model.Lookup; @@ -158,8 +156,6 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI /** Reference to process thread/task **/ private Future future; - /** files for download by user **/ - private List downloadFiles; /** true when UI have been locked, i.e busy **/ private boolean m_locked = false; private String m_AD_Process_UU = ""; @@ -1036,8 +1032,6 @@ private void startProcess0() getProcessInfo().setPrintPreview(true); lockUI(getProcessInfo()); - - downloadFiles = new ArrayList(); //use echo, otherwise lock ui wouldn't work Clients.response(new AuEcho(this, isBackgroundJob() ? "runBackgroundJob" : "runProcess", this)); @@ -1147,13 +1141,6 @@ private void onComplete() } future = null; unlockUI(m_pi); - if (downloadFiles.size() > 0) { - MultiFileDownloadDialog downloadDialog = new MultiFileDownloadDialog(downloadFiles.toArray(new File[0])); - downloadDialog.setPage(getPage()); - downloadDialog.setTitle(m_pi.getTitle()); - Events.postEvent(downloadDialog, new Event(MultiFileDownloadDialog.ON_SHOW)); - } - if (m_disposeOnComplete) dispose(); } @@ -1252,9 +1239,13 @@ public void onEvent(Event event) throws Exception { }, new Event("onAsk")); } + /** + * {@inheritDoc} + * @deprecated (since="12", forRemoval = true) + */ @Override public void download(File file) { - downloadFiles.add(file); + m_pi.addDownloadFiles(file); } /** @@ -1359,14 +1350,6 @@ public String getNotificationType() return (String) notificationTypeField.getValue(); } - /** - * @return list of files for user download - */ - public List getDownloadFiles() - { - return downloadFiles; - } - /** * Runnable to run process in background thread. * Notify process dialog with {@link AbstractProcessDialog#ON_COMPLETE_EVENT} event. @@ -1474,17 +1457,17 @@ else if ("XLSX".equals(m_pi.getReportType())) boolean isReport = (process.isReport() || process.getAD_ReportView_ID() > 0 || process.getJasperReport() != null || process.getAD_PrintFormat_ID() > 0); if (isReport && m_pi.getPDFReport() != null) { - download(m_pi.getPDFReport()); + m_pi.addDownloadFiles(m_pi.getPDFReport()); } if (m_pi.isExport() && m_pi.getExportFile() != null) - download(m_pi.getExportFile()); + m_pi.addDownloadFiles(m_pi.getExportFile()); } if (sendEmail) { MClient client = MClient.get(m_ctx, AD_Client_ID); - client.sendEMailAttachments(AD_User_ID, process.get_Translation("Name", Env.getAD_Language(Env.getCtx())), m_pi.getSummary() + " " + m_pi.getLogInfo(), getDownloadFiles()); + client.sendEMailAttachments(AD_User_ID, process.get_Translation("Name", Env.getAD_Language(Env.getCtx())), m_pi.getSummary() + " " + m_pi.getLogInfo(), m_pi.getDownloadFiles()); } if (createNotice) @@ -1495,10 +1478,10 @@ else if ("XLSX".equals(m_pi.getReportType())) note.saveEx(); MAttachment attachment = null; - if (getDownloadFiles().size() > 0) + if (m_pi.getDownloadFiles().size() > 0) { attachment = note.createAttachment(); - for (File downloadFile : getDownloadFiles()) + for (File downloadFile : m_pi.getDownloadFiles()) attachment.addEntry(downloadFile); } String log = m_pi.getLogInfo(true); @@ -1617,4 +1600,5 @@ public void focus() { if (bOK != null) bOK.focus(); } + } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessDialog.java index c2815c8658..909d3fe41b 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessDialog.java @@ -41,6 +41,7 @@ import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.adempiere.webui.window.Dialog; +import org.adempiere.webui.window.MultiFileDownloadDialog; import org.adempiere.webui.window.SimplePDFViewer; import org.compiere.model.MProcess; import org.compiere.model.MSysConfig; @@ -524,6 +525,17 @@ private void appendRecordLogInfo(ProcessInfoLog[] m_logs, HtmlBasedComponent inf tr.appendChild(td); } } + + if (MSysConfig.getBooleanValue(MSysConfig.PROCESS_SHOW_SEPARATE_DOWNLOAD_DIALOG, true)) { + if (getProcessInfo().getDownloadFiles().size() > 0 ){ + MultiFileDownloadDialog downloadDialog = new MultiFileDownloadDialog(getProcessInfo().getDownloadFiles().toArray(new File[0])); + downloadDialog.setPage(getPage()); + downloadDialog.setTitle(getProcessInfo().getTitle()); + Events.postEvent(downloadDialog, new Event(MultiFileDownloadDialog.ON_SHOW)); + } + }else { + AEnv.appendDownloadLinkForFiles(getProcessInfo().getDownloadFiles().toArray(new File[0]), infoResultContent); + } } /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ProcessInfoDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ProcessInfoDialog.java index 6f8a22d7b9..e2e01a36c2 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ProcessInfoDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ProcessInfoDialog.java @@ -232,6 +232,7 @@ private void init(String title, String header, ProcessInfo pi, ProcessInfoLog[] } } + AEnv.appendDownloadLinkForFiles(pi.getDownloadFiles().toArray(new File[0]), pnlMessage); } @Override diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/MultiFileDownloadDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/MultiFileDownloadDialog.java index a1ddd4bafb..04b1f75666 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/MultiFileDownloadDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/MultiFileDownloadDialog.java @@ -14,21 +14,15 @@ package org.adempiere.webui.window; import java.io.File; -import java.io.FileNotFoundException; -import javax.activation.MimetypesFileTypeMap; - -import org.adempiere.webui.component.DynamicMediaLink; +import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Window; -import org.zkoss.util.media.AMedia; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; -import org.zkoss.zul.Vlayout; /** * Dialog to download multiple files * @author hengsin - * */ public class MultiFileDownloadDialog extends Window { @@ -57,21 +51,7 @@ public void onEvent(Event event) throws Exception { * Show dialog with link for each file */ private void show() { - Vlayout layout = new Vlayout(); - layout.setStyle("padding-top: 10px; padding-bottom: 10px;"); - appendChild(layout); - MimetypesFileTypeMap mimeMap = new MimetypesFileTypeMap(); - for(File file : files) { - try { - AMedia media = new AMedia(file, mimeMap.getContentType(file), null); - DynamicMediaLink link = new DynamicMediaLink(); - layout.appendChild(link); - link.setMedia(media); - link.setLabel(media.getName()); - link.setStyle("margin: 5px;"); - } catch (FileNotFoundException e) { - } - } + AEnv.appendDownloadLinkForFiles(files, this); this.setClosable(true); this.setSizable(true);