/****************************************************************************** * Product: Posterita Ajax UI * * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. This program is distributed in the hope * * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * For the text or an alternative of this public license, you may reach us * * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius * * or via info@posterita.org or http://www.posterita.org/ * *****************************************************************************/ package org.adempiere.webui.desktop; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.Serializable; import java.net.URL; import java.util.logging.Level; import org.adempiere.webui.apps.graph.WGraph; import org.adempiere.webui.apps.graph.WPerformanceDetail; import org.adempiere.webui.component.Tabpanel; import org.adempiere.webui.component.ToolBarButton; import org.adempiere.webui.dashboard.DPActivities; import org.adempiere.webui.dashboard.DashboardPanel; import org.adempiere.webui.dashboard.DashboardRunnable; import org.adempiere.webui.event.MenuListener; import org.adempiere.webui.panel.HeaderPanel; import org.adempiere.webui.panel.SidePanel; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.util.IServerPushCallback; import org.adempiere.webui.util.ServerPushTemplate; import org.adempiere.webui.util.UserPreference; import org.compiere.model.I_AD_Menu; import org.compiere.model.MDashboardContent; import org.compiere.model.MGoal; import org.compiere.model.X_PA_DashboardContent; import org.compiere.util.CLogger; import org.compiere.util.Env; import org.compiere.util.Msg; import org.zkoss.zk.au.out.AuScript; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Executions; 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; import org.zkoss.zk.ui.event.OpenEvent; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zkex.zul.Borderlayout; import org.zkoss.zkex.zul.Center; import org.zkoss.zkex.zul.North; import org.zkoss.zkex.zul.West; import org.zkoss.zkmax.zul.Portalchildren; import org.zkoss.zkmax.zul.Portallayout; import org.zkoss.zul.Html; import org.zkoss.zul.Panel; import org.zkoss.zul.Panelchildren; import org.zkoss.zul.Toolbarbutton; /** * * Default desktop implementation. * @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a> * @author <a href="mailto:hengsin@gmail.com">Low Heng Sin</a> * @date Mar 2, 2007 * @version $Revision: 0.10 $ */ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Serializable, EventListener, IServerPushCallback { /** * generated serial version ID */ private static final long serialVersionUID = -8203958978173990301L; private static final CLogger logger = CLogger.getCLogger(DefaultDesktop.class); private Center windowArea; private Borderlayout layout; private Thread dashboardThread; private DashboardRunnable dashboardRunnable; private int noOfNotice; private int noOfRequest; private int noOfWorkflow; public DefaultDesktop() { super(); } protected Component doCreatePart(Component parent) { SidePanel pnlSide = new SidePanel(); HeaderPanel pnlHead = new HeaderPanel(); pnlSide.getMenuPanel().addMenuListener(this); layout = new Borderlayout(); if (parent != null) { layout.setParent(parent); layout.setWidth("100%"); layout.setHeight("100%"); layout.setStyle("position: absolute"); } else layout.setPage(page); dashboardRunnable = new DashboardRunnable(layout.getDesktop(), this); North n = new North(); layout.appendChild(n); n.setCollapsible(false); pnlHead.setParent(n); West w = new West(); layout.appendChild(w); w.setWidth("300px"); w.setCollapsible(true); w.setSplittable(true); w.setTitle("Menu"); w.setFlex(true); w.addEventListener(Events.ON_OPEN, new EventListener() { @Override public void onEvent(Event event) throws Exception { OpenEvent oe = (OpenEvent) event; UserPreference pref = SessionManager.getSessionApplication().getUserPreference(); pref.setProperty(UserPreference.P_MENU_COLLAPSED, !oe.isOpen()); pref.savePreference(); } }); UserPreference pref = SessionManager.getSessionApplication().getUserPreference(); boolean menuCollapsed= pref.isPropertyBool(UserPreference.P_MENU_COLLAPSED); w.setOpen(!menuCollapsed); pnlSide.setParent(w); windowArea = new Center(); windowArea.setParent(layout); windowArea.setFlex(true); windowContainer.createPart(windowArea); createHomeTab(); return layout; } private void createHomeTab() { Tabpanel homeTab = new Tabpanel(); windowContainer.addWindow(homeTab, Msg.getMsg(Env.getCtx(), "Home").replaceAll("&", ""), false); Portallayout portalLayout = new Portallayout(); portalLayout.setWidth("100%"); portalLayout.setHeight("100%"); portalLayout.setStyle("position: absolute; overflow: auto"); homeTab.appendChild(portalLayout); // Dashboard content Portalchildren portalchildren = null; int currentColumnNo = 0; int noOfCols = 0; int width = 0; try { noOfCols = MDashboardContent.getForSessionColumnCount(); width = noOfCols <= 0 ? 100 : 100 / noOfCols; for (final MDashboardContent dp : MDashboardContent.getForSession()) { int columnNo = dp.getColumnNo(); if(portalchildren == null || currentColumnNo != columnNo) { portalchildren = new Portalchildren(); portalLayout.appendChild(portalchildren); portalchildren.setWidth(width + "%"); portalchildren.setStyle("padding: 5px"); currentColumnNo = columnNo; } Panel panel = new Panel(); panel.setStyle("margin-bottom:10px"); panel.setTitle(dp.getName()); String description = dp.getDescription(); if(description != null) panel.setTooltiptext(description); panel.setCollapsible(dp.isCollapsible()); panel.setOpen( dp.isOpenByDefault() ); panel.setBorder("normal"); portalchildren.appendChild(panel); Panelchildren content = new Panelchildren(); panel.appendChild(content); boolean panelEmpty = true; // HTML content String htmlContent = dp.getHTML(); if(htmlContent != null) { StringBuffer result = new StringBuffer("<html><head>"); URL url = getClass().getClassLoader().getResource("org/compiere/images/PAPanel.css"); InputStreamReader ins; try { ins = new InputStreamReader(url.openStream()); BufferedReader bufferedReader = new BufferedReader( ins ); String cssLine; while ((cssLine = bufferedReader.readLine()) != null) result.append(cssLine + "\n"); } catch (IOException e1) { logger.log(Level.SEVERE, e1.getLocalizedMessage(), e1); } result.append("</head><body><div class=\"content\">\n"); // if(description != null) // result.append("<h2>" + description + "</h2>\n"); result.append(stripHtml(htmlContent, false) + "<br>\n"); result.append("</div>\n</body>\n</html>\n</html>"); Html html = new Html(); html.setContent(result.toString()); content.appendChild(html); panelEmpty = false; } // Window int AD_Window_ID = dp.getAD_Window_ID(); if(AD_Window_ID > 0) { int AD_Menu_ID = dp.getAD_Menu_ID(); ToolBarButton btn = new ToolBarButton(String.valueOf(AD_Menu_ID)); I_AD_Menu menu = dp.getAD_Menu(); btn.setLabel(menu.getName()); btn.addEventListener(Events.ON_CLICK, this); content.appendChild(btn); panelEmpty = false; } // Goal int PA_Goal_ID = dp.getPA_Goal_ID(); if(PA_Goal_ID > 0) { //link to open performance detail Toolbarbutton link = new Toolbarbutton(); link.setImage("/images/Zoom16.png"); link.setAttribute("PA_Goal_ID", PA_Goal_ID); link.addEventListener(Events.ON_CLICK, new EventListener() { public void onEvent(Event event) throws Exception { int PA_Goal_ID = (Integer)event.getTarget().getAttribute("PA_Goal_ID"); MGoal goal = new MGoal(Env.getCtx(), PA_Goal_ID, null); new WPerformanceDetail(goal); } }); content.appendChild(link); String goalDisplay = dp.getGoalDisplay(); MGoal goal = new MGoal(Env.getCtx(), PA_Goal_ID, null); WGraph graph = new WGraph(goal, 55, false, true, !(X_PA_DashboardContent.GOALDISPLAY_Chart.equals(goalDisplay)), X_PA_DashboardContent.GOALDISPLAY_Chart.equals(goalDisplay)); content.appendChild(graph); panelEmpty = false; } // ZUL file url String url = dp.getZulFilePath(); if(url != null) { try { Component component = Executions.createComponents(url, content, null); if(component != null) { if (component instanceof DashboardPanel) { DashboardPanel dashboardPanel = (DashboardPanel) component; if (!dashboardPanel.getChildren().isEmpty()) { content.appendChild(dashboardPanel); dashboardRunnable.add(dashboardPanel); panelEmpty = false; } } else { content.appendChild(component); panelEmpty = false; } } } catch (Exception e) { logger.log(Level.WARNING, "Failed to create components. zul="+url, e); } } if (panelEmpty) panel.detach(); } } catch (Exception e) { logger.log(Level.WARNING, "Failed to create dashboard content", e); } finally { } // //register as 0 registerWindow(homeTab); if (!portalLayout.getDesktop().isServerPushEnabled()) portalLayout.getDesktop().enableServerPush(true); dashboardRunnable.refreshDashboard(); dashboardThread = new Thread(dashboardRunnable, "UpdateInfo"); dashboardThread.setDaemon(true); dashboardThread.start(); } public void onEvent(Event event) { Component comp = event.getTarget(); String eventName = event.getName(); if(eventName.equals(Events.ON_CLICK)) { if(comp instanceof ToolBarButton) { ToolBarButton btn = (ToolBarButton) comp; int menuId = 0; try { menuId = Integer.valueOf(btn.getName()); } catch (Exception e) { } if(menuId > 0) onMenuSelected(menuId); } } } public void onServerPush(ServerPushTemplate template) { noOfNotice = DPActivities.getNoticeCount(); noOfRequest = DPActivities.getRequestCount(); noOfWorkflow = DPActivities.getWorkflowCount(); template.execute(this); } /** * * @param page */ public void setPage(Page page) { if (this.page != page) { layout.setPage(page); this.page = page; if (dashboardThread != null && dashboardThread.isAlive()) { dashboardRunnable.stop(); dashboardThread.interrupt(); DashboardRunnable tmp = dashboardRunnable; dashboardRunnable = new DashboardRunnable(tmp, layout.getDesktop(), this); dashboardThread = new Thread(dashboardRunnable, "UpdateInfo"); dashboardThread.setDaemon(true); dashboardThread.start(); } } } /** * Get the root component * @return Component */ public Component getComponent() { return layout; } public void logout() { if (dashboardThread != null && dashboardThread.isAlive()) { dashboardRunnable.stop(); dashboardThread.interrupt(); } } public void updateUI() { int total = noOfNotice + noOfRequest + noOfWorkflow; windowContainer.setTabTitle(0, Msg.getMsg(Env.getCtx(), "Home").replaceAll("&", "") + " (" + total + ")", Msg.translate(Env.getCtx(), "AD_Note_ID") + " : " + noOfNotice + ", " + Msg.translate(Env.getCtx(), "R_Request_ID") + " : " + noOfRequest + ", " + Msg.getMsg (Env.getCtx(), "WorkflowActivities") + " : " + noOfWorkflow); } private void autoHideMenu() { if (layout.getWest().isCollapsible() && !layout.getWest().isOpen()) { //using undocumented js api, need to be retested after every version upgrade String id = layout.getWest().getUuid() + "!real"; String btn = layout.getWest().getUuid() + "!btn"; String script = "zk.show('" + id + "', false);"; script += "$e('"+id+"')._isSlide = false;"; script += "$e('"+id+"')._lastSize = null;"; script += "$e('"+btn+"').style.display = '';"; AuScript aus = new AuScript(layout.getWest(), script); Clients.response("autoHideWest", aus); } } @Override protected void preOpenNewTab() { autoHideMenu(); } }