IDEMPIERE-5666 - Prevent Closing the Tab of a Running Report (#1778)

* IDEMPIERE-5666 - Prevent Closing the Tab of a Running Report

* IDEMPIERE-5666 - fix javascript error

* IDEMPIERE-5666 - pr1778 patch
This commit is contained in:
Peter Takács 2023-04-14 10:06:07 +02:00 committed by GitHub
parent fdf2f0299c
commit 47891709ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 169 additions and 71 deletions

View File

@ -30,9 +30,11 @@ import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.component.ConfirmPanel;
import org.adempiere.webui.component.DocumentLink;
import org.adempiere.webui.component.Mask;
import org.adempiere.webui.component.Tabpanel;
import org.adempiere.webui.component.Window;
import org.adempiere.webui.desktop.IDesktop;
import org.adempiere.webui.panel.IHelpContext;
import org.adempiere.webui.panel.ITabOnCloseHandler;
import org.adempiere.webui.part.WindowContainer;
import org.adempiere.webui.process.WProcessInfo;
import org.adempiere.webui.session.SessionManager;
@ -69,6 +71,7 @@ import org.zkoss.zul.A;
import org.zkoss.zul.Div;
import org.zkoss.zul.Html;
import org.zkoss.zul.Label;
import org.zkoss.zul.Tab;
import org.zkoss.zul.Vlayout;
import com.lowagie.text.Document;
@ -87,7 +90,7 @@ import com.lowagie.text.pdf.PdfWriter;
* @author arboleda - globalqss
* - Implement ShowHelp option on processes and reports
*/
public class ProcessDialog extends AbstractProcessDialog implements EventListener<Event>, IHelpContext
public class ProcessDialog extends AbstractProcessDialog implements EventListener<Event>, IHelpContext, ITabOnCloseHandler
{
/**
* generated serial id
@ -170,6 +173,11 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
super.onPageAttached(newpage, oldpage);
try {
SessionManager.getSessionApplication().getKeylistener().addEventListener(Events.ON_CTRL_KEY, this);
Component parentTab = this.getParent();
if (parentTab != null && parentTab instanceof Tabpanel) {
((Tabpanel)parentTab).setOnCloseHandler(this);
}
} catch (Exception e) {}
}
@ -779,5 +787,24 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
if(getShowHelp() != null && MProcess.SHOWHELP_RunSilently_TakeDefaults.equals(getShowHelp()))
this.dispose();
}
@Override
public void onClose(Tabpanel tabPanel) {
if(!isUILocked()) {
Tab tab = tabPanel.getLinkedTab();
if (tab != null) {
tab.close();
cleanUp();
}
}
}
private void cleanUp() {
if (m_WindowNo >= 0)
{
SessionManager.getAppDesktop().unregisterWindow(m_WindowNo);
m_WindowNo = -1;
}
}
} // ProcessDialog

View File

@ -20,8 +20,10 @@ import java.util.logging.Level;
import org.adempiere.webui.ClientInfo;
import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.component.Tabpanel;
import org.adempiere.webui.component.Window;
import org.adempiere.webui.event.DialogEvents;
import org.adempiere.webui.panel.ITabOnCloseHandler;
import org.adempiere.webui.util.ZKUpdateUtil;
import org.compiere.model.MPInstance;
import org.compiere.print.MPrintFormat;
@ -30,6 +32,7 @@ import org.compiere.util.CLogger;
import org.compiere.util.Env;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.HtmlBasedComponent;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
@ -45,7 +48,7 @@ import org.zkoss.zk.ui.event.Events;
* @author arboleda - globalqss
* - Implement ShowHelp option on processes and reports
*/
public class ProcessModalDialog extends AbstractProcessDialog implements EventListener<Event>, DialogEvents
public class ProcessModalDialog extends AbstractProcessDialog implements EventListener<Event>, DialogEvents, ITabOnCloseHandler
{
/**
* generated serial id
@ -66,6 +69,10 @@ public class ProcessModalDialog extends AbstractProcessDialog implements EventLi
*/
private String orientation;
private ITabOnCloseHandler originalOnCloseHandler;
private Tabpanel parentTabPanel;
/**
* @param WindowNo
* @param pi
@ -268,7 +275,11 @@ public class ProcessModalDialog extends AbstractProcessDialog implements EventLi
@Override
public void updateUI() {
if (parentTabPanel != null) {
parentTabPanel.setOnCloseHandler(originalOnCloseHandler);
originalOnCloseHandler = null;
parentTabPanel = null;
}
}
@Override
@ -276,6 +287,32 @@ public class ProcessModalDialog extends AbstractProcessDialog implements EventLi
closeBusyDialog();
}
@Override
public void onPageAttached(Page newpage, Page oldpage) {
super.onPageAttached(newpage, oldpage);
Component parent = this.getParent();
while (parent != null) {
if (parent instanceof Tabpanel) {
parentTabPanel = (Tabpanel) parent;
originalOnCloseHandler = parentTabPanel.getOnCloseHandler();
parentTabPanel.setOnCloseHandler(this);
break;
}
parent = parent.getParent();
}
}
@Override
public void onPageDetached(Page page) {
super.onPageDetached(page);
if (parentTabPanel != null && isCancel()) {
parentTabPanel.setOnCloseHandler(originalOnCloseHandler);
originalOnCloseHandler = null;
parentTabPanel = null;
}
}
/**
* handle events
*/
@ -343,4 +380,10 @@ public class ProcessModalDialog extends AbstractProcessDialog implements EventLi
}
}
}
@Override
public void onClose(Tabpanel tabPanel) {
return;
}
} // ProcessModalDialog

View File

@ -115,6 +115,13 @@ public class Tabpanel extends org.zkoss.zul.Tabpanel implements IdSpace, ISuppor
this.onCloseHandler = handler;
}
/**
* @return {@link ITabOnCloseHandler}
*/
public ITabOnCloseHandler getOnCloseHandler() {
return onCloseHandler;
}
/**
* {@inheritDoc}
*/

View File

@ -276,8 +276,8 @@ public abstract class TabbedDesktop extends AbstractDesktop {
preOpenNewTab();
if (Window.INSERT_NEXT.equals(window.getAttribute(Window.INSERT_POSITION_KEY))) {
windowContainer.insertAfter(windowContainer.getSelectedTab(), tabPanel, title, true, true, null);
}
else if(Window.REPLACE.equals(window.getAttribute(Window.INSERT_POSITION_KEY))) {
}
else if(Window.REPLACE.equals(window.getAttribute(Window.INSERT_POSITION_KEY))) {
Tab refTab = windowContainer.getSelectedTab();
Object windowNoAttribute = window.getAttribute(WindowContainer.REPLACE_WINDOW_NO);
if (windowNoAttribute != null && windowNoAttribute instanceof Integer) {
@ -285,10 +285,10 @@ public abstract class TabbedDesktop extends AbstractDesktop {
refTab = windowContainer.getTab(windowNo);
}
windowContainer.replace(refTab, window, title);
}
else {
windowContainer.addWindow(tabPanel, title, true, null);
}
}
else {
windowContainer.addWindow(tabPanel, title, true, null);
}
if (window instanceof IHelpContext)
Events.sendEvent(new Event(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT, window));
}

View File

@ -62,7 +62,6 @@ import org.adempiere.webui.event.DrillEvent;
import org.adempiere.webui.event.DrillEvent.DrillData;
import org.adempiere.webui.event.ZoomEvent;
import org.adempiere.webui.panel.ADForm;
import org.adempiere.webui.panel.ITabOnCloseHandler;
import org.adempiere.webui.panel.StatusBarPanel;
import org.adempiere.webui.report.HTMLExtension;
import org.adempiere.webui.session.SessionManager;
@ -125,7 +124,6 @@ import org.zkoss.zul.North;
import org.zkoss.zul.Popup;
import org.zkoss.zul.Separator;
import org.zkoss.zul.South;
import org.zkoss.zul.Tab;
import org.zkoss.zul.Toolbar;
import org.zkoss.zul.Toolbarbutton;
import org.zkoss.zul.Vlayout;
@ -146,13 +144,13 @@ import org.zkoss.zul.impl.XulElement;
* @author Teo Sarca, SC ARHIPAC SERVICE SRL
* <li>FR [ 1762466 ] Add "Window" menu to report viewer.
* <li>FR [ 1894640 ] Report Engine: Excel Export support
*
*
* @author Low Heng Sin
*/
public class ZkReportViewer extends Window implements EventListener<Event>, ITabOnCloseHandler, IReportViewerExportSource {
public class ZkReportViewer extends Window implements EventListener<Event>, IReportViewerExportSource {
/**
* generated serial id
* generated serial id
*/
private static final long serialVersionUID = 6307014622485159910L;
@ -172,14 +170,14 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
private boolean m_setting = false;
/** Report Engine */
protected ReportEngine m_reportEngine;
/** Table ID */
private int m_AD_Table_ID = 0;
private boolean m_isCanExport;
/** Process ID */
private int m_AD_Process_ID = 0;
private MQuery m_ddQ = null;
private MQuery m_daQ = null;
/** Table ID */
private int m_AD_Table_ID = 0;
private boolean m_isCanExport;
/** Process ID */
private int m_AD_Process_ID = 0;
private MQuery m_ddQ = null;
private MQuery m_daQ = null;
private Menuitem m_ddM = null;
private Menuitem m_daM = null;
@ -223,7 +221,7 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
private ToolBarButton bCloudUpload = new ToolBarButton();
protected Map<MAuthorizationAccount, IUploadService> uploadServicesMap = new HashMap<>();
private final ExportFormat[] exportFormats = new ExportFormat[] {
new ExportFormat(POSTSCRIPT_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FilePS"), POSTSCRIPT_FILE_EXT, POSTSCRIPT_MIME_TYPE),
new ExportFormat(XML_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileXML"), XML_FILE_EXT, XML_MIME_TYPE),
@ -247,7 +245,7 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
*/
public ZkReportViewer(ReportEngine re, String title) {
super();
init = false;
m_WindowNo = SessionManager.getAppDesktop().registerWindow(this);
setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, m_WindowNo);
@ -425,6 +423,7 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
try {
SessionManager.getSessionApplication().getKeylistener().removeEventListener(Events.ON_CTRL_KEY, this);
} catch (Exception e) {}
cleanUp();
}
private void init() {
@ -786,14 +785,14 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
linkDiv.appendChild(reportLink);
south.appendChild(linkDiv);
//m_WindowNo
int AD_Window_ID = Env.getContextAsInt(Env.getCtx(), m_reportEngine.getWindowNo(), "_WinInfo_AD_Window_ID", true);
if (AD_Window_ID == 0)
AD_Window_ID = Env.getZoomWindowID(m_reportEngine.getQuery());
m_AD_Process_ID = m_reportEngine.getPrintInfo() != null ? m_reportEngine.getPrintInfo().getAD_Process_ID() : 0;
updateToolbarAccess(AD_Window_ID, m_AD_Process_ID);
this.setBorder("normal");
int AD_Window_ID = Env.getContextAsInt(Env.getCtx(), m_reportEngine.getWindowNo(), "_WinInfo_AD_Window_ID", true);
if (AD_Window_ID == 0)
AD_Window_ID = Env.getZoomWindowID(m_reportEngine.getQuery());
m_AD_Process_ID = m_reportEngine.getPrintInfo() != null ? m_reportEngine.getPrintInfo().getAD_Process_ID() : 0;
updateToolbarAccess(AD_Window_ID, m_AD_Process_ID);
this.setBorder("normal");
this.addEventListener("onZoom", new EventListener<Event>() {
public void onEvent(Event event) throws Exception {
@ -839,8 +838,23 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
});
init = true;
Events.echoEvent("onPostInit", this, null);
setTabOnCloseHandler();
}
private void setTabOnCloseHandler() {
Component parent = this.getParent();
while (parent != null) {
if (parent instanceof Tabpanel) {
Tabpanel parentTabPanel = (Tabpanel) parent;
parentTabPanel.setOnCloseHandler(t -> {
});
break;
}
parent = parent.getParent();
}
}
/**
@ -1112,25 +1126,6 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
super.onClose();
} // dispose
@Override
public void onClose(Tabpanel tabPanel) {
Tab tab = tabPanel.getLinkedTab();
tab.close();
cleanUp();
}
@Override
public void setParent(Component parent) {
super.setParent(parent);
if (parent != null) {
if (parent instanceof Tabpanel) {
Tabpanel tabPanel = (Tabpanel) parent;
tabPanel.setOnCloseHandler(this);
}
}
}
private void cleanUp() {
if (m_reportEngine != null || m_WindowNo >= 0)
{
@ -1173,8 +1168,16 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
}
else if (event.getTarget() instanceof ProcessModalDialog)
{
if(DialogEvents.ON_WINDOW_CLOSE.equals(event.getName()))
hideBusyMask();
if(DialogEvents.ON_WINDOW_CLOSE.equals(event.getName()))
{
hideBusyMask();
ProcessModalDialog dialog = (ProcessModalDialog) event.getTarget();
if (dialog.isCancel())
{
if (getDesktop() != null)
clearTabOnCloseHandler();
}
}
}
}
@ -1522,6 +1525,7 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
return;
ProcessInfo pi = new ProcessInfo("RefreshWithParameters", AD_Process_ID);
pi.setReplaceTabContent();
setTabOnCloseHandler();
ProcessModalDialog processModalDialog = new ProcessModalDialog(this, m_WindowNo, pi);
ZKUpdateUtil.setWindowWidthX(processModalDialog, 850);
this.getParent().appendChild(processModalDialog);
@ -1785,7 +1789,7 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
if (mask != null && mask.getParent() != null) {
mask.detach();
StringBuilder script = new StringBuilder("(function(){let w=zk.Widget.$('#");
script.append(getParent().getUuid()).append("');w.busy=false;");
script.append(getParent().getUuid()).append("');if(w){w.busy=false;}");
script.append("})()");
Clients.response(new AuScript(script.toString()));
}
@ -1797,8 +1801,25 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
progressWindow.dispose();
progressWindow = null;
}
if (getDesktop() != null)
clearTabOnCloseHandler();
}
private void clearTabOnCloseHandler() {
Executions.schedule(getDesktop(), e -> {
Component parent = this.getParent();
while (parent != null) {
if (parent instanceof Tabpanel) {
Tabpanel parentTabPanel = (Tabpanel) parent;
parentTabPanel.setOnCloseHandler(null);
break;
}
parent = parent.getParent();
}
}, new Event("onClearTabOnCloseHandler"));
}
static class PDFRendererRunnable extends ZkContextRunnable implements IServerPushCallback {
private ZkReportViewer viewer;
@ -2033,7 +2054,7 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
ZKUpdateUtil.setHeight(findWindow, "100%");
else
ZKUpdateUtil.setHeight(findWindow, "60%");
findWindow.setSizable(false);
findWindow.setContentStyle("background-color: #fff; width: 99%; margin: auto;");
}
}
findWindow.setSizable(false);
findWindow.setContentStyle("background-color: #fff; width: 99%; margin: auto;");
}
}

View File

@ -46,17 +46,17 @@ public class ZkReportViewerProvider implements ReportViewerProvider {
});
}
}
protected void openReportViewWindow (ReportEngine report) {
ZkReportViewer viewer = new ZkReportViewer(report, report.getName());
viewer.setAttribute(Window.MODE_KEY, Window.MODE_EMBEDDED);
viewer.setAttribute(Window.INSERT_POSITION_KEY, Window.INSERT_NEXT);
if(report.isReplaceTabContent()) {
viewer.setAttribute(Window.INSERT_POSITION_KEY, Window.REPLACE);
viewer.setAttribute(WindowContainer.REPLACE_WINDOW_NO, report.getWindowNo());
}
viewer.setAttribute(WindowContainer.DEFER_SET_SELECTED_TAB, Boolean.TRUE);
SessionManager.getAppDesktop().showWindow(viewer);
viewer.setAttribute(Window.MODE_KEY, Window.MODE_EMBEDDED);
viewer.setAttribute(Window.INSERT_POSITION_KEY, Window.INSERT_NEXT);
if(report.isReplaceTabContent()) {
viewer.setAttribute(Window.INSERT_POSITION_KEY, Window.REPLACE);
viewer.setAttribute(WindowContainer.REPLACE_WINDOW_NO, report.getWindowNo());
}
viewer.setAttribute(WindowContainer.DEFER_SET_SELECTED_TAB, Boolean.TRUE);
SessionManager.getAppDesktop().showWindow(viewer);
}
}