package de.forsthaus.webui.util;
import java.io.Serializable;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Path;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.EventQueues;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Center;
import org.zkoss.zul.Column;
import org.zkoss.zul.Columns;
import org.zkoss.zul.Div;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Intbox;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Toolbarbutton;
import org.zkoss.zul.Window;
import de.forsthaus.policy.model.UserImpl;
/**
* =======================================================================<br>
* MessageBarController. <br>
* =======================================================================<br>
* Works with the EventQueues mechanism of zk 5.x. ALl needed components are
* created in this class. In the zul-template declare only this controller with
* 'apply' to a winMessageBar window component.<br>
* This MessageBarController is for sending and receiving messages from other
* users.<br>
*
* The message text we do input with a special helper window that is called
* InputMessageTextBox.java
*
* <pre>
* < borderlayout >
* . . .
* < !-- STATUS BAR AREA -- >
* < south id="south" border="none" margins="1,0,0,0"
* height="20px" splittable="false" flex="true" >
* < div id="divSouth" >
*
* < !-- The MessageBar. Comps are created in the Controller -- >
* < window id="winMessageBar" apply="${messageBarCtrl}"
* border="none" width="100%" height="100%" />
* < !-- The StatusBar. Comps are created in the Controller -- >
* < window id="winStatusBar" apply="${statusBarCtrl}"
* border="none" width="100%" height="100%" />
* < /div >
* < /south >
* < /borderlayout >
* </pre>
*
* call for the message system:
*
* <pre>
* EventQueues.lookup("userNameEventQueue", EventQueues.APPLICATION, true).publish(new Event("onChangeSelectedObject", null, "new Value"));
* </pre>
*
*
* Spring bean declaration:
*
* <pre>
* < !-- MessageBarCtrl -->
* < bean id="messageBarCtrl" class="de.forsthaus.webui.util.MessageBarCtrl"
* scope="prototype">
* < /bean>
* </pre>
*
* since: zk 5.0.0
*
* @author Stephan Gerth
*
*/
public class MessageBarCtrl extends GenericForwardComposer implements Serializable {
private static final long serialVersionUID = 1L;
/*
* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* All the components that are defined here and have a corresponding
* component with the same 'id' in the zul-file are getting autowired by our
* 'extends GFCBaseCtrl' GenericForwardComposer.
* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
protected Window winMessageBar; // autowired
// Indicator column for message buttons
private Column statusBarMessageIndicator;
private Toolbarbutton btnOpenMsg;
private Toolbarbutton btnSendMsg;
private Window msgWindow = null;
private String msg = "";
private String userName;
/**
* Default constructor.
*/
public MessageBarCtrl() {
super();
}
@Override
public void doAfterCompose(Component window) throws Exception {
super.doAfterCompose(window);
// !!! not used at time. Here we can get the User for filtering the
// incoming
// messages.
try {
userName = ((UserImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
} catch (Exception e) {
e.printStackTrace();
}
// Listener for incoming messages ( scope=APPLICATION )
EventQueues.lookup("testEventQueue", EventQueues.APPLICATION, true).subscribe(new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
final String msg = (String) event.getData();
// Check if empty, than do not show incoming message
if (StringUtils.isEmpty(msg)) {
return;
}
setMsg(msg);
if (msgWindow == null) {
/**
* If you whish to popup the incoming message than uncomment
* these next 3 lines.
*/
// START Popup
getMsgWindow();
((Textbox) getMsgWindow().getFellow("tb")).setValue(getMsg());
MessageBarCtrl.this.btnOpenMsg.setImage("/images/icons/message2_16x16.gif");
// END Popup
/**
* If you whish to inform smartly of incoming message than
* uncomment the next line for only a blinking Icon.
*/
// MessageBarCtrl.this.btnOpenMsg.setImage("/images/icons/incoming_message1_16x16.gif");
} else {
Textbox t = ((Textbox) getMsgWindow().getFellow("tb"));
t.setValue(getMsg());
// SCROLL the text to the last Message.
Clients.evalJavaScript("scrollTextbox('" + t.getUuid() + "')");
// int stPos = t.getText().length();
// t.setSelectionRange(stPos, getMsg().length() - 1);
}
}
});
}
/**
* Automatically called method from zk.
*
* @param event
*/
public void onCreate$winMessageBar(Event event) {
final Grid grid = new Grid();
grid.setHeight("100%");
grid.setWidth("50px");
grid.setParent(this.winMessageBar);
final Columns columns = new Columns();
columns.setSizable(false);
columns.setParent(grid);
// Column for the Message buttons
this.statusBarMessageIndicator = new Column();
this.statusBarMessageIndicator.setWidth("50px");
this.statusBarMessageIndicator.setStyle("background-color: #D6DCDE; padding: 0px");
this.statusBarMessageIndicator.setParent(columns);
Div div = new Div();
div.setStyle("padding: 1px;");
div.setParent(statusBarMessageIndicator);
// open message button
this.btnOpenMsg = new Toolbarbutton();
this.btnOpenMsg.setId("btnOpenMsg");
this.btnOpenMsg.setWidth("20px");
this.btnOpenMsg.setHeight("20px");
this.btnOpenMsg.setImage("/images/icons/message2_16x16.gif");
this.btnOpenMsg.setTooltiptext(Labels.getLabel("common.Message.Open"));
this.btnOpenMsg.setParent(div);
this.btnOpenMsg.addEventListener("onClick", new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
// 1. Reset to normal image
btnOpenMsg.setImage("/images/icons/message2_16x16.gif");
// 2. open the message window
Window win = getMsgWindow();
Textbox t = (Textbox) win.getFellow("tb");
t.setText(getMsg());
// TODO scroll to latest message
// Clients.scrollIntoView(t);
}
});
// send message button
this.btnSendMsg = new Toolbarbutton();
this.btnSendMsg.setWidth("20px");
this.btnSendMsg.setHeight("20px");
this.btnSendMsg.setImage("/images/icons/message1_16x16.gif");
this.btnSendMsg.setTooltiptext(Labels.getLabel("common.Message.Send"));
this.btnSendMsg.setParent(div);
this.btnSendMsg.addEventListener("onClick", new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
// open a box for inserting the message
Window win = (Window) Path.getComponent("/outerIndexWindow");
final String str = InputMessageTextBox.show(win);
EventQueues.lookup("testEventQueue", EventQueues.APPLICATION, true).publish(new Event("onTestEventQueue", null, str));
}
});
}
// +++++++++++++++++++++++++++++++++++++++++++++++++ //
// ++++++++++++++++ Setter/Getter ++++++++++++++++++ //
// +++++++++++++++++++++++++++++++++++++++++++++++++ //
public void setMsg(String msg) {
this.msg = this.msg + "\n" + msg;
// this.msg = this.msg + "\n" +
// "_____________________________________________________" + "\n";
}
public String getMsg() {
return msg;
}
public void setMsgWindow(Window msgWindow) {
this.msgWindow = msgWindow;
}
/**
* Get the message window. <br>
* Thanks to Lesstra for adding the borderlayout for nicer looking by
* resizing this window.
*
* @return
*/
public Window getMsgWindow() {
int msgHeight = 260;
// if null, create the MessageWindow
if (msgWindow == null) {
msgWindow = new Window();
msgWindow.setId("msgWindow");
msgWindow.setTitle("Messages");
msgWindow.setSizable(true);
msgWindow.setClosable(true);
msgWindow.setWidth("400px");
msgWindow.setHeight(String.valueOf(msgHeight) + "px");
msgWindow.setParent(winMessageBar);
msgWindow.setStyle("padding: 3px");
msgWindow.addEventListener("onClose", new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
msgWindow.detach();
msgWindow = null;
}
});
// ------ added borderlayout --------
Borderlayout blayout = new Borderlayout();
Center center = new Center();
center.setFlex(true);
center.setBorder("none");
center.setAutoscroll(true);
Textbox tb = new Textbox();
tb.setId("tb");
tb.setMultiline(true);
tb.setReadonly(true);
// tb.setRows(17);
// tb.setWidth("98%");
tb.setParent(center);
center.setParent(blayout);
blayout.setParent(msgWindow);
/**
* set the bottom of the msgWindow, so that we can see and reach the
* messageBar buttons.
*/
final int height = ((Intbox) Path.getComponent("/outerIndexWindow/currentDesktopHeight")).getValue().intValue();
final int h = height - msgHeight + 30;
msgWindow.setLeft("3px");
msgWindow.setTop(String.valueOf(h) + "px");
msgWindow.doOverlapped();
}
return msgWindow;
}
}