/* * #%L * carewebframework * %% * Copyright (C) 2008 - 2016 Regenstrief Institute, Inc. * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This Source Code Form is also subject to the terms of the Health-Related * Additional Disclaimer of Warranty and Limitation of Liability available at * * http://www.carewebframework.org/licensing/disclaimer. * * #L% */ package org.carewebframework.plugin.infopanel.controller; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.carewebframework.api.event.IGenericEvent; import org.carewebframework.shell.plugins.PluginContainer; import org.carewebframework.shell.plugins.PluginController; import org.carewebframework.plugin.infopanel.model.IInfoPanel; import org.carewebframework.ui.zk.MenuUtil; import org.carewebframework.ui.zk.ZKUtil; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.HtmlBasedComponent; import org.zkoss.zk.ui.event.DropEvent; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zul.Grid; import org.zkoss.zul.Label; import org.zkoss.zul.LayoutRegion; import org.zkoss.zul.Menubar; import org.zkoss.zul.Menuitem; import org.zkoss.zul.Rows; /** * Controller for the main info panel. */ public class MainController extends PluginController implements IInfoPanel { private static final Log log = LogFactory.getLog(MainController.class); private static final long serialVersionUID = 1L; protected static final String ALERT_ACTION_EVENT = "onAlertAction"; private Menubar menubar; private Component dropRoot; private HtmlBasedComponent alertIcon; private LayoutRegion alertPanel; private HtmlBasedComponent menuPanel; private Grid alertGrid; private Rows alertRoot; private Label alertTitle; private String collapsedAlertPanelHeight; private String openAlertPanelHeight = "33%"; private boolean alertPanelOpen; private String alertTitlePrefix; private int lastAlertCount = -1; /** * Listener for event-based drop and alert requests. */ private final IGenericEvent<Component> dropListener = new IGenericEvent<Component>() { @Override public void eventCallback(String eventName, Component comp) { if (isActive()) { if (eventName.equals(DROP_EVENT_NAME)) { drop(comp); } else if (eventName.equals(ALERT_EVENT_NAME)) { showAlert(comp); } } } }; /** * Set the drop id of the root component. * * @param comp The root component of the info panel. */ @Override public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); ((HtmlBasedComponent) comp).setDroppable(getDropId()); this.collapsedAlertPanelHeight = this.alertPanel.getHeight(); this.alertTitlePrefix = this.alertTitle.getValue(); openAlertPanel(false); } /** * Adds a menu item to the panel's menu bar. * * @param menuitem The menu item to register. * @param path The menu path under which the item should appear. * @see org.carewebframework.plugin.infopanel.model.IInfoPanel#registerMenuItem(Menuitem, String) */ @Override public void registerMenuItem(Menuitem menuitem, String path) { MenuUtil.addMenuItem(path + "\\" + menuitem.getLabel(), menuitem, menubar, null); menuPanel.setVisible(true); if (log.isDebugEnabled()) { log.debug("Registered menu item: " + menuitem); } } /** * Removes a menu item from the panel's menu bar. * * @param menuitem Menu item to remove. * @see org.carewebframework.plugin.infopanel.model.IInfoPanel#unregisterMenuItem(Menuitem) */ @Override public void unregisterMenuItem(Menuitem menuitem) { Component parent = menuitem.getParent(); menuitem.detach(); if (parent != null) { MenuUtil.pruneMenus(parent); menuPanel.setVisible(parent.getFirstChild() != null); } if (log.isDebugEnabled()) { log.debug("Unregistered menu item: " + menuitem); } } /** * Handler for drop events. * * @param event The drop event. */ public void onDrop(DropEvent event) { drop(event.getDragged()); } /** * Toggles the alert panel open state. */ public void onClick$alertIcon() { openAlertPanel(!alertPanelOpen); } /** * Handles onAlertAction event which an alert container sends after it has processed an action. * * @param event The onAlertAction event. */ public void onAlertAction$alertRoot(Event event) { event = ZKUtil.getEventOrigin(event); Action action = (Action) event.getData(); openAlertPanel(null); if (action == Action.TOP) { alertGrid.setActivePage(0); alertGrid.invalidate(); } } /** * Open or close the alert panel, updating the alert icon. * * @param open If true, open the alert panel. If false, close it. If null, open status is * determined by the presence or absence of alerts. */ private void openAlertPanel(Boolean open) { if (this.alertPanelOpen) { this.openAlertPanelHeight = this.alertPanel.getHeight(); } int alertCount = 0; for (Component cmp : alertRoot.getChildren()) { if (cmp.isVisible()) { alertCount++; } } open = open == null ? alertCount > 0 : open; alertPanelOpen = open; alertGrid.setVisible(open); alertPanel.setMinsize(open ? 70 : 0); alertPanel.setSplittable(open); alertPanel.setHeight(open ? this.openAlertPanelHeight : this.collapsedAlertPanelHeight); alertIcon.setSclass(open ? "glyphicon-chevron-down" : "glyphicon-chevron-up"); if (alertCount != lastAlertCount) { lastAlertCount = alertCount; String countStr = (alertCount == 0 ? "no" : Integer.toString(alertCount)) + " alert" + (alertCount == 1 ? "" : "s"); alertTitle.setValue(alertTitlePrefix + " - " + countStr); alertPanel.setVisible(alertCount > 0); } Clients.resize(root); } /** * Returns the drop id for the panel. * * @see org.carewebframework.ui.zk.IDropHandler#getDropId() */ @Override public String getDropId() { return DROP_ID; } /** * Drops the specified item onto the panel, invoking its renderer. * * @param droppedItem Item to drop. * @see org.carewebframework.ui.zk.IDropHandler#drop(Component) */ @Override public void drop(Component droppedItem) { DropContainer.render(dropRoot, droppedItem); } /** * Displays an alert in the alert grid. * * @param root Root component for the rendered alert. */ @Override public void showAlert(Component root) { AlertContainer.render(alertRoot, root); alertGrid.setActivePage(0); openAlertPanel(true); } /** * Clear all alerts. */ @Override public void clearAlerts() { List<Component> children = alertRoot.getChildren(); while (children.size() > 0) { AlertContainer alertContainer = (AlertContainer) children.get(0); alertContainer.doAction(Action.REMOVE); } openAlertPanel(false); } /** * Subscribe to drop request events. */ @Override public void onLoad(PluginContainer container) { getEventManager().subscribe(EVENT_NAME, dropListener); } /** * Unsubscribe from drop request events. */ @Override public void onUnload() { getEventManager().unsubscribe(EVENT_NAME, dropListener); } }