IDEMPIERE-5570 Zk: Improve readability of code (#1774)

- org.adempiere.webui.dashboard and org.adempiere.webui.desktop package
This commit is contained in:
hengsin 2023-04-11 19:35:38 +08:00 committed by GitHub
parent b5cb64bc92
commit ea6c44b913
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 789 additions and 234 deletions

View File

@ -47,7 +47,7 @@ import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Div;
/**
* Document Status Indicator
* Document Status ({@link MDocumentStatus}) Indicator
*/
public class WDocumentStatusIndicator extends Panel implements EventListener<Event> {
private static final long serialVersionUID = -9076405331101242792L;

View File

@ -16,31 +16,44 @@ package org.adempiere.webui.dashboard;
import org.zkoss.calendar.impl.SimpleCalendarEvent;
/**
*
* Calendar event for R_Request
* @author Elaine
*
*/
public class ADCalendarEvent extends SimpleCalendarEvent {
/**
*
* generated serial id
*/
private static final long serialVersionUID = 2289841014956779967L;
private int R_Request_ID;
private int R_RequestType_ID;
/**
* @return R_Request_ID
*/
public int getR_Request_ID() {
return R_Request_ID;
}
/**
* Set R_Request_ID
* @param request_ID
*/
public void setR_Request_ID(int request_ID) {
R_Request_ID = request_ID;
}
/**
* @return R_RequestType_ID
*/
public int getR_RequestType_ID() {
return R_RequestType_ID;
}
/**
* Set R_RequestType_ID
* @param requestType_ID
*/
public void setR_RequestType_ID(int requestType_ID) {
R_RequestType_ID = requestType_ID;
}

View File

@ -72,34 +72,56 @@ import org.zkoss.zul.Timer;
import org.zkoss.zul.Toolbarbutton;
/**
*
* Calendar window
* @author Elaine
*
*/
public class CalendarWindow extends Window implements EventListener<Event>, ITabOnCloseHandler {
/**
*
* generated serial id
*/
private static final long serialVersionUID = 1576992746053720647L;
private static final String ON_MOBILE_SET_SELECTED_TAB_ECHO = "onMobileSetSelectedTabEcho";
private static final String ON_MOVE_DATE_EVENT = "onMoveDate";
private static final String ON_UPDATE_VIEW_EVENT = "onUpdateView";
private static final String ON_MOUSE_OVER_EVENT = "onMouseOver";
private static final String ON_EVENT_UPDATE_EVENT = "onEventUpdate";
private static final String ON_EVENT_EDIT_EVENT = "onEventEdit";
private static final String ON_EVENT_CREATE_EVENT = "onEventCreate";
/** Zk Calendar instance. Center of window. */
private Calendars calendars;
/** Calendar model for {@link #calendars} */
private SimpleCalendarModel scm;
/** Re-query button */
private Toolbarbutton btnRefresh;
/** List of request types */
private Listbox lbxRequestTypes;
/** Pie chart for calendar events. South of window. */
private Image myChart;
private Button btnCurrentDate, btnSwitchTimeZone;
/** Label for start and end date of current Calendar view */
private Label lblDate;
/** button to move Calendar to previous or next page */
private Component divArrowLeft, divArrowRight;
private Span FDOW;
/** List to select first day of a week (monday, tuesday, etc). Visible for week and month view. */
private Listbox lbxFDOW;
/** Tab for Day, Week, 5Day and Month view */
private Component divTabDay, divTabWeek, divTabWeekdays, divTabMonth;
/** Message Popup */
private Popup updateMsg;
/** Content of {@link #updateMsg} */
private Label popupLabel;
/** Timer to close {@link #updateMsg} */
private Timer timer;
/** Window for event */
private EventWindow eventWin;
/**
* Create window content from "zul/calendar/calendar.zul"
* @param scm SimpleCalendarModel
*/
public CalendarWindow(SimpleCalendarModel scm) {
super();
@ -112,7 +134,7 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
Component component = Executions.createComponents(ThemeManager.getThemeResource("zul/calendar/calendar.zul"), this, null);
Borderlayout borderlayout = (Borderlayout) component.getFellow("main");
borderlayout.setStyle("position: absolute");
borderlayout.setStyle("position: relative");
ZKUpdateUtil.setWidth(borderlayout, "100%");
ZKUpdateUtil.setHeight(borderlayout, "100%");
@ -147,10 +169,10 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
lblDate.addEventListener(Events.ON_CREATE, this);
divArrowLeft = component.getFellow("divArrowLeft");
divArrowLeft.addEventListener("onMoveDate", this);
divArrowLeft.addEventListener(ON_MOVE_DATE_EVENT, this);
divArrowRight = component.getFellow("divArrowRight");
divArrowRight.addEventListener("onMoveDate", this);
divArrowRight.addEventListener(ON_MOVE_DATE_EVENT, this);
FDOW = (Span) component.getFellow("FDOW");
FDOW.addEventListener(Events.ON_CREATE, this);
@ -165,16 +187,16 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
}
divTabDay = component.getFellow("divTabDay");
divTabDay.addEventListener("onUpdateView", this);
divTabDay.addEventListener(ON_UPDATE_VIEW_EVENT, this);
divTabWeek = component.getFellow("divTabWeek");
divTabWeek.addEventListener("onUpdateView", this);
divTabWeek.addEventListener(ON_UPDATE_VIEW_EVENT, this);
divTabWeekdays = component.getFellow("divTabWeekdays");
divTabWeekdays.addEventListener("onUpdateView", this);
divTabWeekdays.addEventListener(ON_UPDATE_VIEW_EVENT, this);
divTabMonth = component.getFellow("divTabMonth");
divTabMonth.addEventListener("onUpdateView", this);
divTabMonth.addEventListener(ON_UPDATE_VIEW_EVENT, this);
updateMsg = (Popup) component.getFellow("updateMsg");
@ -184,10 +206,10 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
this.appendChild(component);
calendars.addEventListener("onEventCreate", this);
calendars.addEventListener("onEventEdit", this);
calendars.addEventListener("onEventUpdate", this);
calendars.addEventListener("onMouseOver", this);
calendars.addEventListener(ON_EVENT_CREATE_EVENT, this);
calendars.addEventListener(ON_EVENT_EDIT_EVENT, this);
calendars.addEventListener(ON_EVENT_UPDATE_EVENT, this);
calendars.addEventListener(ON_MOUSE_OVER_EVENT, this);
if (ClientInfo.isMobile()) {
addCallback(AFTER_PAGE_ATTACHED, t -> afterPageAttached());
@ -203,6 +225,10 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
}
}
/**
* After page attached callback for mobile client. <br/>
* Setup listener for {@link WindowContainer#ON_MOBILE_SET_SELECTED_TAB} event.
*/
private void afterPageAttached() {
Component p = getParent();
while (p != null) {
@ -214,10 +240,15 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
}
}
/**
* {@link WindowContainer#ON_MOBILE_SET_SELECTED_TAB} event.<br/>
* Echo {@link #ON_MOBILE_SET_SELECTED_TAB_ECHO} event to redraw {@link #calendars}.
*/
private void onMobileSelected() {
Events.echoEvent(ON_MOBILE_SET_SELECTED_TAB_ECHO, this, null);
}
@Override
public void onClose(Tabpanel tabPanel){
//IDEMPIERE-1457: On close, remove calendars away scm
calendars.setModel(null);
@ -225,6 +256,7 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
tab.close();
}
@Override
public void onEvent(Event e) throws Exception {
String type = e.getName();
@ -246,13 +278,13 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
else if (e.getTarget() == lbxFDOW)
lbxFDOW.setSelectedIndex(0);
}
else if (type.equals("onMoveDate")) {
else if (type.equals(ON_MOVE_DATE_EVENT)) {
if (e.getTarget() == divArrowLeft)
divArrowClicked(false);
else if (e.getTarget() == divArrowRight)
divArrowClicked(true);
}
else if (type.equals("onUpdateView")) {
else if (type.equals(ON_UPDATE_VIEW_EVENT)) {
String text = String.valueOf(e.getData());
int days = Msg.getMsg(Env.getCtx(),"Day").equals(text) ? 1: Msg.getMsg(Env.getCtx(),"5Days").equals(text) ? 5: Msg.getMsg(Env.getCtx(),"Week").equals(text) ? 7: 0;
divTabClicked(days);
@ -278,14 +310,14 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
syncModel();
}
}
else if (type.equals("onEventCreate")) {
else if (type.equals(ON_EVENT_CREATE_EVENT)) {
if (e instanceof CalendarsEvent) {
CalendarsEvent calendarsEvent = (CalendarsEvent) e;
RequestWindow requestWin = new RequestWindow(calendarsEvent, this);
SessionManager.getAppDesktop().showWindow(requestWin);
}
}
else if (type.equals("onEventEdit")) {
else if (type.equals(ON_EVENT_EDIT_EVENT)) {
if (e instanceof CalendarsEvent) {
CalendarsEvent calendarsEvent = (CalendarsEvent) e;
CalendarEvent calendarEvent = calendarsEvent.getCalendarEvent();
@ -300,7 +332,7 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
}
}
}
else if (type.equals("onEventUpdate")) {
else if (type.equals(ON_EVENT_UPDATE_EVENT)) {
if (e instanceof CalendarsEvent)
{
CalendarsEvent evt = (CalendarsEvent) e;
@ -329,6 +361,9 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
}
}
/**
* Update {@link #myChart}
*/
private void syncModel() {
Hashtable<String,BigDecimal> ht = new Hashtable<String,BigDecimal>();
@ -362,6 +397,7 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
pieDataset.setValue(name == null ? "" : name, Double.valueOf(size > 0 ? value.doubleValue()/size*100 : 0));
}
//TODO replace with billboard chart
JFreeChart chart = ChartFactory.createPieChart(Msg.getMsg(Env.getCtx(),"EventsAnalysis"), pieDataset, true, true, true);
PiePlot plot = (PiePlot) chart.getPlot();
plot.setForegroundAlpha(0.5f);
@ -377,10 +413,16 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
ht = null;
}
/**
* Refresh model and UI
*/
public void onRefresh() {
btnRefreshClicked();
}
/**
* Refresh model and UI
*/
private void btnRefreshClicked() {
int R_RequestType_ID = 0;
Listitem li = lbxRequestTypes.getSelectedItem();
@ -411,6 +453,9 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
syncModel();
}
/**
* Set time zone of {@link #calendars}
*/
private void setTimeZone()
{
String alternateTimeZone = MSysConfig.getValue(MSysConfig.CALENDAR_ALTERNATE_TIMEZONE, "Pacific Time=PST", Env.getAD_Client_ID(Env.getCtx()));
@ -424,6 +469,9 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
}
}
/**
* Update {@link #lblDate}
*/
private void updateDateLabel() {
Date b = calendars.getBeginDate();
Date e = calendars.getEndDate();
@ -432,12 +480,18 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
lblDate.setValue(sdfV.format(b) + " - " + sdfV.format(e));
}
/**
* Set {@link #calendars} to current date
*/
private void btnCurrentDateClicked() {
calendars.setCurrentDate(Calendar.getInstance(calendars.getDefaultTimeZone()).getTime());
updateDateLabel();
syncModel();
}
/**
* Change {@link #calendars} time zone
*/
private void btnSwitchTimeZoneClicked() {
Map<?, ?> zone = calendars.getTimeZones();
if (!zone.isEmpty()) {
@ -449,6 +503,10 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
syncModel();
}
/**
* Move {@link #calendars} to next or previous page
* @param isNext true for next page, false for previous page
*/
private void divArrowClicked(boolean isNext) {
if (isNext)
calendars.nextPage();
@ -458,6 +516,10 @@ public class CalendarWindow extends Window implements EventListener<Event>, ITab
syncModel();
}
/**
* On switching of calendar view (Days, Weeks, etc)
* @param days
*/
private void divTabClicked(int days) {
if (days > 0) {
calendars.setMold("default");

View File

@ -66,39 +66,53 @@ import org.zkoss.zul.Label;
import org.zkoss.zul.impl.LabelImageElement;
/**
* Dashboard item: ZK calendar
* Dashboard gadget: Zk Calendar. <br/>
* Content created from "zul/calendar/calendar_mini.zul".
*
* @author Elaine
* @date November 20, 2008
*/
public class DPCalendar extends DashboardPanel implements EventListener<Event>, EventHandler {
/**
*
* generated serial id
*/
private static final long serialVersionUID = -224914882522997787L;
private static final String ON_MOBILE_SET_SELECTED_TAB_ECHO = "onMobileSetSelectedTabEcho";
private static final String ON_EVENT_EDIT_EVENT = "onEventEdit";
private static final String ON_EVENT_CREATE_EVENT = "onEventCreate";
private static final String ON_MOVE_DATE_EVENT = "onMoveDate";
private static final String ON_REQUEST_CHANGED_TOPIC = "onRequestChanged";
/** Zk Calendar instance */
private Calendars calendars;
/** Model for {@link #calendars} */
private SimpleCalendarModel scm;
/** Button to open Calendar window, to Refresh Calendar */
private LabelImageElement btnCal, btnRefresh;
private LabelImageElement btnCurrentDate;
/** Label for start and end date of current Calendar view */
private Label lblDate;
/** button to move Calendar to previous or next page */
private Component divArrowLeft, divArrowRight;
private static final String ON_REQUEST_CHANGED_TOPIC = "onRequestChanged";
/** Window for event */
private EventWindow eventWin;
private WeakReference<Desktop> desktop;
/** List of Calendar (Request) events */
private ArrayList<ADCalendarEvent> events;
/** Desktop cleanup listener to call {@link #cleanup()} */
private DesktopCleanup listener;
/** Event handler for R_Request model */
private static RequestEventHandler eventHandler;
/** Subscriber to {@link IMessageService} for "onRequestChanged" topic */
private static TopicSubscriber subscriber;
private static final CLogger log = CLogger.getCLogger(DPCalendar.class);
/**
* Default constructor
*/
public DPCalendar() {
super();
@ -119,15 +133,15 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event>,
lblDate.addEventListener(Events.ON_CREATE, this);
divArrowLeft = component.getFellow("divArrowLeft");
divArrowLeft.addEventListener("onMoveDate", this);
divArrowLeft.addEventListener(ON_MOVE_DATE_EVENT, this);
divArrowRight = component.getFellow("divArrowRight");
divArrowRight.addEventListener("onMoveDate", this);
divArrowRight.addEventListener(ON_MOVE_DATE_EVENT, this);
this.appendChild(component);
calendars.addEventListener("onEventCreate", this);
calendars.addEventListener("onEventEdit", this);
calendars.addEventListener(ON_EVENT_CREATE_EVENT, this);
calendars.addEventListener(ON_EVENT_EDIT_EVENT, this);
createStaticListeners();
@ -144,6 +158,10 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event>,
}
}
/**
* After page attached callback for mobile client. <br/>
* Setup listener for {@link WindowContainer#ON_MOBILE_SET_SELECTED_TAB} event.
*/
private void afterPageAttached() {
Component p = getParent();
while (p != null) {
@ -155,10 +173,17 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event>,
}
}
/**
* {@link WindowContainer#ON_MOBILE_SET_SELECTED_TAB} event.<br/>
* Echo {@link #ON_MOBILE_SET_SELECTED_TAB_ECHO} event to redraw {@link #calendars}.
*/
private void onMobileSelected() {
Events.echoEvent(ON_MOBILE_SET_SELECTED_TAB_ECHO, this, null);
}
/**
* Setup {@link #eventHandler} and {@link #subscriber}
*/
private synchronized void createStaticListeners() {
if (eventHandler == null) {
eventHandler = new RequestEventHandler();
@ -175,6 +200,7 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event>,
}
}
@Override
public void onEvent(Event e) throws Exception {
String type = e.getName();
@ -190,20 +216,20 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event>,
if (e.getTarget() == lblDate)
updateDateLabel();
}
else if (type.equals("onMoveDate")) {
else if (type.equals(ON_MOVE_DATE_EVENT)) {
if (e.getTarget() == divArrowLeft)
divArrowClicked(false);
else if (e.getTarget() == divArrowRight)
divArrowClicked(true);
}
else if (type.equals("onEventCreate")) {
else if (type.equals(ON_EVENT_CREATE_EVENT)) {
if (e instanceof CalendarsEvent) {
CalendarsEvent calendarsEvent = (CalendarsEvent) e;
RequestWindow requestWin = new RequestWindow(calendarsEvent, this);
SessionManager.getAppDesktop().showWindow(requestWin);
}
}
else if (type.equals("onEventEdit")) {
else if (type.equals(ON_EVENT_EDIT_EVENT)) {
if (e instanceof CalendarsEvent) {
CalendarsEvent calendarsEvent = (CalendarsEvent) e;
CalendarEvent calendarEvent = calendarsEvent.getCalendarEvent();
@ -220,6 +246,13 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event>,
}
}
/**
* TODO move this and ADCalendarEvent to org.adempiere.ui and create unit test for it
* Retrieve events (request) from DB
* @param RequestTypeID
* @param ctx
* @return ADCalendarEvent list
*/
public static ArrayList<ADCalendarEvent> getEvents(int RequestTypeID, Properties ctx) {
String mode = MSysConfig.getValue(MSysConfig.ZK_DASHBOARD_CALENDAR_REQUEST_DISPLAY_MODE, "CSU", Env.getAD_Client_ID(ctx));
@ -366,6 +399,12 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event>,
return events;
}
/**
* TODO move to MRequestType
* Get request types from DB
* @param ctx
* @return X_R_RequestType list
*/
public static ArrayList<X_R_RequestType> getRequestTypes(Properties ctx) {
ArrayList<X_R_RequestType> types = new ArrayList<X_R_RequestType>();
String sql = "SELECT * "
@ -394,6 +433,9 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event>,
return types;
}
/**
* Refresh model and UI
*/
public void onRefresh() {
btnRefreshClicked();
}
@ -429,15 +471,24 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event>,
calendars.invalidate();
}
/**
* Refresh model and UI
*/
private void btnRefreshClicked() {
refreshModel();
updateUI();
}
/**
* Refresh model
*/
private void refreshModel() {
events = getEvents(0, Env.getCtx());
}
/**
* Update {@link #lblDate}
*/
private void updateDateLabel() {
Date b = calendars.getBeginDate();
Date e = calendars.getEndDate();
@ -446,12 +497,19 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event>,
lblDate.setValue(sdfV.format(b) + " - " + sdfV.format(e));
}
/**
* Set {@link #calendars} to current date
*/
private void btnCurrentDateClicked() {
calendars.setCurrentDate(Calendar.getInstance(calendars.getDefaultTimeZone()).getTime());
updateDateLabel();
updateUI();
}
/**
* Move {@link #calendars} to next or previous page
* @param isNext true for next page, false for previous page
*/
private void divArrowClicked(boolean isNext) {
if (isNext)
calendars.nextPage();
@ -508,13 +566,16 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event>,
}
/**
*
* Perform clean up
*/
protected void cleanup() {
EventManager.getInstance().unregister(this);
desktop = null;
}
/**
* ITopicSubscriber to post OSGi event from "onRequestChanged" topic
*/
static class TopicSubscriber implements ITopicSubscriber<Map<String, String>> {
@Override
@ -525,6 +586,9 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event>,
}
/**
* Event handler for R_Request model
*/
static class RequestEventHandler extends AbstractEventHandler {
@Override
protected void doHandleEvent(org.osgi.service.event.Event event) {
@ -552,6 +616,9 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event>,
}
}
/**
* Runnable to post "onRequestChanged" message ({@link IMessageService}) or OSGi event (if {@link IMessageService} not available)
*/
static class RequestRunnable implements Runnable {
private Map<String, String> message;
@ -573,10 +640,16 @@ public class DPCalendar extends DashboardPanel implements EventListener<Event>,
}
}
/**
* TrxEventListener to call a {@link Runnable} after successful commit of transaction.
*/
static class TrxListener implements TrxEventListener {
private Runnable runnable;
/**
* @param runnable
*/
protected TrxListener(Runnable runnable) {
this.runnable = runnable;
}

View File

@ -45,9 +45,12 @@ import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Image;
import org.zkoss.zul.Toolbar;
/**
* Dashboard gadget for {@link WDocumentStatusPanel}
*/
public class DPDocumentStatus extends DashboardPanel implements EventListener<Event> {
/**
*
* generated serial id
*/
private static final long serialVersionUID = 7904122964566112177L;
private WDocumentStatusPanel statusPanel;
@ -63,6 +66,9 @@ public class DPDocumentStatus extends DashboardPanel implements EventListener<Ev
statusPanel.updateUI();
}
/**
* Default constructor
*/
public DPDocumentStatus()
{
super();
@ -94,6 +100,7 @@ public class DPDocumentStatus extends DashboardPanel implements EventListener<Ev
}
}
@Override
public void onEvent(Event event) throws Exception {
String eventName = event.getName();

View File

@ -42,7 +42,7 @@ import org.zkoss.zul.Treerow;
import org.zkoss.zul.Vbox;
/**
* Dashboard item: User favourites - Tree based view organize
* Dashboard gadget: User favourites - Tree based view organize
*
* @author Elaine
* @author Logilite Technologies - IDEMPIERE-3340
@ -50,14 +50,14 @@ import org.zkoss.zul.Vbox;
*/
public class DPFavourites extends DashboardPanel implements EventListener<Event>
{
/**
*
* generated serial id
*/
private static final long serialVersionUID = 7915726855926813700L;
public static final String FAVOURITE_DROPPABLE = "favourite";
/** model for {@link #tree} */
private FavoriteSimpleTreeModel treeModel;
private ToolBarButton btnAdd;
@ -65,9 +65,12 @@ public class DPFavourites extends DashboardPanel implements EventListener<Event>
private ToolBarButton btnExpand;
private ToolBarButton btnAutoLaunch;
/** Favourites menu tree */
private Tree tree;
//
/**
* Default constructor
*/
public DPFavourites()
{
super();
@ -134,6 +137,10 @@ public class DPFavourites extends DashboardPanel implements EventListener<Event>
this.appendChild(toolbar);
} // DPFavourites
/**
* Create favourite tree panel
* @return Box
*/
private Box createFavoritePanel()
{
tree = new Tree();
@ -155,7 +162,7 @@ public class DPFavourites extends DashboardPanel implements EventListener<Event>
} // createFavoritePanel
/**
* Creating Tree structure
* Create Tree model ({@link #treeModel})
*/
public void initTreeModel()
{
@ -165,6 +172,7 @@ public class DPFavourites extends DashboardPanel implements EventListener<Event>
/**
* Event Like open Menu Window, Expand/Collapse Node, Add node into Tree
*/
@Override
public void onEvent(Event event)
{
String eventName = event.getName();
@ -201,6 +209,9 @@ public class DPFavourites extends DashboardPanel implements EventListener<Event>
}
} // onEvent
/**
* Open {@link LoginOpenSequenceDialog}
*/
private void doLoginOpenSeq()
{
LoginOpenSequenceDialog dialog = new LoginOpenSequenceDialog(Env.getAD_User_ID(Env.getCtx()));
@ -211,6 +222,7 @@ public class DPFavourites extends DashboardPanel implements EventListener<Event>
/**
* Add or Edit folder
* @param isAddFolder
*/
private void doFolderOpr(boolean isAddFolder)
{
@ -240,6 +252,10 @@ public class DPFavourites extends DashboardPanel implements EventListener<Event>
}
} // doExpandCollapseAll
/**
* @param tree
* @return Current selected MTreeNode
*/
public static MTreeNode getCurrentSelectedTreeNode(Tree tree)
{
Treeitem selItem = tree.getSelectedItem();
@ -252,13 +268,17 @@ public class DPFavourites extends DashboardPanel implements EventListener<Event>
return (MTreeNode) dtn.getData();
} // getCurrentSelectedTreeNode
/**
* @param tree
* @return Current selected Node_ID
*/
public static int getCurrentSelectedNodeID(Tree tree)
{
return getCurrentSelectedTreeNode(tree).getNode_ID();
} // getCurrentSelectedNodeID
/**
* Insert Node into Tree it's contains only Menu type node, Dragged from Menu Tab.
* Insert Node (Menu type node) into Tree, Dragged from Menu Tab.
*
* @param menuID - AD_Menu_ID
* @param parentNodeID - Parent AD_Favorite_Node_ID
@ -276,7 +296,7 @@ public class DPFavourites extends DashboardPanel implements EventListener<Event>
} // insertMenuInTree
/**
* Add Node in Tree view
* Add Node into Tree view
*
* @param treeModel - FavoriteSimpleTreeModel
* @param tree - Tree

View File

@ -17,17 +17,19 @@ import org.adempiere.webui.util.ZKUpdateUtil;
import org.zkoss.zul.Iframe;
/**
* Dashboard item: Google calendar
* Dashboard gadget: Google calendar
* @author Elaine
* @date November 20, 2008
*/
public class DPGoogleCalendar extends DashboardPanel {
/**
*
* generated serial id
*/
private static final long serialVersionUID = -6420016898259232438L;
/**
* Default constructor
*/
public DPGoogleCalendar()
{
super();

View File

@ -17,27 +17,31 @@ package org.adempiere.webui.dashboard;
import org.adempiere.webui.panel.MenuTreePanel;
/**
* Dashboard item: Menu Tree
* Dashboard gadget: Menu Tree
* @author Elaine
* @date July 31, 2012
*/
public class DPMenuTree extends DashboardPanel {
/**
*
* generated serial id
*/
private static final long serialVersionUID = -3095921038206382907L;
private MenuTreePanel menuTreePanel;
/**
* Default constructor
*/
public DPMenuTree()
{
super();
menuTreePanel = new MenuTreePanel(this);
this.appendChild(menuTreePanel);
}
/**
* @return {@link MenuTreePanel}
*/
public MenuTreePanel getMenuTreePanel()
{
return menuTreePanel;

View File

@ -24,7 +24,7 @@ import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.util.Clients;
/**
* Dashboard item: Performance Indicators
* Dashboard gadget: Performance Indicators
* @author Elaine
* @date November 20, 2008
*/
@ -36,6 +36,7 @@ public class DPPerformance extends DashboardPanel {
/** performance chart panel */
private WPAPanel paPanel;
/** {@link MGoal} performance records */
private MGoal[] performanceData;
/**

View File

@ -53,31 +53,37 @@ import org.zkoss.zul.Toolbar;
import org.zkoss.zul.Vbox;
/**
* Dashboard item: Recent Items
* Dashboard gadget: Recent Items
* @author Carlos Ruiz / GlobalQSS
* @date January 27, 2012
*/
public class DPRecentItems extends DashboardPanel implements EventListener<Event>, EventHandler {
private static final String AD_RECENT_ITEM_ID_ATTR = "AD_RecentItem_ID";
/**
*
* generated serial id
*/
private static final long serialVersionUID = 662950038476166515L;
/** Recent item link ({@link A}) attribute to store AD_RecentItem_ID value */
private static final String AD_RECENT_ITEM_ID_ATTR = "AD_RecentItem_ID";
/** Droppable identifier */
public static final String DELETE_RECENTITEMS_DROPPABLE = "deleteRecentItems";
private static TopicSubscriber topicSubscriber;
private Box bxRecentItems;
/** Login user id */
private int AD_User_ID;
private WeakReference<Desktop> desktop;
/** Desktop cleanup listener to call {@link #cleanup()} */
private DesktopCleanup listener;
/**
* Default constructor
*/
public DPRecentItems()
{
super();
@ -145,11 +151,17 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
};
}
/**
* Perform clean up
*/
protected void cleanup() {
EventManager.getInstance().unregister(this);
desktop = null;
}
/**
* Setup {@link #topicSubscriber}
*/
private static synchronized void createTopicSubscriber() {
if (topicSubscriber == null) {
topicSubscriber = new TopicSubscriber();
@ -162,7 +174,7 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
}
/**
* Make Recent Item remove persistent
* Remove recent item record from DB
* @param AD_RecentItem_ID Recent Item ID
* @return true if updated
*/
@ -175,6 +187,7 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
}
}
@Override
public void onEvent(Event event)
{
Component comp = event.getTarget();
@ -200,6 +213,10 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
}
}
/**
* Handle onClick event from recent item link/button
* @param comp Component
*/
private void doOnClick(Component comp) {
if (comp instanceof A)
{
@ -227,6 +244,9 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
}
}
/**
* Reload from DB
*/
private synchronized void refresh() {
// Please review here - is throwing NPE in some cases when user push repeatedly the refresh button
List<?> childs = bxRecentItems.getChildren();
@ -276,6 +296,10 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
}
/**
* Remove recent item link from {@link #bxRecentItems} and DB
* @param btn {@link A}
*/
private void removeLink(A btn) {
String value = (String) btn.getAttribute(AD_RECENT_ITEM_ID_ATTR);
@ -288,6 +312,9 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
}
}
/**
* @return icon font class or icon image url
*/
private String getIconFile() {
if (ThemeManager.isUseFontIconForImage())
return "z-icon-Window";
@ -311,7 +338,7 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
}
/**
*
* Update {@link #desktop} reference and setup {@link #listener}
*/
protected void updateDesktopReference() {
if ((desktop == null || desktop.get() == null) || (desktop.get() != null && desktop.get() != getDesktop())) {
@ -364,7 +391,14 @@ public class DPRecentItems extends DashboardPanel implements EventListener<Event
return true;
}
/**
* {@link ITopicSubscriber} for "onRecentItemChanged" topic. <br/>
* Call {@link MRecentItem#postOnChangedEvent(int)}.
*/
static class TopicSubscriber implements ITopicSubscriber<Integer> {
/**
* @param message AD_User_ID
*/
@Override
public void onMessage(Integer message) {
MRecentItem.postOnChangedEvent(message);

View File

@ -49,24 +49,33 @@ import org.zkoss.zul.Panelchildren;
import org.zkoss.zul.Toolbar;
import org.zkoss.zul.Vbox;
/**
* Dashboard gadget: running background jobs (Run As Job in Process Dialog).
*/
public class DPRunningJobs extends DashboardPanel implements EventListener<Event>, EventHandler {
/**
*
* generated serial id
*/
private static final long serialVersionUID = -8515643315156488709L;
/** Job link ({@link A}) attribute to store AD_PInstance_ID value */
private static final String AD_PINSTANCE_ID_ATTR = "AD_PInstance_ID";
private static TopicSubscriber topicSubscriber;
private Box bxJobs;
/** Login user id */
private int AD_User_ID;
private WeakReference<Desktop> desktop;
/** Desktop cleanup listener to call {@link #cleanup()} */
private DesktopCleanup listener;
/**
* Default constructor
*/
public DPRunningJobs()
{
super();
@ -114,12 +123,18 @@ public class DPRunningJobs extends DashboardPanel implements EventListener<Event
};
}
/**
* Perform clean up
*/
protected void cleanup()
{
EventManager.getInstance().unregister(this);
desktop = null;
}
/**
* Setup {@link #topicSubscriber}
*/
private static synchronized void createTopicSubscriber()
{
if (topicSubscriber == null) {
@ -142,6 +157,10 @@ public class DPRunningJobs extends DashboardPanel implements EventListener<Event
doOnClick(comp);
}
/**
* Handle onClick event from Job link/button
* @param comp Component
*/
private void doOnClick(Component comp)
{
if (comp instanceof A)
@ -166,6 +185,9 @@ public class DPRunningJobs extends DashboardPanel implements EventListener<Event
}
}
/**
* Reload from DB
*/
private synchronized void refresh()
{
// Please review here - is throwing NPE in some cases when user push repeatedly the refresh button
@ -197,6 +219,10 @@ public class DPRunningJobs extends DashboardPanel implements EventListener<Event
}
}
/**
* @param AD_User_ID
* @return List of running background jobs for AD_User_ID
*/
public static List<MPInstance> getRunningJobForUser(int AD_User_ID)
{
List<MPInstance> pis = new Query(Env.getCtx(), MPInstance.Table_Name, "Coalesce(AD_User_ID,0)=? AND IsProcessing='Y' AND IsRunAsJob='Y'", null)
@ -224,7 +250,7 @@ public class DPRunningJobs extends DashboardPanel implements EventListener<Event
}
/**
*
* Update {@link #desktop} reference and setup {@link #listener}
*/
protected void updateDesktopReference()
{
@ -280,7 +306,14 @@ public class DPRunningJobs extends DashboardPanel implements EventListener<Event
return true;
}
/**
* {@link ITopicSubscriber} for "onRunningJobChanged" topic. <br/>
* Call {@link MPInstance#postOnChangedEvent(int)}.
*/
static class TopicSubscriber implements ITopicSubscriber<Integer> {
/**
* @param message AD_User_ID
*/
@Override
public void onMessage(Integer message) {
MPInstance.postOnChangedEvent(message);

View File

@ -41,17 +41,19 @@ import org.zkoss.zul.Box;
import org.zkoss.zul.Vbox;
/**
* Dashboard item: Info views
* Dashboard gadget: List of Info views
* @author Elaine
* @date November 20, 2008
*/
public class DPViews extends DashboardPanel implements EventListener<Event> {
/**
*
* generated serial id
*/
private static final long serialVersionUID = 8375414665766937581L;
/**
* Default constructor
*/
public DPViews()
{
super();
@ -59,6 +61,10 @@ public class DPViews extends DashboardPanel implements EventListener<Event> {
this.appendChild(createViewPanel());
}
/**
* Layout panel
* @return {@link Box}
*/
private Box createViewPanel()
{
Vbox vbox = new Vbox();
@ -163,6 +169,7 @@ public class DPViews extends DashboardPanel implements EventListener<Event> {
return vbox;
}
@Override
public void onEvent(Event event)
{
Component comp = event.getTarget();
@ -202,7 +209,7 @@ public class DPViews extends DashboardPanel implements EventListener<Event> {
}
/**
* List of Info Windows to be displayed in the panel
* Info Window to be displayed in the panel
* @author nmicoud
*/
private class ListInfoWindow {
@ -210,15 +217,25 @@ public class DPViews extends DashboardPanel implements EventListener<Event> {
MInfoWindow iw = null;
int seqNo = 0;
/**
* @param infoWindow
* @param seqNo
*/
public ListInfoWindow(MInfoWindow infoWindow, int seqNo) {
iw = infoWindow;
this.seqNo = seqNo;
}
/**
* @return Sequence Number
*/
public int getSeqNo() {
return seqNo;
}
/**
* @return MInfoWindow
*/
public MInfoWindow getInfoWindow() {
return iw;
}

View File

@ -17,17 +17,20 @@ import org.adempiere.webui.component.Window;
import org.adempiere.webui.util.ServerPushTemplate;
/**
* Custom dashboard item base class
* Base class for dashboard gadget/widget
* @author Elaine
* @date November 20, 2008
*/
public abstract class DashboardPanel extends Window implements IDashboardPanel {
/**
*
* generated serial id
*/
private static final long serialVersionUID = 7424244218250118823L;
/**
* Default constructor
*/
public DashboardPanel()
{
super();
@ -57,7 +60,7 @@ public abstract class DashboardPanel extends Window implements IDashboardPanel {
}
/**
* Empty Dashboard Panels are not rendered on the Dashboard
* Empty Dashboard Panel are not rendered on the Dashboard
* @return true if the panel is empty
*/
public boolean isEmpty() {

View File

@ -33,28 +33,30 @@ import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.DesktopCleanup;
/**
*
* Runnable with weak reference to {@link Desktop} and a list of {@link DashboardPanel}.
* @author hengsin
* @author Cristina Ghita, www.arhipac.ro BF [2871741] Error at start
* @see https://sourceforge.net/p/adempiere/zk-web-client/327/
*/
public class DashboardRunnable implements Runnable, Serializable
{
/**
* generated serial id
*/
private static final long serialVersionUID = 5995227773511788894L;
private WeakReference<Desktop> desktop;
private List<DashboardPanel> dashboardPanels;
private Locale locale;
/** Desktop cleanup listener to call {@link #cleanup()} */
private DesktopCleanup listener;
@SuppressWarnings("unused")
private static final CLogger logger = CLogger.getCLogger(DashboardRunnable.class);
/**
*
* @param desktop zk desktop interface
* @param desktop zk Desktop instance
*/
public DashboardRunnable(Desktop desktop) {
this.desktop = new WeakReference<Desktop>(desktop);
@ -71,6 +73,9 @@ public class DashboardRunnable implements Runnable, Serializable
this.desktop.get().addListener(listener);
}
/**
* Perform clean up
*/
protected void cleanup() {
dashboardPanels = null;
if (desktop != null && desktop.get() != null)
@ -79,7 +84,8 @@ public class DashboardRunnable implements Runnable, Serializable
}
/**
* @param tmp
* Copy {@link #dashboardPanels} from tmp.
* @param tmp DashboardRunnable
* @param desktop
*/
public DashboardRunnable(DashboardRunnable tmp, Desktop desktop) {
@ -88,6 +94,10 @@ public class DashboardRunnable implements Runnable, Serializable
tmp.cleanup();
}
/**
* Refresh {@link #dashboardPanels} (usually call by background pooling thread).
* Delegate to {@link #refreshDashboard(boolean)}.
*/
@Override
public void run()
{
@ -104,11 +114,11 @@ public class DashboardRunnable implements Runnable, Serializable
}
/**
* Refresh dashboard content
* Refresh {@link #dashboardPanels}
* @param pooling true if calling from pooling thread
*/
public void refreshDashboard(boolean pooling)
{
ServerPushTemplate template = new ServerPushTemplate(desktop.get());
//set thread local context if not in event thread
Properties ctx = null;

View File

@ -39,14 +39,12 @@ import org.zkoss.zul.Center;
import org.zkoss.zul.South;
/**
*
* Window for Request Event
* @author Elaine
*
*/
public class EventWindow extends Window implements EventListener<Event> {
/**
*
* generated serial id
*/
private static final long serialVersionUID = 4758066526040260586L;
private DatetimeBox dtBeginDate, dtEndDate;
@ -55,6 +53,9 @@ public class EventWindow extends Window implements EventListener<Event> {
private int R_Request_ID = 0;
/**
* Default constructor
*/
public EventWindow() {
super();
@ -95,7 +96,6 @@ public class EventWindow extends Window implements EventListener<Event> {
confirmPanel = new ConfirmPanel(false, false, false, false, false, true);
confirmPanel.addActionListener(this);
Grid grid = GridFactory.newGridLayout();
Columns columns = new Columns();
@ -150,6 +150,10 @@ public class EventWindow extends Window implements EventListener<Event> {
south.appendChild(confirmPanel);
}
/**
* Update UI component with details from event
* @param event {@link ADCalendarEvent}
*/
public void setData(ADCalendarEvent event) {
txtHeaderColor.setStyle("background-color: " + event.getHeaderColor());
txtContentColor.setStyle("background-color: " + event.getContentColor());
@ -162,6 +166,7 @@ public class EventWindow extends Window implements EventListener<Event> {
confirmPanel.getButton(ConfirmPanel.A_ZOOM).setEnabled(R_Request_ID > 0);
}
@Override
public void onEvent(Event e) throws Exception {
if (e.getTarget() == confirmPanel.getButton(ConfirmPanel.A_OK))
setVisible(false);

View File

@ -45,34 +45,44 @@ import org.zkoss.zul.TreeNode;
import org.zkoss.zul.event.TreeDataEvent;
/**
* Favourite folder add or edit dialog
* Favourite add or edit folder dialog
*
* @author Logilite Technologies
*/
public class FavouriteFolderDialog extends Window implements EventListener<Event>
{
/**
*
* generated serial id
*/
private static final long serialVersionUID = -2838644830113603288L;
/** Folder name */
private Textbox txtFolder;
/** For add mode, true to add to root instead of current selected parent folder node. */
private Checkbox chkAddAsRoot;
/** For IsCollapsible */
private Checkbox chkDefaultExpanded;
private Label lblSelectedNodeInfo = new Label();
private Borderlayout mainLayout = new Borderlayout();
/** Center of {@link #mainLayout} */
private Panel centerPanel = new Panel();
/** Grid layout of {@link #centerPanel} */
private Grid grid = new Grid();
private ConfirmPanel confirmPanel = new ConfirmPanel(true);
/** Edit Mode: Node to edit. Add Mode: Parent folder node */
private MTreeFavoriteNode favNodeSummary;
private FavoriteSimpleTreeModel treeModel;
private Tree tree;
/** True for add mode, false for edit mode */
private boolean isAdd;
/**
* @param isAdd
* @param treeModel
* @param tree
*/
public FavouriteFolderDialog(boolean isAdd, FavoriteSimpleTreeModel treeModel, Tree tree)
{
super();
@ -86,6 +96,9 @@ public class FavouriteFolderDialog extends Window implements EventListener<Event
initAttributes();
}
/**
* Layout dialog
*/
private void init()
{
if (isAdd)
@ -245,6 +258,7 @@ public class FavouriteFolderDialog extends Window implements EventListener<Event
/**
* Insert Folder as Node to Tree.
* @param folderName
*/
private void insertFolder(String folderName)
{

View File

@ -17,7 +17,7 @@ import org.adempiere.webui.util.IServerPushCallback;
import org.adempiere.webui.util.ServerPushTemplate;
/**
* Interface for dashboard panel
* Interface for dashboard gadget/widget
* @author Elaine
* @author hengsin
*
@ -25,8 +25,9 @@ import org.adempiere.webui.util.ServerPushTemplate;
public interface IDashboardPanel extends IServerPushCallback {
/**
* Refresh content of panel. For performance reason, keep the activate of desktop as short
* as possible.
* Refresh content/model of panel. <br/>
* To keep UI responsive, long running operation should be perform here outside of Event Listener Thread.<br/>
* Update of UI components should happens in the updateUI method (on Event Listener Thread) and should be completed in a short period of time.
* @param template
*/
public void refresh(ServerPushTemplate template);

View File

@ -58,14 +58,14 @@ import org.zkoss.zul.Hlayout;
import org.zkoss.zul.South;
/**
* Favorite node login to open menu and its sequence configuration dialog
* Dialog to manage auto launch favourite items.
*
* @author Logilite Technologies
*/
public class LoginOpenSequenceDialog extends Window
{
/**
*
* generated serial id
*/
private static final long serialVersionUID = -6200912526954948898L;
@ -79,7 +79,9 @@ public class LoginOpenSequenceDialog extends Window
private ConfirmPanel confirmPanel = new ConfirmPanel(true, false, true, false, false, false);
/** model for {@link #noList} */
private SimpleListModel noModel = new SimpleListModel();
/** model for {@link #yesList} */
private SimpleListModel yesModel = new SimpleListModel();
private Listbox noList = new Listbox();
@ -88,6 +90,7 @@ public class LoginOpenSequenceDialog extends Window
private Label noLabel = new Label();
private Label yesLabel = new Label();
/** List for auto launch sequence */
private ArrayList<Integer> autoOpenSeqs = new ArrayList<Integer>();
private int m_AD_User_ID;
@ -371,7 +374,7 @@ public class LoginOpenSequenceDialog extends Window
/**
* @param event - Event
*/
void migrateValueAcrossLists(Event event)
protected void migrateValueAcrossLists(Event event)
{
Object source = event.getTarget();
if (source instanceof ListItem)
@ -393,7 +396,7 @@ public class LoginOpenSequenceDialog extends Window
* @param listTo
* @param endIndex
*/
void migrateLists(Listbox listFrom, Listbox listTo, int endIndex)
protected void migrateLists(Listbox listFrom, Listbox listTo, int endIndex)
{
int index = 0;
SimpleListModel lmFrom = (SimpleListModel) listFrom.getModel();
@ -425,7 +428,7 @@ public class LoginOpenSequenceDialog extends Window
*
* @param event - Event
*/
void migrateValueWithinYesList(int endIndex, List<ListElement> selObjects)
protected void migrateValueWithinYesList(int endIndex, List<ListElement> selObjects)
{
int iniIndex = 0;
Arrays.sort(selObjects.toArray());
@ -445,7 +448,7 @@ public class LoginOpenSequenceDialog extends Window
*
* @param event - Event
*/
void migrateValueWithinYesList(Event event)
protected void migrateValueWithinYesList(Event event)
{
Object[] selObjects = yesList.getSelectedItems().toArray();
@ -510,7 +513,7 @@ public class LoginOpenSequenceDialog extends Window
} // migrateValueWithinYesList
/**
* Save Login open sequence no
* Save auto launch configuration to DB
*/
public void saveData()
{
@ -560,7 +563,7 @@ public class LoginOpenSequenceDialog extends Window
private static class ListElement extends NamePair
{
/**
*
* generated serial id
*/
private static final long serialVersionUID = -1717531470895073281L;
@ -621,13 +624,12 @@ public class LoginOpenSequenceDialog extends Window
} // ListElement
/**
* Drag Listener
* Listener for onDrop event
*/
private class DragListener implements EventListener<Event>
{
/**
* Creates a ADSortTab.DragListener.
* Default constructor
*/
public DragListener()
{

View File

@ -53,14 +53,12 @@ import org.zkoss.zul.Center;
import org.zkoss.zul.South;
/**
*
* Window for request
* @author Elaine
*
*/
public class RequestWindow extends Window implements EventListener<Event> {
/**
*
* generated serial id
*/
private static final long serialVersionUID = 7757368164776005797L;
@ -79,6 +77,10 @@ public class RequestWindow extends Window implements EventListener<Event> {
private Window parent;
private Calendar calBegin,calEnd;
/**
* @param ce CalendarsEvent
* @param parent
*/
public RequestWindow(CalendarsEvent ce, Window parent) {
super();
@ -279,6 +281,7 @@ public class RequestWindow extends Window implements EventListener<Event> {
tbxEndTime.setValue(ce.getEndDate());
}
@Override
public void onEvent(Event e) throws Exception {
if (m_readOnly)
this.detach();
@ -322,7 +325,6 @@ public class RequestWindow extends Window implements EventListener<Event> {
{
if (log.isLoggable(Level.FINE)) log.fine("R_Request_ID=" + request.getR_Request_ID());
Events.postEvent("onRefresh", parent, null);
// Events.echoEvent("onRefresh", parent, null);
}
else
{
@ -336,7 +338,10 @@ public class RequestWindow extends Window implements EventListener<Event> {
this.detach();
}
//Check, Start time is not >= End time, when Start Plan == Complete Plan
/**
* Check, Start time is not >= End time, when Start Plan == Complete Plan
* @return true if {@link #calBegin} >= {@link #calEnd}, false otherwise (true indicate error)
*/
private boolean checkTime()
{
calBegin = Calendar.getInstance();

View File

@ -36,9 +36,8 @@ import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zul.Window.Mode;
/**
* Base class for desktop implementation
* Abstract base class for {@link IDesktop} implementation
* @author hengsin
*
*/
public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop {
@ -50,11 +49,14 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
@SuppressWarnings("unused")
private static final CLogger logger = CLogger.getCLogger(AbstractDesktop.class);
/**
* Default constructor
*/
public AbstractDesktop() {
}
/**
* Event listener for menu item selection.
* Event listener for menu item selection.<br/>
* Identifies the action associated with the selected
* menu item and acts accordingly.
*
@ -63,6 +65,7 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
* @throws ApplicationException If the selected menu action has yet
* to be implemented
*/
@Override
public void onMenuSelected(int menuId)
{
MMenu menu = MMenu.get(menuId);
@ -109,14 +112,13 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
}
/**
* @return clientInfo
* @return {@link ClientInfo}
*/
public ClientInfo getClientInfo() {
return clientInfo;
}
/**
*
* @param clientInfo
*/
public void setClientInfo(ClientInfo clientInfo) {
@ -125,6 +127,7 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
/**
* @param win
* @param registered Window Number (start from 0)
*/
public int registerWindow(Object win) {
List<Object> windows = getWindows();
@ -134,6 +137,7 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
}
/**
* Remove from registered window list and clear environment context
* @param WindowNo
*/
public void unregisterWindow(int WindowNo) {
@ -144,7 +148,7 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
}
/**
*
* Find window by registered window number
* @param WindowNo
* @return Object
*/
@ -158,24 +162,25 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
@Override
public int findWindowNo(Component component) {
if (component == null)
return -1;
if (component == null)
return -1;
List<Object> windows = getWindows();
if (windows != null) {
if (windows.contains(component))
return windows.indexOf(component);
Component parent = component.getParent();
while (parent != null) {
if (windows.contains(parent))
return windows.indexOf(parent);
parent = parent.getParent();
}
}
List<Object> windows = getWindows();
if (windows != null) {
if (windows.contains(component))
return windows.indexOf(component);
Component parent = component.getParent();
while (parent != null) {
if (windows.contains(parent))
return windows.indexOf(parent);
parent = parent.getParent();
}
}
return -1;
}
/**
* Delegate to {@link #showWindow(Window, String)}
* @param win
*/
public void showWindow(Window win)
@ -185,10 +190,10 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
}
/**
* when width of win set by stylesheet (css class or in style) win sometime don't in center.
* fix by find out method change to {@link LayoutUtils#openOverlappedWindow(org.zkoss.zk.ui.Component, org.zkoss.zul.Window, String)}
* @param win
* @param pos
* When width of win set by stylesheet (css class or in style) win sometime don't position in center.<br/>
* To workaround that, use {@link LayoutUtils#openOverlappedWindow(org.zkoss.zk.ui.Component, org.zkoss.zul.Window, String)}.
* @param win Window
* @param pos see {@link org.zkoss.zul.Window#setPosition(String)}
*/
public void showWindow(final Window win, final String pos)
{
@ -218,6 +223,12 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
}
}
/**
*
* @param win Window
* @param pos see {@link org.zkoss.zul.Window#setPosition(String)}
* @param mode {@link Mode} (POPUP, OVERLAPPED, EMBEDDED or HIGHLIGHTED)
*/
private void showNonModalWindow(final Window win, final String pos,
final Mode mode) {
if (Mode.POPUP == mode)
@ -238,10 +249,14 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
}
}
/**
* Show {@link Mode#EMBEDDED} window
* @param win
*/
protected abstract void showEmbedded(Window win);
/**
*
* Show modal window.
* @param win
*/
protected void showModal(final Window win)
@ -289,9 +304,9 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
}
/**
*
* @param win
* @param position
* Show {@link Mode#POPUP} window
* @param win Window
* @param position see {@link org.zkoss.zul.Window#setPosition(String)}
*/
protected void showPopup(Window win, String position)
{
@ -306,9 +321,9 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
}
/**
*
* @param win
* @param position
* Show {@link Mode#OVERLAPPED} window
* @param win Window
* @param position see {@link org.zkoss.zul.Window#setPosition(String)}
*/
protected void showOverlapped(Window win, String position)
{
@ -323,9 +338,9 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
}
/**
*
* @param win
* @param position
* Show {@link Mode#HIGHLIGHTED} window
* @param win Window
* @param position see {@link org.zkoss.zul.Window#setPosition(String)}
*/
protected void showHighlighted(Window win, String position)
{
@ -339,6 +354,9 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
win.focus();
}
/**
* @return List of registered windows
*/
protected List<Object> getWindows(){
Desktop desktop = getComponent().getDesktop();
if (desktop != null) {
@ -355,18 +373,30 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
}
}
/**
* @param predefinedVariables
*/
public void setPredefinedContextVariables(String predefinedVariables) {
this.predefinedContextVariables = predefinedVariables;
}
/**
* @return {@link #predefinedContextVariables}
*/
protected String getPredefinedContextVariables() {
return this.predefinedContextVariables;
}
/**
* @param isSOTrx
*/
public void setMenuIsSOTrx(boolean isSOTrx) {
this.menuIsSOTrx = isSOTrx;
}
/**
* @return {@link #menuIsSOTrx}
*/
protected boolean isMenuSOTrx() {
return this.menuIsSOTrx;
}

View File

@ -124,8 +124,8 @@ import org.zkoss.zul.Toolbarbutton;
import org.zkoss.zul.Vlayout;
/**
* Dashboard renderer and controller
* @author hengsin
*
*/
public class DashboardController implements EventListener<Event> {
@ -134,14 +134,21 @@ public class DashboardController implements EventListener<Event> {
private Component prevParent;
private Component prevNext;
/** dashboard gadget panels */
private List<Panel> panelList = new ArrayList<Panel>();
/** For column orientation */
private List<Anchorchildren> columnList;
/** For row orientation */
private List<Anchorchildren> rowList;
private Anchorlayout dashboardLayout;
private Anchorchildren maximizedHolder;
/** Runnable for pooling refresh of dashboard gadgets */
private DashboardRunnable dashboardRunnable;
/** Timer for {@link #dashboardRunnable} */
private Timer dashboardTimer;
/** True for dashboard, false for left/right side panel */
private boolean isShowInDashboard;
/** number of columns for column oriented dashboard */
private int noOfCols;
private static final String PANEL_EMPTY_ATTRIBUTE = "panel.empty";
@ -153,10 +160,15 @@ public class DashboardController implements EventListener<Event> {
private static final String FLEX_GROW_ATTRIBUTE = "FlexGrow";
private static final String IMAGES_CONTEXT_HELP_PNG = "images/Help16.png";
/** Default total width for column oriented layout (in percentage) */
private final static int DEFAULT_DASHBOARD_WIDTH = 99;
/** Column orientation */
private final static String DASHBOARD_LAYOUT_COLUMNS = "C";
/** Row orientation */
private final static String DASHBOARD_LAYOUT_ROWS = "R";
/** Max number of gadgets in a row. For row oriented layout. */
private final static int MAX_NO_OF_PREFS_IN_ROW = 10;
/** Default horizontal flex grow for dashboard gadget. For row oriented layout. */
private final static int DEFAULT_FLEX_GROW = 1;
/**
@ -174,10 +186,10 @@ public class DashboardController implements EventListener<Event> {
}
/**
*
* @param parent
* @param desktopImpl
* @param isShowInDashboard
* Render main or side dashboard
* @param parent Parent Component of dashboard
* @param desktopImpl IDesktop
* @param isShowInDashboard true for main/center dashboard, false for left/right side dashboard
*/
public void render(Component parent, IDesktop desktopImpl, boolean isShowInDashboard) {
@ -188,6 +200,13 @@ public class DashboardController implements EventListener<Event> {
renderColumns(parent, desktopImpl, isShowInDashboard, false);
}
/**
* Render dashboard in column orientation
* @param parent Component
* @param desktopImpl IDesktop
* @param isShowInDashboard true for dashboard, false for left/right side panel
* @param update true for update, false for new
*/
protected void renderColumns(Component parent, IDesktop desktopImpl, boolean isShowInDashboard, boolean update) {
this.isShowInDashboard = isShowInDashboard;
if (!update)
@ -371,6 +390,12 @@ public class DashboardController implements EventListener<Event> {
}
}
/**
* Create new gadget panel
* @param dp
* @param dc
* @return {@link Panel}
*/
private Panel newGadgetPanel(MDashboardPreference dp, MDashboardContent dc) {
Panel panel;
panel = new Panel();
@ -402,6 +427,11 @@ public class DashboardController implements EventListener<Event> {
return panel;
}
/**
* Render help button for individual dashboard gadget
* @param caption
* @param text
*/
private void renderHelpButton(Caption caption, String text) {
A help = new A();
help.setSclass("dashboard-content-help-icon");
@ -433,12 +463,12 @@ public class DashboardController implements EventListener<Event> {
/**
* Render gadget panel in background thread
* @param spt
* @param dashboardContent
* @param panel
* @param spt ServerPushTemplate
* @param dashboardContent MDashboardContent
* @param panel Panel
* @param contextPath
* @param panelChildren
* @param zulComponent
* @param panelChildren Panelchildren
* @param zulComponent Component created from zul in Event Listener thread
* @throws Exception
*/
private void asyncRenderGadgetPanel(ServerPushTemplate spt, MDashboardContent dashboardContent, Panel panel, String contextPath,
@ -479,6 +509,10 @@ public class DashboardController implements EventListener<Event> {
}
}
/**
* Start {@link #dashboardRunnable} for pooling refresh of dashboard gadgets (using {@link #dashboardTimer})
* @param parent
*/
private void startDashboardRunnable(Component parent) {
// default Update every one minutes
int interval = MSysConfig.getIntValue(MSysConfig.ZK_DASHBOARD_REFRESH_INTERVAL, 60000);
@ -496,6 +530,13 @@ public class DashboardController implements EventListener<Event> {
dashboardTimer.setPage(parent.getPage());
}
/**
* Render dashboard in row orientation
* @param parent
* @param desktopImpl
* @param isShowInDashboard
* @param update
*/
protected void renderRows(Component parent, IDesktop desktopImpl, boolean isShowInDashboard, boolean update) {
this.isShowInDashboard = isShowInDashboard;
if (!update)
@ -670,7 +711,6 @@ public class DashboardController implements EventListener<Event> {
{
logger.log(Level.WARNING, "Failed to create dashboard content", e);
}
//
if (!update)
{
@ -678,6 +718,12 @@ public class DashboardController implements EventListener<Event> {
}
}
/**
* Find dashboard gadget panel by PA_DashboardContent_ID and PA_DashboardPreference_ID
* @param PA_DashboardContent_ID
* @param PA_DashboardPreference_ID
* @return {@link Panel}
*/
private Panel findPanel(int PA_DashboardContent_ID, int PA_DashboardPreference_ID) {
for(Panel panel : panelList) {
Object value1 = panel.getAttribute(MDashboardPreference.COLUMNNAME_PA_DashboardContent_ID);
@ -694,13 +740,13 @@ public class DashboardController implements EventListener<Event> {
/**
* Create gadget components in background thread
* @param dashboardContent
* @param dashboardRunnable
* @param dashboardContent MDashboardContent
* @param dashboardRunnable DashboardRunnable
* @param contextPath
* @param parentComponent
* @param components
* @param zulComponent
* @param spt
* @param components list to add created Component
* @param zulComponent Component created from zul in Event Listener thread
* @param spt ServerPushTemplate
* @throws Exception
*/
private void asyncRenderComponents(MDashboardContent dashboardContent, DashboardRunnable dashboardRunnable, String contextPath,
@ -932,10 +978,10 @@ public class DashboardController implements EventListener<Event> {
}
/**
* Synchronous render of gadget content in foreground ui thread
* Synchronous render of gadget content in foreground UI (Event Listener) thread
* @param content must be an instanceof {@link HtmlBasedComponent}
* @param dashboardContent
* @param dashboardRunnable
* @param dashboardContent MDashboardContent
* @param dashboardRunnable DashboardRunnable
* @return true if gadget dashboard is not empty
* @throws Exception
*/
@ -974,8 +1020,9 @@ public class DashboardController implements EventListener<Event> {
}
/**
* Add Drill Across Event Listener to Border Layout
* @param processID
* Add onDrillAcross, onZoom and onDrillDown Event Listener to component
* @param processID AD_Process_ID
* @param component Component
*/
private void addDrillAcrossEventListener(int processID, Component component) {
component.addEventListener(DrillEvent.ON_DRILL_ACROSS, new EventListener<Event>() {
@ -1021,7 +1068,7 @@ public class DashboardController implements EventListener<Event> {
/**
* Execute Drill to Query
* @param query query
* @param query MQuery
*/
private void executeDrill (MQuery query)
{
@ -1212,6 +1259,11 @@ public class DashboardController implements EventListener<Event> {
return wrapper;
}
/**
* Create and save dashboard preference (MDashboardPreference) to DB.
* @param AD_User_ID
* @param AD_Role_ID
*/
private void createDashboardPreference(int AD_User_ID, int AD_Role_ID)
{
MDashboardContent[] dcs = MDashboardContentAccess.get(Env.getCtx(),AD_Role_ID, AD_User_ID, null);
@ -1232,7 +1284,13 @@ public class DashboardController implements EventListener<Event> {
}
}
/**
* Update dashboard preference (MDashboardPreference) in DB.
* @param dps
* @param dcs
* @param ctx
* @return true if there are changes
*/
private boolean updatePreferences(MDashboardPreference[] dps,MDashboardContent[] dcs, Properties ctx) {
boolean change = false;
for (int i = 0; i < dcs.length; i++) {
@ -1273,6 +1331,11 @@ public class DashboardController implements EventListener<Event> {
return change;
}
/**
* Save dashboard preference (MDashboardPreference) to DB.
* @param layout
* @param prevLayout
*/
private void saveDashboardPreference(Component layout, Component prevLayout)
{
String layoutOrientation = MSysConfig.getValue(MSysConfig.DASHBOARD_LAYOUT_ORIENTATION, Env.getAD_Client_ID(Env.getCtx()));
@ -1456,7 +1519,6 @@ public class DashboardController implements EventListener<Event> {
}
/**
*
* @param page
* @param desktop
*/
@ -1484,12 +1546,22 @@ public class DashboardController implements EventListener<Event> {
dashboardLayout = null;
}
/**
* add dashboardPanel to {@link #dashboardRunnable}
* @param dashboardPanel
*/
private void addDashboardPanel(DashboardPanel dashboardPanel) {
if (dashboardRunnable != null) {
dashboardRunnable.add(dashboardPanel);
}
}
/**
* Strip &lt;html&gt;, &lt;body&gt; and &lt;head&gt; tag
* @param htmlString
* @param all true to escpae &lt; and &gt;
* @return stripped htmlString
*/
private String stripHtml(String htmlString, boolean all) {
htmlString = htmlString
.replace("<html>", "")
@ -1506,6 +1578,13 @@ public class DashboardController implements EventListener<Event> {
return htmlString;
}
/**
* Run report
* @param AD_Process_ID
* @param AD_PrintFormat_ID
* @param parameters Report parameters
* @return {@link ReportEngine}
*/
private ReportEngine runReport(int AD_Process_ID, int AD_PrintFormat_ID, String parameters) {
MProcess process = MProcess.get(Env.getCtx(), AD_Process_ID);
if (!process.isReport() || process.getAD_ReportView_ID() == 0)
@ -1546,6 +1625,16 @@ public class DashboardController implements EventListener<Event> {
}
/**
* Generate report media (html)
* @param AD_Process_ID
* @param AD_PrintFormat_ID
* @param parameters
* @param component
* @param contextPath
* @return {@link AMedia}
* @throws Exception
*/
private AMedia generateReport(int AD_Process_ID, int AD_PrintFormat_ID, String parameters, Component component, String contextPath) throws Exception {
ReportEngine re = runReport(AD_Process_ID, AD_PrintFormat_ID, parameters);
if(re == null)
@ -1556,6 +1645,12 @@ public class DashboardController implements EventListener<Event> {
return new AMedia(re.getName(), "html", "text/html", file, false);
}
/**
* Run report and open in report viewer
* @param AD_Process_ID
* @param AD_PrintFormat_ID
* @param parameters
*/
protected void openReportInViewer(int AD_Process_ID, int AD_PrintFormat_ID, String parameters) {
ReportEngine re = runReport(AD_Process_ID, AD_PrintFormat_ID, parameters);
new ZkReportViewerProvider().openViewer(re);
@ -1747,10 +1842,8 @@ public class DashboardController implements EventListener<Event> {
MProcessPara pp = MProcess.get(i.getAD_Process_ID()).getParameter(ip.getParameterName());
if (pp != null) {
MLookupInfo mli = MLookupFactory.getLookupInfo(Env.getCtx(), 0, 0, pp.getAD_Reference_ID(), Env.getLanguage(Env.getCtx()), pp.getColumnName(), pp.getAD_Reference_Value_ID(), false, "");
PreparedStatement pstmt = null;
ResultSet rs = null;
StringBuilder name = new StringBuilder("");
@ -1793,7 +1886,6 @@ public class DashboardController implements EventListener<Event> {
}
/**
*
* @param clientInfo
*/
public void updateLayout(ClientInfo clientInfo) {
@ -1819,6 +1911,14 @@ public class DashboardController implements EventListener<Event> {
}
}
/**
* Render chart
* @param chartPanel
* @param width
* @param height
* @param model {@link ChartModel}
* @param showTitle
*/
private void renderChart(final Div chartPanel, int width, int height, ChartModel model, boolean showTitle) {
List<IChartRendererService> list = Extensions.getChartRendererServices();
for (IChartRendererService renderer : list) {

View File

@ -101,7 +101,7 @@ import org.zkoss.zul.West;
/**
*
* Default desktop implementation.
* Default {@link IDesktop} 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
@ -110,12 +110,8 @@ import org.zkoss.zul.West;
*/
public class DefaultDesktop extends TabbedDesktop implements MenuListener, Serializable, EventListener<Event>, EventHandler, DesktopCleanup
{
private static final String POPUP_OPEN_ATTR = "popup.open";
private static final String HOME_TAB_RENDER_ATTR = "homeTab.render";
/**
*
* generated serial id
*/
private static final long serialVersionUID = 7189914859100400758L;
@ -127,49 +123,73 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
private static final String IMAGES_THREELINE_MENU_PNG = "images/threelines.png";
private static final String POPUP_OPEN_ATTR = "popup.open";
private static final String HOME_TAB_RENDER_ATTR = "homeTab.render";
private static final String HELP_CONTROLLER_WIDTH_PREFERENCE = "HelpController.Width";
private static final String SIDE_CONTROLLER_WIDTH_PREFERENCE = "SideController.Width";
@SuppressWarnings("unused")
private static final CLogger logger = CLogger.getCLogger(DefaultDesktop.class);
/** Main layout. With id "layout" in desktop.zul */
private Borderlayout layout;
private int noCount;
/** Panel of home tab */
private Tabpanel homeTab;
private DashboardController dashboardController, sideController;
/** HeaderPanel of {@link #headerContainer}. With id "header" in desktop.zul */
private HeaderPanel pnlHead;
private Desktop m_desktop = null;
/** Renderer and controller for help and quick info panel */
private HelpController helpController;
/** Button to hide or show North desktop header. Visible for mobile client. */
private ToolBarButton max;
/** Button to hide or show help and quick info panels */
private ToolBarButton contextHelp;
/** Button to open north header popup. Visible when {@link #max} is true. */
private ToolBarButton showHeader;
/** Body component of north header. With id "northBody" in desktop.zul */
private Component headerContainer;
/** Popup open by {@link #showHeader} */
private Window headerPopup;
private Image logo;
/** true if client browser is a mobile browser */
private boolean mobile;
/** Help and quick info popup for mobile client */
private Popup eastPopup;
/** West panel popup for mobile client */
private Popup westPopup;
/** Button to show {@link #westPopup}. Visible for mobile client. */
private ToolBarButton westBtn;
// For quick info optimization
private GridTab gridTab;
// Right side Quick info is visible
/** True if Right side Quick info is visible */
private boolean isQuickInfoOpen = true;
/**
* Default constructor
*/
public DefaultDesktop()
{
super();
@ -191,6 +211,9 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
queue.subscribe(this);
}
/**
* Create desktop layout from "zul/desktop/desktop.zul".
*/
@SuppressWarnings("serial")
protected Component doCreatePart(Component parent)
{
@ -446,9 +469,11 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
return layout;
}
/**
* @return saved width for west panel. null if there's no saved width.
*/
private String getWestWidthPreference() {
String width = Env.getPreference(Env.getCtx(), 0, "SideController.Width", false);
String width = Env.getPreference(Env.getCtx(), 0, SIDE_CONTROLLER_WIDTH_PREFERENCE, false);
if( (! Util.isEmpty(width)) ){
ClientInfo browserInfo = getClientInfo();
@ -462,8 +487,11 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
return null;
}
/**
* Save width of west panel as user preference
* @param width
*/
protected void updateSideControllerWidthPreference(String width) {
if( width != null ){
Query query = new Query(Env.getCtx(),
MTable.get(Env.getCtx(), I_AD_Preference.Table_ID),
@ -474,14 +502,13 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
MPreference preference = query.setOnlyActiveRecords(true)
.setApplyAccessFilter(true)
.setClient_ID()
.setParameters("SideController.Width", userId)
.setParameters(SIDE_CONTROLLER_WIDTH_PREFERENCE, userId)
.first();
if ( preference == null || preference.getAD_Preference_ID() <= 0 ) {
preference = new MPreference(Env.getCtx(), 0, null);
preference.setAD_User_ID(userId); // allow System
preference.setAttribute("SideController.Width");
preference.setAttribute(SIDE_CONTROLLER_WIDTH_PREFERENCE);
}
preference.setValue(width);
preference.saveEx();
@ -490,9 +517,11 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
}
/**
* @return saved width of east/help panel. null if there's no saved width.
*/
private String getEastWidthPreference() {
String width = Env.getPreference(Env.getCtx(), 0, "HelpController.Width", false);
String width = Env.getPreference(Env.getCtx(), 0, HELP_CONTROLLER_WIDTH_PREFERENCE, false);
if( (! Util.isEmpty(width)) ){
ClientInfo browserInfo = getClientInfo();
@ -506,8 +535,11 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
return null;
}
/**
* Save width of east/help panel as user preference
* @param width
*/
protected void updateHelpWidthPreference(String width) {
if( width != null ){
Query query = new Query(Env.getCtx(),
MTable.get(Env.getCtx(), I_AD_Preference.Table_ID),
@ -518,14 +550,13 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
MPreference preference = query.setOnlyActiveRecords(true)
.setApplyAccessFilter(true)
.setClient_ID()
.setParameters("HelpController.Width", userId)
.setParameters(HELP_CONTROLLER_WIDTH_PREFERENCE, userId)
.first();
if ( preference == null || preference.getAD_Preference_ID() <= 0 ) {
preference = new MPreference(Env.getCtx(), 0, null);
preference.setAD_User_ID(userId); // allow System
preference.setAttribute("HelpController.Width");
preference.setAttribute(HELP_CONTROLLER_WIDTH_PREFERENCE);
}
preference.setValue(width);
preference.saveEx();
@ -533,24 +564,40 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
}
/**
* Save west/menu panel collapsed state as user preference
* @param collapsed
*/
private void updateMenuCollapsedPreference(boolean collapsed) {
UserPreference pref = SessionManager.getSessionApplication().getUserPreference();
pref.setProperty(UserPreference.P_MENU_COLLAPSED, collapsed);
pref.savePreference();
}
/**
* Save east/help panel collapsed state as user preference
* @param collapsed
*/
private void updateHelpCollapsedPreference(boolean collapsed) {
UserPreference pref = SessionManager.getSessionApplication().getUserPreference();
pref.setProperty(UserPreference.P_HELP_COLLAPSED, collapsed);
pref.savePreference();
}
/**
* Save page/desktop header collapsed state as user preference
* @param collapsed
*/
private void updateHeaderCollapsedPreference(boolean collapsed) {
UserPreference pref = SessionManager.getSessionApplication().getUserPreference();
pref.setProperty(UserPreference.P_HEADER_COLLAPSED, collapsed);
pref.savePreference();
}
/**
* Render content of home tab.<br/>
* Delegate to {@link DashboardController#render(Component, IDesktop, boolean)}
*/
public void renderHomeTab()
{
homeTab.getChildren().clear();
@ -609,6 +656,10 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
homeTab.invalidate();
}
/**
* Set width of popup for side panel
* @param popup
*/
protected void setSidePopupWidth(Popup popup) {
if (ClientInfo.minWidth(ClientInfo.LARGE_WIDTH))
popup.setWidth("30%");
@ -624,6 +675,7 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
popup.setWidth("80%");
}
@Override
public void onEvent(Event event)
{
Component comp = event.getTarget();
@ -697,6 +749,9 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
}
}
/**
* Make page/desktop header visible again
*/
protected void restoreHeader() {
layout.getNorth().setVisible(true);
if (ThemeManager.isUseFontIconForImage())
@ -710,6 +765,9 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
updateHeaderCollapsedPreference(false);
}
/**
* Hide page/desktop header
*/
protected void collapseHeader() {
layout.getNorth().setVisible(false);
if (ThemeManager.isUseFontIconForImage())
@ -739,7 +797,6 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
}
/**
*
* @param page
*/
public void setPage(Page page) {
@ -789,6 +846,11 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
}
}
/**
* Asynchronous logout. Call by {@link #logout(Callback)}.<br/>
* This is to workaround client side detached element leak.
* @param callback
*/
private void asyncLogout(Callback<Boolean> callback) {
unbindEventManager();
if (dashboardController != null) {
@ -816,14 +878,22 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
m_desktop = null;
}
/**
* Update home tab title after {@link #ON_ACTIVITIES_CHANGED_EVENT}
*/
public void updateUI() {
windowContainer.setTabTitle(0, Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Home")) + " (" + noCount + ")", null);
}
//use _docClick undocumented api. need verification after major zk release update
/**
* use _docClick undocumented api. need verification after major zk release update
*/
private final static String autoHideMenuScript = "(function(){try{let w=zk.Widget.$('#{0}');let t=zk.Widget.$('#{1}');" +
"let e=new Object;e.target=t;w._docClick(e);}catch(error){}})()";
/**
* Auto hide west panel or popup
*/
private void autoHideMenu() {
if (mobile) {
if (westPopup.getAttribute(POPUP_OPEN_ATTR) != null) {
@ -852,19 +922,23 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
autoHideMenu();
}
//Implementation for Broadcast message
/**
* Implementation for Broadcast message
*/
public void bindEventManager() {
EventManager.getInstance().register(IEventTopics.BROADCAST_MESSAGE, this);
}
/**
* Clean up for Broadcast message
*/
public void unbindEventManager() {
EventManager.getInstance().unregister(this);
}
/**
* Handle OSGi event for Broadcast message
*/
@Override
public void handleEvent(final org.osgi.service.event.Event event) {
String eventName = event.getTopic();
@ -1029,7 +1103,10 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
}
}
int getMenuID()
/**
* @return Menu tree ID for login role
*/
protected int getMenuID()
{
int AD_Role_ID = Env.getAD_Role_ID(Env.getCtx());
int AD_Tree_ID = DB.getSQLValue(null,
@ -1042,6 +1119,11 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
return AD_Tree_ID;
}
/**
* Process auto launch configuration after login (store in AD_Tree_Favorite_Node)
* @param ctx
*/
private void automaticOpen(Properties ctx) {
if (isActionURL()) // IDEMPIERE-2334 vs IDEMPIERE-3000 - do not open windows when coming from an action URL
return;
@ -1107,6 +1189,9 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
}
}
/**
* Update width of side panel
*/
private void updateSideLayout() {
if (westPopup != null && westPopup.getChildren().size() > 1)
setSidePopupWidth(westPopup);
@ -1114,6 +1199,9 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
setSidePopupWidth(eastPopup);
}
/**
* @return true if there's Action parameter in URL
*/
private boolean isActionURL() {
ConcurrentMap<String, String[]> parameters = new ConcurrentHashMap<String, String[]>(Executions.getCurrent().getParameterMap());
String action = "";

View File

@ -33,8 +33,9 @@ import org.zkoss.zul.Tree;
*/
public class FavouriteController
{
private static final String DESKTOP_FAVOURITE_CONTROLLER = "desktop.FavouriteController";
/** Session attribute to store FavouriteController reference */
private static final String DESKTOP_FAVOURITE_CONTROLLER = "desktop.FavouriteController";
/** Node_ID:MTreeNode */
private Map<Integer, MTreeNode> nodeMap;
private int m_AD_Tree_Favorite_ID;
@ -45,11 +46,18 @@ public class FavouriteController
private Tree tree;
private FavoriteSimpleTreeModel treeModel;
/**
* Private constructor.<br/>
* Use {@link #getInstance(Session)} to get singleton instance for a Session.
*/
private FavouriteController()
{
init();
}
/**
* Load user favourites
*/
private void init()
{
nodeMap = new LinkedHashMap<>();
@ -102,7 +110,7 @@ public class FavouriteController
* Get favourites controller instance for current session
*
* @param currSess
* @return FavouriteController session instance
* @return FavouriteController session instance
*/
public static synchronized FavouriteController getInstance(Session currSess)
{
@ -116,6 +124,12 @@ public class FavouriteController
return controller;
} // getInstance
/**
*
* @param add true for add, false for delete
* @param Menu_ID
* @return true if add/delete is successful
*/
private boolean barUpdate(boolean add, int Menu_ID)
{
if (add)
@ -144,7 +158,7 @@ public class FavouriteController
* Add node (by node id) to favourties
*
* @param nodeId
* @return true if successfully added
* @return true if successfully added
*/
public boolean addNode(int nodeId)
{
@ -160,7 +174,7 @@ public class FavouriteController
* add tree node to favourites
*
* @param node
* @return true if successfully added
* @return true if successfully added
*/
public boolean addNode(MTreeNode node)
{
@ -188,7 +202,7 @@ public class FavouriteController
* remove node (by node id) from favourites
*
* @param nodeId
* @return true if found and remove
* @return true if found and remove
*/
public boolean removeNode(int nodeId)
{
@ -213,7 +227,7 @@ public class FavouriteController
/**
* @param nodeId
* @return true if node id is in the current favourites list
* @return true if node id is in the current favourites list
*/
public boolean hasNode(int nodeId)
{
@ -253,16 +267,26 @@ public class FavouriteController
deletedCallbacks.add(callback);
}
/**
* @return AD_Tree_Favorite_ID
*/
public int getAD_Tree_Favorite_ID()
{
return m_AD_Tree_Favorite_ID;
}
/**
* @return root MTreeNode
*/
public MTreeNode getRootNode()
{
return rootNode;
}
/**
* @param treeModel FavoriteSimpleTreeModel
* @param tree Tree
*/
public void setTreeAndModel(FavoriteSimpleTreeModel treeModel, Tree tree)
{
this.tree = tree;

View File

@ -25,6 +25,7 @@ import org.compiere.model.GridTab;
import org.compiere.model.MQuery;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.EventQueue;
/**
* Desktop interface
@ -34,6 +35,7 @@ import org.zkoss.zk.ui.Page;
public interface IDesktop extends UIPart {
public static final String WINDOWNO_ATTRIBUTE = "desktop.windowno";
/** {@link EventQueue} name for activities (workflow activities, request, notice and unprocessed documents) */
public static final String ACTIVITIES_EVENT_QUEUE = "ActivitiesEventQueue";
public static final String ON_ACTIVITIES_CHANGED_EVENT = "onActivitiesChanged";

View File

@ -48,21 +48,22 @@ import org.zkoss.zul.Tab;
import org.zkoss.zul.Tabpanels;
/**
* A Tabbed MDI implementation
* Abstract base class for Tabbed MDI implementation
* @author hengsin
*
*/
public abstract class TabbedDesktop extends AbstractDesktop {
/** Controller for open desktop windows. */
protected WindowContainer windowContainer;
/**
* Default constructor
*/
public TabbedDesktop() {
super();
windowContainer = new WindowContainer();
}
/**
*
* @param processId
* @param soTrx
* @return ProcessDialog
@ -83,9 +84,8 @@ public abstract class TabbedDesktop extends AbstractDesktop {
}
/**
*
* @param formId
* @return ADWindow
* @return ADForm
*/
public ADForm openForm(int formId) {
ADForm form = ADForm.openForm(formId, null, null, getPredefinedContextVariables(), isMenuSOTrx());
@ -107,7 +107,6 @@ public abstract class TabbedDesktop extends AbstractDesktop {
}
/**
*
* @param infoId
*/
@Override
@ -128,7 +127,6 @@ public abstract class TabbedDesktop extends AbstractDesktop {
}
/**
*
* @param workflow_ID
*/
public void openWorkflow(int workflow_ID) {
@ -142,7 +140,6 @@ public abstract class TabbedDesktop extends AbstractDesktop {
}
/**
*
* @param windowId
* @param callback
*/
@ -151,7 +148,6 @@ public abstract class TabbedDesktop extends AbstractDesktop {
}
/**
*
* @param windowId
* @param query
* @param callback
@ -173,7 +169,6 @@ public abstract class TabbedDesktop extends AbstractDesktop {
}
/**
*
* @param taskId
*/
public void openTask(int taskId) {
@ -190,7 +185,6 @@ public abstract class TabbedDesktop extends AbstractDesktop {
}
/**
*
* @param url
* @param title
* @param closeable
@ -202,7 +196,7 @@ public abstract class TabbedDesktop extends AbstractDesktop {
}
/**
* @param content
* @param content HTML content
* @param title
* @param closeable
*/
@ -218,8 +212,7 @@ public abstract class TabbedDesktop extends AbstractDesktop {
}
/**
*
* @param fr
* @param fr Iframe
* @param title
* @param closeable
*/
@ -268,7 +261,7 @@ public abstract class TabbedDesktop extends AbstractDesktop {
}
/**
*
* Show window in new tab
* @param window
*/
protected void showEmbedded(Window window)
@ -328,9 +321,8 @@ public abstract class TabbedDesktop extends AbstractDesktop {
}
/**
*
* @param windowNo
* @return boolean
* @return true if found and close
*/
public boolean closeWindow(int windowNo)
{
@ -374,6 +366,9 @@ public abstract class TabbedDesktop extends AbstractDesktop {
{
}
/**
* Runnable to create window content ({@link ADWindow#createPart(Object)})
*/
class OpenWindowRunnable implements Runnable {
private final ADWindow adWindow;
@ -381,6 +376,12 @@ public abstract class TabbedDesktop extends AbstractDesktop {
private final DesktopTabpanel tabPanel;
private Callback<ADWindow> callback;
/**
* @param adWindow
* @param tab
* @param tabPanel
* @param callback
*/
protected OpenWindowRunnable(ADWindow adWindow, Tab tab, DesktopTabpanel tabPanel, Callback<ADWindow> callback) {
this.adWindow = adWindow;
this.tab = tab;
@ -401,6 +402,10 @@ public abstract class TabbedDesktop extends AbstractDesktop {
}
}
/**
* @param title
* @param windowNo
*/
public void setTabTitle(String title, int windowNo) {
windowContainer.setTabTitle(title, windowNo);
}

View File

@ -51,9 +51,9 @@ import org.zkoss.zul.Menuitem;
import org.zkoss.zul.Style;
/**
*
* Controller for open desktop windows. <br/>
* Implemented using {@link Tabbox}.
* @author Low Heng Sin
*
*/
public class WindowContainer extends AbstractUIPart implements EventListener<Event>
{

View File

@ -21,8 +21,8 @@ package org.adempiere.webui.util;
public interface IServerPushCallback {
/**
* Callback method to perform UI related update. For performance reason, implementation of this method
* must not perform potentially slow operation.
* Callback method to perform UI related update. To keep UI responsive, implementation of this method
* must not perform potentially slow operation (to avoid holding on to the single Event Listener Thread for too long).
*/
public void updateUI();