IDEMPIERE-369 Master Detail layout improvements. 1) Fixed dataIgnore bugs with new record. 2) Fixed wrong icon for customized grid view dialog. 3) Fixed layout issue with document action dialog. 3) Added highlight for active tab. 4) Click on row indicator will now toggle form view. 5) Added indicator for 2nd or 3rd level tab. 5) Drop desktop implementation that's not maintained anymore.

This commit is contained in:
Heng Sin Low 2012-10-19 10:28:08 +08:00
parent b6272115b9
commit 2b8ecf09be
14 changed files with 200 additions and 779 deletions

View File

@ -2657,7 +2657,9 @@ public class GridTable extends AbstractTableModel
{
if (!m_inserting && !m_changed && m_rowChanged < 0)
{
log.fine("Nothing to ignore");
if (log.isLoggable(Level.FINE))
log.fine("Nothing to ignore");
m_newRow = -1;
return;
}
log.info("Inserting=" + m_inserting);

View File

@ -931,5 +931,10 @@ public class ADSortTab extends Panel implements IADTabpanel
public void setDetailPaneMode(boolean detailMode, boolean vflex) {
this.setVflex(Boolean.toString(vflex));
}
@Override
public GridView getGridView() {
return null;
}
} //ADSortTab

View File

@ -98,6 +98,12 @@ import org.zkoss.zul.impl.XulElement;
public class ADTabpanel extends Div implements Evaluatee, EventListener<Event>,
DataStatusListener, IADTabpanel
{
public static final String ON_SWITCH_VIEW_EVENT = "onSwitchView";
public static final String ON_ACTIVATE_EVENT = "onActivate";
private static final String ATTR_ON_ACTIVATE_POSTED = "org.adempiere.webui.adwindow.ADTabpanel.onActivatePosted";
/**
*
*/
@ -163,6 +169,13 @@ DataStatusListener, IADTabpanel
initComponents();
addEventListener(ON_DEFER_SET_SELECTED_NODE, this);
addEventListener(WPaymentEditor.ON_SAVE_PAYMENT, this);
addEventListener(ON_ACTIVATE_EVENT, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
removeAttribute(ATTR_ON_ACTIVATE_POSTED);
}
});
}
private void initComponents()
@ -586,7 +599,7 @@ DataStatusListener, IADTabpanel
for (WEditor comp : editors)
{
GridField mField = comp.getGridField();
if (mField != null && mField.getIncluded_Tab_ID() <= 0)
if (mField != null)
{
if (mField.isDisplayed(true)) // check context
{
@ -796,6 +809,14 @@ DataStatusListener, IADTabpanel
*/
public void activate(boolean activate)
{
if (activate) {
if (getAttribute(ATTR_ON_ACTIVATE_POSTED) != null) {
return;
}
setAttribute(ATTR_ON_ACTIVATE_POSTED, Boolean.TRUE);
}
active = activate;
if (listPanel.isVisible()) {
if (activate)
@ -813,8 +834,8 @@ DataStatusListener, IADTabpanel
setSelectedNode(gridTab.getRecord_ID());
}
Event event = new Event("onActivate", this, activate);
Events.sendEvent(event);
Event event = new Event(ON_ACTIVATE_EVENT, this, activate);
Events.postEvent(event);
}
/**
@ -1060,7 +1081,7 @@ DataStatusListener, IADTabpanel
if (details != null)
addDetails(details);
Events.sendEvent(this, new Event("onSwitchView", this));
Events.sendEvent(this, new Event(ON_SWITCH_VIEW_EVENT, this));
}
class ZoomListener implements EventListener {
@ -1132,6 +1153,7 @@ DataStatusListener, IADTabpanel
*
* @return GridPanel
*/
@Override
public GridView getGridView() {
return listPanel;
}

View File

@ -1126,6 +1126,9 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
if (adTabbox.getSelectedGridTab() != null && adTabbox.getSelectedGridTab().isQueryActive())
dbInfo = "[ " + dbInfo + " ]";
breadCrumb.setStatusDB(dbInfo, e);
} else if (adTabbox.getSelectedDetailADTabpanel() == null)
{
return;
}
// Set Message / Info
@ -1485,6 +1488,8 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
}
private void doOnFind() {
adTabbox.dataIgnore();
// Gets Fields from AD_Field_v
GridField[] findFields = adTabbox.getSelectedGridTab().getFields();
if (findWindow == null || !findWindow.validate(adTabbox.getSelectedGridTab().getWindowNo(), adTabbox.getSelectedGridTab().getName(),

View File

@ -41,6 +41,7 @@ import org.zkoss.zk.ui.HtmlBasedComponent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Menuitem;
import org.zkoss.zul.Vlayout;
@ -53,10 +54,6 @@ import org.zkoss.zul.Vlayout;
*/
public class CompositeADTabbox extends AbstractADTabbox
{
private static final String ON_SWITCH_VIEW_EVENT = "onSwitchView";
private static final String ON_ACTIVATE_EVENT = "onActivate";
public static final String ON_SELECTION_CHANGED_EVENT = "onSelectionChanged";
public static final String ADTAB_INDEX_ATTRIBUTE = "adtab.index";
@ -87,6 +84,8 @@ public class CompositeADTabbox extends AbstractADTabbox
@Override
public void onEvent(Event event) throws Exception {
if (DetailPane.ON_EDIT_EVENT.equals(event.getName())) {
if (headerTab.getGridTab().isNew()) return;
final int row = detailPane.getSelectedADTabpanel() != null
? detailPane.getSelectedADTabpanel().getGridTab().getCurrentRow()
: 0;
@ -99,6 +98,8 @@ public class CompositeADTabbox extends AbstractADTabbox
});
}
else if (DetailPane.ON_NEW_EVENT.equals(event.getName())) {
if (headerTab.getGridTab().isNew()) return;
final int row = detailPane.getSelectedADTabpanel() != null
? detailPane.getSelectedADTabpanel().getGridTab().getCurrentRow()
: 0;
@ -113,6 +114,8 @@ public class CompositeADTabbox extends AbstractADTabbox
});
}
else if (DetailPane.ON_DELETE_EVENT.equals(event.getName())) {
if (headerTab.getGridTab().isNew()) return;
final IADTabpanel tabPanel = detailPane.getSelectedADTabpanel();
if (tabPanel != null && tabPanel.getGridTab().getRowCount() > 0
&& tabPanel.getGridTab().getCurrentRow() >= 0) {
@ -137,6 +140,7 @@ public class CompositeADTabbox extends AbstractADTabbox
protected void onEditDetail(int row) {
int oldIndex = selectedIndex;
IADTabpanel selectedPanel = detailPane.getSelectedADTabpanel();
if (selectedPanel == null) return;
int newIndex = (Integer)selectedPanel.getAttribute(ADTAB_INDEX_ATTRIBUTE);
Event selectionChanged = new Event(ON_SELECTION_CHANGED_EVENT, layout, new Object[]{oldIndex, newIndex});
@ -198,7 +202,7 @@ public class CompositeADTabbox extends AbstractADTabbox
tabPanel.setAttribute(ADTAB_INDEX_ATTRIBUTE, tabPanelList.size()-1);
tabPanel.addEventListener(ON_ACTIVATE_EVENT, new EventListener<Event>() {
tabPanel.addEventListener(ADTabpanel.ON_ACTIVATE_EVENT, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
Boolean b = (Boolean) event.getData();
@ -247,7 +251,7 @@ public class CompositeADTabbox extends AbstractADTabbox
}
});
tabPanel.addEventListener(ON_SWITCH_VIEW_EVENT, new EventListener<Event>() {
tabPanel.addEventListener(ADTabpanel.ON_SWITCH_VIEW_EVENT, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
@ -277,16 +281,26 @@ public class CompositeADTabbox extends AbstractADTabbox
}
});
if (tabPanel.getGridView() != null) {
tabPanel.getGridView().addEventListener(DetailPane.ON_EDIT_EVENT, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
GridView gridView = (GridView) event.getTarget();
if (gridView.getParent() == headerTab) {
adWindowPanel.onToggle();
}
}
});
}
if (layout.getChildren().isEmpty()) {
layout.appendChild(tabPanel);
headerTab = tabPanel;
updateBreadCrumb();
} else if (tabLabel.tabLevel <= 1) {
boolean activate = false;
if (detailPane.getParent() == null) {
ADTabpanel adtabpanel = (ADTabpanel) headerTab;
adtabpanel.addDetails(detailPane);
activate = true;
} else
tabPanel.setVisible(false);
detailPane.setHflex("1");
@ -294,8 +308,6 @@ public class CompositeADTabbox extends AbstractADTabbox
detailPane.addADTabpanel(tabPanel, tabLabel);
tabPanel.setDetailPaneMode(true, isUseVflexForDetailPane());
detailPane.setVflex(Boolean.toString(isUseVflexForDetailPane()));
if (activate)
activateDetailADTabpanel();
} else {
detailPane.addADTabpanel(tabPanel, tabLabel, false);
tabPanel.setDetailPaneMode(true, isUseVflexForDetailPane());
@ -305,15 +317,7 @@ public class CompositeADTabbox extends AbstractADTabbox
htmlComponent.setVflex("1");
htmlComponent.setWidth("100%");
tabPanel.getGridTab().addDataStatusListener(new SyncDataStatusListener(tabPanel));
if (detailPane.getTabcount() > 1) {
int selectedIndex = detailPane.getSelectedIndex();
updateTabState();
if (detailPane.getSelectedIndex() != selectedIndex) {
activateDetailADTabpanel();
}
}
tabPanel.getGridTab().addDataStatusListener(new SyncDataStatusListener(tabPanel));
}
private void activateDetailADTabpanel() {
@ -403,6 +407,8 @@ public class CompositeADTabbox extends AbstractADTabbox
} else if (tabLevel > currentLevel ){
detailPane.addADTabpanel(tabPanel, tabLabel, false);
tabPanel.setDetailPaneMode(true, isUseVflexForDetailPane());
} else {
break;
}
}
@ -413,6 +419,8 @@ public class CompositeADTabbox extends AbstractADTabbox
detailPane.setSelectedIndex(0);
}
headerTab.setDetailPaneMode(false, isUseVflexForDetailPane());
updateBreadCrumb();
}
@ -518,7 +526,7 @@ public class CompositeADTabbox extends AbstractADTabbox
//refresh current row
detailTab.getGridTab().dataRefresh(false);
//keep focus
onDetailRecord();
Clients.scrollIntoView(detailTab);
return;
}
@ -530,7 +538,6 @@ public class CompositeADTabbox extends AbstractADTabbox
if (!parentColumnNames.contains(field.getColumnName()))
Env.setContext(Env.getCtx(), field.getWindowNo(), field.getColumnName(), "");
}
detailTab.query(false, 0, 0);
detailTab.activate(true);
detailTab.setDetailPaneMode(true, isUseVflexForDetailPane());
detailPane.setVflex(Boolean.toString(isUseVflexForDetailPane()));
@ -655,7 +662,10 @@ public class CompositeADTabbox extends AbstractADTabbox
@Override
public void updateDetailPaneToolbar(boolean changed, boolean readOnly) {
detailPane.updateToolbar(changed, readOnly);
if (headerTab.getGridTab().isNew() || headerTab.getGridTab().getRowCount() == 0)
detailPane.disableToolbar();
else
detailPane.updateToolbar(changed, readOnly);
}
@Override

View File

@ -140,19 +140,16 @@ public class DetailPane extends Panel implements EventListener<Event> {
tab.setLabel(tabLabel.label);
if (!enabled) {
tab.setDisabled(true);
tab.setSclass("adwindow-detailpane-sub-tab");
}
Tabpanels tabpanels = tabbox.getTabpanels();
if (tabpanels == null) {
tabpanels = new Tabpanels();
//TODO: is this style needed ?
tabpanels.setStyle("min-height: 200px; overflow-y: visible;");
tabpanels.setWidth("100%");
tabbox.appendChild(tabpanels);
}
Tabpanel tp = new Tabpanel();
//TODO: is this style needed
tp.setStyle("min-height: 180px; overflow-y: visible; width: 99%; margin: auto;");
tabpanels.appendChild(tp);
tp.setStyle("background-color: #fff");
ToolBar toolbar = new ToolBar();
@ -206,6 +203,17 @@ public class DetailPane extends Panel implements EventListener<Event> {
tabPanel.setAttribute("AD_Tab_ID", tabLabel.AD_Tab_ID);
tp.appendChild(tabPanel);
if (tabPanel instanceof ADTabpanel) {
ADTabpanel adtab = (ADTabpanel) tabPanel;
adtab.getGridView().addEventListener(ON_EDIT_EVENT, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
GridView gridView = (GridView) event.getTarget();
if (gridView.isDetailPaneMode())
onEdit();
}
});
}
}
public void setEventListener(EventListener<Event> listener) {
@ -247,6 +255,7 @@ public class DetailPane extends Panel implements EventListener<Event> {
public void setStatusMessage(String status, boolean error) {
IADTabpanel tabPanel = getSelectedADTabpanel();
if (tabPanel == null) return;
Hbox messageContainer = messageContainers.get(tabPanel.getAttribute("AD_Tab_ID"));
Execution execution = Executions.getCurrent();
@ -323,12 +332,14 @@ public class DetailPane extends Panel implements EventListener<Event> {
@Override
public void onEvent(Event event) throws Exception {
Component messageContainer = event.getTarget().getParent();
Boolean error = (Boolean) messageContainer.getAttribute(STATUS_ERROR_ATTRIBUTE);
String status = (String) messageContainer.getAttribute(STATUS_TEXT_ATTRIBUTE);
createPopupContent(status);
showPopup(error, messageContainer);
if (event.getName().equals(Events.ON_CLICK)) {
Component messageContainer = event.getTarget().getParent();
Boolean error = (Boolean) messageContainer.getAttribute(STATUS_ERROR_ATTRIBUTE);
String status = (String) messageContainer.getAttribute(STATUS_TEXT_ATTRIBUTE);
createPopupContent(status);
showPopup(error, messageContainer);
}
}
protected void createPopupContent(String status) {
@ -394,20 +405,14 @@ public class DetailPane extends Panel implements EventListener<Event> {
}
boolean enableNew = !changed && insertRecord && !adtab.getGridTab().isSortTab();
boolean enableDelete = !changed && !readOnly && !adtab.getGridTab().isSortTab();
int newBtn = 0;
int deleteBtn = 0;
for(Component c : toolbar.getChildren()) {
if (c instanceof ToolBarButton) {
ToolBarButton btn = (ToolBarButton) c;
if (NEW_IMAGE.equals(btn.getImage())) {
btn.setDisabled(!enableNew);
newBtn++;
} else if (DELETE_IMAGE.equals(btn.getImage())) {
btn.setDisabled(!enableDelete);
deleteBtn++;
}
if (newBtn > 0 && deleteBtn > 0)
break;
}
}
}
@ -453,4 +458,18 @@ public class DetailPane extends Panel implements EventListener<Event> {
Tab tab = (Tab) tabbox.getTabs().getChildren().get(i);
tab.setDisabled(!enabled);
}
public void disableToolbar() {
int index = getSelectedIndex();
if (index < 0 || index >= getTabcount()) return;
Tabpanel tabpanel = tabbox.getTabpanel(index);
Toolbar toolbar = (Toolbar) tabpanel.getFirstChild();
for(Component c : toolbar.getChildren()) {
if (c instanceof ToolBarButton) {
ToolBarButton btn = (ToolBarButton) c;
btn.setDisabled(true);
}
}
}
}

View File

@ -39,7 +39,9 @@ import org.compiere.model.GridField;
import org.compiere.model.GridTab;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.NamePair;
import org.compiere.util.Util;
import org.zkoss.zk.au.out.AuFocus;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.HtmlBasedComponent;
@ -86,6 +88,7 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
private boolean editing = false;
private int currentRowIndex = -1;
private AbstractADWindowContent m_windowPanel;
private ActionListener buttonListener;
/**
*
@ -113,9 +116,10 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
private void prepareFieldEditor(GridField gridField, WEditor editor) {
if (editor instanceof WButtonEditor)
{
if (m_windowPanel != null)
if (buttonListener != null)
{
((WButtonEditor)editor).addActionListener(m_windowPanel);
((WButtonEditor)editor).removeActionListener(buttonListener);
((WButtonEditor)editor).addActionListener(buttonListener);
}
else
{
@ -229,16 +233,7 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
editor.setValue(gridTab.getValue(rowIndex, gridField.getColumnName()));
editor.setReadWrite(gridField.isEditable(gridRowCtx, true,true));
editor.getComponent().setAttribute("grid.row.index", rowIndex);
editor.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
WButtonEditor editor = (WButtonEditor) event.getSource();
int rowIndex = (Integer) editor.getComponent().getAttribute("grid.row.index");
int newRowIndex = gridTab.navigate(rowIndex);
if (newRowIndex == rowIndex) {
m_windowPanel.actionPerformed(event);
}
}
});
editor.addActionListener(buttonListener);
component = editor.getComponent();
} else {
String text = getDisplayText(value, gridField);
@ -398,6 +393,18 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
Cell cell = new Cell();
cell.setWidth("10px");
cell.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
Cell cell = (Cell) event.getTarget();
if (cell.getSclass() != null && cell.getSclass().indexOf("row-indicator-seld") >= 0)
Events.sendEvent(gridPanel, new Event(DetailPane.ON_EDIT_EVENT, gridPanel));
else
Events.sendEvent(event.getTarget().getParent(), event);
}
});
cell.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "EditRecord")));
//TODO: checkbox for selection and batch action ( delete, export, complete, etc )
// cell.appendChild(new Checkbox());
row.appendChild(cell);
@ -450,13 +457,13 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
Cell cell = (Cell) currentRow.getFirstChild();
if (cell != null) {
cell.setStyle("background-color: transparent");
cell.setSclass(null);
cell.setSclass("row-indicator");
}
}
currentRow = row;
Cell cell = (Cell) currentRow.getFirstChild();
if (cell != null) {
cell.setSclass("current-row-indicator");
cell.setSclass("row-indicator-seld");
}
currentRowIndex = gridTab.getCurrentRow();
@ -665,6 +672,24 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
* @param windowPanel
*/
public void setADWindowPanel(AbstractADWindowContent windowPanel) {
if (this.m_windowPanel == windowPanel)
return;
this.m_windowPanel = windowPanel;
buttonListener = new ActionListener() {
public void actionPerformed(ActionEvent event) {
WButtonEditor editor = (WButtonEditor) event.getSource();
Integer rowIndex = (Integer) editor.getComponent().getAttribute("grid.row.index");
if (rowIndex != null) {
int newRowIndex = gridTab.navigate(rowIndex);
if (newRowIndex == rowIndex) {
m_windowPanel.actionPerformed(event);
}
} else {
m_windowPanel.actionPerformed(event);
}
}
};
}
}

View File

@ -119,6 +119,8 @@ public class GridView extends Vbox implements EventListener<Event>
private Borderlayout borderLayout;
private boolean detailPaneMode;
public GridView()
{
this(0);
@ -191,7 +193,8 @@ public class GridView extends Vbox implements EventListener<Event>
}
public void setDetailPaneMode(boolean detailPaneMode, boolean vflex) {
if (detailPaneMode) {
this.detailPaneMode = detailPaneMode;
if (detailPaneMode) {
pageSize = DEFAULT_DETAIL_PAGE_SIZE;
updatePaging();
if (borderLayout.getParent() != null) {
@ -221,6 +224,10 @@ public class GridView extends Vbox implements EventListener<Event>
}
}
public boolean isDetailPaneMode() {
return this.detailPaneMode;
}
private void updatePaging() {
if (paging != null && paging.getPageSize() != pageSize) {
paging.setPageSize(pageSize);
@ -435,7 +442,7 @@ public class GridView extends Vbox implements EventListener<Event>
columns.appendChild(indicator);
listbox.appendChild(columns);
columns.setSizable(true);
columns.setMenupopup("auto");
columns.setMenupopup("none");
columns.setColumnsgroup(false);
Map<Integer, String> colnames = new HashMap<Integer, String>();
@ -777,7 +784,7 @@ public class GridView extends Vbox implements EventListener<Event>
for (WEditor comp : list)
{
GridField mField = comp.getGridField();
if (mField != null && mField.getIncluded_Tab_ID() <= 0)
if (mField != null)
{
if (noData)
{

View File

@ -119,5 +119,7 @@ public interface IADTabpanel extends Component, Evaluatee {
public boolean isActive();
public void setDetailPaneMode(boolean detailMode, boolean vflex);
public void setDetailPaneMode(boolean detailMode, boolean vflex);
public abstract GridView getGridView();
}

View File

@ -1,351 +0,0 @@
/******************************************************************************
* Copyright (C) 2008 Low Heng Sin *
* Copyright (C) 2008 Idalica Corporation *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.webui.desktop;
import java.io.Serializable;
import java.util.Properties;
import org.adempiere.util.ServerContext;
import org.adempiere.webui.adwindow.ADWindow;
import org.adempiere.webui.apps.BusyDialog;
import org.adempiere.webui.apps.ProcessDialog;
import org.adempiere.webui.component.Accordion;
import org.adempiere.webui.component.Tabpanel;
import org.adempiere.webui.component.ToolBarButton;
import org.adempiere.webui.dashboard.DPActivities;
import org.adempiere.webui.dashboard.DashboardPanel;
import org.adempiere.webui.event.MenuListener;
import org.adempiere.webui.panel.ADForm;
import org.adempiere.webui.panel.HeaderPanel;
import org.adempiere.webui.session.SessionContextListener;
import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.util.IServerPushCallback;
import org.adempiere.webui.util.ServerPushTemplate;
import org.adempiere.webui.util.UserPreference;
import org.compiere.util.CLogger;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Util;
import org.zkoss.zk.au.out.AuScript;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Center;
import org.zkoss.zul.Div;
import org.zkoss.zul.North;
import org.zkoss.zul.West;
/**
* @author hengsin
*/
public class NavBar2Desktop extends TabbedDesktop implements MenuListener, Serializable, EventListener<Event>, IServerPushCallback
{
private static final long serialVersionUID = -7483133591812825441L;
private static final String FAVOURITES_PATH = "/zul/favourites.zul";
private static final String ACTIVITIES_PATH = "/zul/activities.zul";
@SuppressWarnings("unused")
private static final CLogger logger = CLogger.getCLogger(DefaultDesktop.class);
private Center windowArea;
private Borderlayout layout;
private Accordion shortcutPanel;
private int noOfNotice;
private int noOfRequest;
private int noOfWorkflow;
private int noOfUnprocessed;
private Tabpanel homeTab;
private DashboardController dashboardController, sideController;
public NavBar2Desktop()
{
super();
dashboardController = new DashboardController();
sideController = new DashboardController();
}
protected Component doCreatePart(Component parent)
{
HeaderPanel pnlHead = new HeaderPanel();
layout = new Borderlayout();
if (parent != null)
{
layout.setParent(parent);
layout.setWidth("100%");
layout.setHeight("100%");
layout.setStyle("position: absolute");
}
else
layout.setPage(page);
North n = new North();
layout.appendChild(n);
n.setCollapsible(false);
pnlHead.setParent(n);
West w = new West();
w.setTitle(" ");
layout.appendChild(w);
w.setWidth("300px");
w.setCollapsible(true);
w.setSplittable(true);
w.addEventListener(Events.ON_OPEN, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
OpenEvent oe = (OpenEvent) event;
UserPreference pref = SessionManager.getSessionApplication().getUserPreference();
pref.setProperty(UserPreference.P_MENU_COLLAPSED, !oe.isOpen());
pref.savePreference();
}
});
UserPreference pref = SessionManager.getSessionApplication().getUserPreference();
boolean menuCollapsed= pref.isPropertyBool(UserPreference.P_MENU_COLLAPSED);
w.setOpen(!menuCollapsed);
sideController.render(w, this, false);
Center center = new Center();
center.setParent(layout);
Borderlayout innerLayout = new Borderlayout();
innerLayout.setHeight("100%");
innerLayout.setWidth("100%");
innerLayout.setParent(center);
innerLayout.setVflex("1");
innerLayout.setHflex("1");
West innerW = new West();
innerW.setWidth("200px");
innerW.setCollapsible(true);
innerW.setTitle("Navigation");
innerW.setSplittable(true);
innerW.setCollapsible(true);
innerW.setParent(innerLayout);
shortcutPanel = new Accordion();
shortcutPanel.setWidth("100%");
shortcutPanel.setHeight("100%");
innerW.appendChild(shortcutPanel);
Div div = new Div();
Executions.createComponents(FAVOURITES_PATH, div, null);
shortcutPanel.add(div, "Favourites");
div = new Div();
Component component = Executions.createComponents(ACTIVITIES_PATH, div, null);
if (component instanceof DashboardPanel)
{
DashboardPanel dashboardPanel = (DashboardPanel) component;
dashboardController.addDashboardPanel(dashboardPanel);
}
shortcutPanel.add(div, "Activities");
shortcutPanel.setSelectedIndex(0);
windowArea = new Center();
windowArea.setParent(innerLayout);
windowContainer.createPart(windowArea);
homeTab = new Tabpanel();
windowContainer.addWindow(homeTab, Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Home")), false);
BusyDialog busyDialog = new BusyDialog();
busyDialog.setShadow(false);
homeTab.appendChild(busyDialog);
if (!layout.getDesktop().isServerPushEnabled())
{
layout.getDesktop().enableServerPush(true);
}
Runnable runnable = new Runnable() {
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
IServerPushCallback callback = new IServerPushCallback() {
public void updateUI() {
Properties ctx = (Properties)layout.getDesktop().getSession().getAttribute(SessionContextListener.SESSION_CTX);
try {
ServerContext.setCurrentInstance(ctx);
renderHomeTab();
} finally {
ServerContext.dispose();
}
}
};
ServerPushTemplate template = new ServerPushTemplate(layout.getDesktop());
template.executeAsync(callback);
}
};
Thread thread = new Thread(runnable);
thread.start();
return layout;
}
private void renderHomeTab()
{
homeTab.getChildren().clear();
//register as 0
registerWindow(homeTab);
dashboardController.render(homeTab, this, true);
}
public void onEvent(Event event)
{
Component comp = event.getTarget();
String eventName = event.getName();
if(eventName.equals(Events.ON_CLICK))
{
if(comp instanceof ToolBarButton)
{
ToolBarButton btn = (ToolBarButton) comp;
int menuId = 0;
try
{
menuId = Integer.valueOf(btn.getName());
}
catch (Exception e) {
}
if(menuId > 0) onMenuSelected(menuId);
}
}
}
public void onServerPush(ServerPushTemplate template)
{
noOfNotice = DPActivities.getNoticeCount();
noOfRequest = DPActivities.getRequestCount();
noOfWorkflow = DPActivities.getWorkflowCount();
noOfUnprocessed = DPActivities.getUnprocessedCount();
template.executeAsync(this);
}
/**
*
* @param page
*/
public void setPage(Page page) {
if (this.page != page) {
layout.setPage(page);
this.page = page;
}
if (dashboardController != null) {
dashboardController.onSetPage(page, layout.getDesktop(), this);
}
if (sideController != null) {
sideController.onSetPage(page, layout.getDesktop(), this);
}
}
/**
* Get the root component
* @return Component
*/
public Component getComponent() {
return layout;
}
public void logout() {
if (dashboardController != null) {
dashboardController.onLogOut();
}
if (sideController != null) {
sideController.onLogOut();
}
}
public void updateUI() {
int total = noOfNotice + noOfRequest + noOfWorkflow + noOfUnprocessed;
shortcutPanel.setLabel(1, "Activities (" + total + ")");
shortcutPanel.setTooltiptext(1, Msg.translate(Env.getCtx(), "AD_Note_ID") + " : " + noOfNotice
+ ", " + Msg.translate(Env.getCtx(), "R_Request_ID") + " : " + noOfRequest
+ ", " + Msg.getMsg (Env.getCtx(), "WorkflowActivities") + " : " + noOfWorkflow
+ (noOfUnprocessed>0 ? ", " + Msg.getMsg (Env.getCtx(), "UnprocessedDocs") + " : " + noOfUnprocessed : "")
);
}
private void autoHideMenu() {
if (layout.getWest().isCollapsible() && !layout.getWest().isOpen())
{
//using undocumented js api, need to be retested after every version upgrade
String id = layout.getWest().getUuid() + "!real";
String btn = layout.getWest().getUuid() + "!btn";
String script = "zk.show('" + id + "', false);";
script += "$e('"+id+"')._isSlide = false;";
script += "$e('"+id+"')._lastSize = null;";
script += "$e('"+btn+"').style.display = '';";
AuScript aus = new AuScript(layout.getWest(), script);
Clients.response("autoHideWest", aus);
}
}
@Override
public ADWindow openWindow(int windowId) {
autoHideMenu();
return super.openWindow(windowId);
}
@Override
public ADForm openForm(int formId) {
autoHideMenu();
return super.openForm(formId);
}
@Override
public ProcessDialog openProcessDialog(int processId, boolean soTrx) {
autoHideMenu();
return super.openProcessDialog(processId, soTrx);
}
@Override
public void openTask(int taskId) {
autoHideMenu();
super.openTask(taskId);
}
@Override
public void openWorkflow(int workflowID) {
autoHideMenu();
super.openWorkflow(workflowID);
}
}

View File

@ -1,359 +0,0 @@
/******************************************************************************
* Copyright (C) 2008 Low Heng Sin *
* Copyright (C) 2008 Idalica Corporation *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.webui.desktop;
import java.io.Serializable;
import java.util.Properties;
import org.adempiere.util.ServerContext;
import org.adempiere.webui.adwindow.ADWindow;
import org.adempiere.webui.apps.BusyDialog;
import org.adempiere.webui.apps.ProcessDialog;
import org.adempiere.webui.component.Accordion;
import org.adempiere.webui.component.Tabpanel;
import org.adempiere.webui.component.ToolBarButton;
import org.adempiere.webui.dashboard.DPActivities;
import org.adempiere.webui.dashboard.DPFavourites;
import org.adempiere.webui.dashboard.DashboardPanel;
import org.adempiere.webui.event.MenuListener;
import org.adempiere.webui.panel.ADForm;
import org.adempiere.webui.panel.HeaderPanel;
import org.adempiere.webui.panel.MenuTreePanel;
import org.adempiere.webui.session.SessionContextListener;
import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.util.IServerPushCallback;
import org.adempiere.webui.util.ServerPushTemplate;
import org.adempiere.webui.util.UserPreference;
import org.compiere.util.CLogger;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.zkoss.zk.au.out.AuScript;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.DropEvent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Center;
import org.zkoss.zul.Div;
import org.zkoss.zul.North;
import org.zkoss.zul.Treeitem;
import org.zkoss.zul.Treerow;
import org.zkoss.zul.West;
/**
* @author hengsin
*/
public class NavBarDesktop extends TabbedDesktop implements MenuListener, Serializable, EventListener<Event>, IServerPushCallback
{
private static final long serialVersionUID = 4721048271543882164L;
private static final String FAVOURITES_PATH = "/zul/favourites.zul";
private static final String ACTIVITIES_PATH = "/zul/activities.zul";
private static final String VIEWS_PATH = "/zul/views.zul";
@SuppressWarnings("unused")
private static final CLogger logger = CLogger.getCLogger(DefaultDesktop.class);
private Center windowArea;
private Borderlayout layout;
private Accordion navigationPanel;
private West leftRegion;
private DPFavourites favPanel;
private int noOfNotice;
private int noOfRequest;
private int noOfWorkflow;
private int noOfUnprocessed;
private Tabpanel homeTab;
private DashboardController dashboardController;
public NavBarDesktop()
{
super();
dashboardController = new DashboardController();
}
protected Component doCreatePart(Component parent)
{
HeaderPanel pnlHead = new HeaderPanel();
layout = new Borderlayout();
if (parent != null)
{
layout.setParent(parent);
layout.setWidth("100%");
layout.setHeight("100%");
layout.setStyle("position: absolute");
}
else
layout.setPage(page);
North n = new North();
layout.appendChild(n);
n.setCollapsible(false);
pnlHead.setParent(n);
leftRegion = new West();
layout.appendChild(leftRegion);
leftRegion.setWidth("300px");
leftRegion.setCollapsible(true);
leftRegion.setSplittable(true);
leftRegion.setTitle("Navigation");
leftRegion.addEventListener(Events.ON_OPEN, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
OpenEvent oe = (OpenEvent) event;
UserPreference pref = SessionManager.getSessionApplication().getUserPreference();
pref.setProperty(UserPreference.P_MENU_COLLAPSED, !oe.isOpen());
pref.savePreference();
}
});
UserPreference pref = SessionManager.getSessionApplication().getUserPreference();
boolean menuCollapsed= pref.isPropertyBool(UserPreference.P_MENU_COLLAPSED);
leftRegion.setOpen(!menuCollapsed);
navigationPanel = new Accordion();
navigationPanel.setParent(leftRegion);
navigationPanel.setWidth("100%");
navigationPanel.setHeight("100%");
navigationPanel.add(new MenuTreePanel(null), "Application Menu");
Div div = new Div();
favPanel = (DPFavourites) Executions.createComponents(FAVOURITES_PATH, div, null);
navigationPanel.add(div, "Favourites");
//setup drag and drop for favourites
div = navigationPanel.getHeader(1);
div.setDroppable(DPFavourites.FAVOURITE_DROPPABLE);
div.addEventListener(Events.ON_DROP, this);
div = new Div();
Component component = Executions.createComponents(ACTIVITIES_PATH, div, null);
if (component instanceof DashboardPanel)
{
DashboardPanel dashboardPanel = (DashboardPanel) component;
dashboardController.addDashboardPanel(dashboardPanel);
}
navigationPanel.add(div, "Activities");
div = new Div();
Executions.createComponents(VIEWS_PATH, div, null);
navigationPanel.add(div, Msg.getMsg(Env.getCtx(), "View").replaceAll("&", ""));
navigationPanel.setSelectedIndex(0);
windowArea = new Center();
windowArea.setParent(layout);
windowContainer.createPart(windowArea);
homeTab = new Tabpanel();
windowContainer.addWindow(homeTab, Msg.getMsg(Env.getCtx(), "Home").replaceAll("&", ""), false);
BusyDialog busyDialog = new BusyDialog();
busyDialog.setShadow(false);
homeTab.appendChild(busyDialog);
if (!layout.getDesktop().isServerPushEnabled())
{
layout.getDesktop().enableServerPush(true);
}
Runnable runnable = new Runnable() {
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
IServerPushCallback callback = new IServerPushCallback() {
public void updateUI() {
Properties ctx = (Properties)layout.getDesktop().getSession().getAttribute(SessionContextListener.SESSION_CTX);
try {
ServerContext.setCurrentInstance(ctx);
renderHomeTab();
} finally {
ServerContext.dispose();
}
}
};
ServerPushTemplate template = new ServerPushTemplate(layout.getDesktop());
template.executeAsync(callback);
}
};
Thread thread = new Thread(runnable);
thread.start();
return layout;
}
private void renderHomeTab()
{
homeTab.getChildren().clear();
//register as 0
registerWindow(homeTab);
dashboardController.render(homeTab, this, true);
}
public void onEvent(Event event)
{
Component comp = event.getTarget();
String eventName = event.getName();
if(eventName.equals(Events.ON_CLICK))
{
if(comp instanceof ToolBarButton)
{
ToolBarButton btn = (ToolBarButton) comp;
int menuId = 0;
try
{
menuId = Integer.valueOf(btn.getName());
}
catch (Exception e) {
}
if(menuId > 0) onMenuSelected(menuId);
}
}
else if(eventName.equals(Events.ON_DROP))
{
DropEvent de = (DropEvent) event;
Component dragged = de.getDragged();
if(dragged instanceof Treerow)
{
Treerow treerow = (Treerow) dragged;
Treeitem treeitem = (Treeitem) treerow.getParent();
favPanel.addItem(treeitem);
}
}
}
public void onServerPush(ServerPushTemplate template)
{
noOfNotice = DPActivities.getNoticeCount();
noOfRequest = DPActivities.getRequestCount();
noOfWorkflow = DPActivities.getWorkflowCount();
noOfUnprocessed = DPActivities.getUnprocessedCount();
template.executeAsync(this);
}
/**
*
* @param page
*/
public void setPage(Page page) {
if (this.page != page) {
layout.setPage(page);
this.page = page;
}
if (dashboardController != null) {
dashboardController.onSetPage(page, layout.getDesktop(), this);
}
}
/**
* Get the root component
* @return Component
*/
public Component getComponent() {
return layout;
}
public void logout() {
if (dashboardController != null) {
dashboardController.onLogOut();
}
}
public void updateUI() {
int total = noOfNotice + noOfRequest + noOfWorkflow + noOfUnprocessed;
navigationPanel.setLabel(2, "Activities (" + total + ")");
navigationPanel.setTooltiptext(2, Msg.translate(Env.getCtx(), "AD_Note_ID") + " : " + noOfNotice
+ ", " + Msg.translate(Env.getCtx(), "R_Request_ID") + " : " + noOfRequest
+ ", " + Msg.getMsg (Env.getCtx(), "WorkflowActivities") + " : " + noOfWorkflow
+ (noOfUnprocessed>0 ? ", " + Msg.getMsg (Env.getCtx(), "UnprocessedDocs") + " : " + noOfUnprocessed : "")
);
}
private void autoHideMenu() {
if (layout.getWest().isCollapsible() && !layout.getWest().isOpen())
{
//using undocumented js api, need to be retested after every version upgrade
String id = layout.getWest().getUuid() + "!real";
String btn = layout.getWest().getUuid() + "!btn";
String script = "zk.show('" + id + "', false);";
script += "$e('"+id+"')._isSlide = false;";
script += "$e('"+id+"')._lastSize = null;";
script += "$e('"+btn+"').style.display = '';";
AuScript aus = new AuScript(layout.getWest(), script);
Clients.response("autoHideWest", aus);
}
}
@Override
public ADWindow openWindow(int windowId) {
autoHideMenu();
return super.openWindow(windowId);
}
@Override
public ADForm openForm(int formId) {
autoHideMenu();
return super.openForm(formId);
}
@Override
public ProcessDialog openProcessDialog(int processId, boolean soTrx) {
autoHideMenu();
return super.openProcessDialog(processId, soTrx);
}
@Override
public void openTask(int taskId) {
autoHideMenu();
super.openTask(taskId);
}
@Override
public void openWorkflow(int workflowID) {
autoHideMenu();
super.openWorkflow(workflowID);
}
}

View File

@ -160,10 +160,10 @@ public class CustomizeGridViewPanel extends Panel
yesList.setSeltype("multiple");
noList.setSeltype("multiple");
bAdd.setImage("images/Detail24.png");
bAdd.setImage("images/Next24.png");
bAdd.addEventListener(Events.ON_CLICK, actionListener);
bRemove.setImage("images/Parent24.png");
bRemove.setImage("images/Previous24.png");
bRemove.addEventListener(Events.ON_CLICK, actionListener);
EventListener crossListMouseListener = new DragListener();
@ -179,10 +179,10 @@ public class CustomizeGridViewPanel extends Panel
}
};
bUp.setImage("images/Previous24.png");
bUp.setImage("images/Parent24.png");
bUp.addEventListener(Events.ON_CLICK, actionListener);
bDown.setImage("images/Next24.png");
bDown.setImage("images/Detail24.png");
bDown.addEventListener(Events.ON_CLICK, actionListener);
EventListener yesListMouseMotionListener = new EventListener()

View File

@ -247,7 +247,7 @@ public class WDocActionPanel extends Window implements EventListener<Event>, Dia
Grid grid = GridFactory.newGridLayout();
grid.setId("grd");
grid.setWidth("400px");
grid.setStyle("width: 390px; margin: auto;");
Rows rows = new Rows();
@ -258,10 +258,10 @@ public class WDocActionPanel extends Window implements EventListener<Event>, Dia
Panel pnlDocAction = new Panel();
pnlDocAction.appendChild(lblDocAction);
pnlDocAction.appendChild(new Space());
pnlDocAction.appendChild(lstDocAction);
rowDocAction.appendChild(pnlDocAction);
rowDocAction.setAlign("right");
rowLabel.appendChild(label);
rowConfirm.appendChild(confirmPanel);
rowSpacer.appendChild(new Space());

View File

@ -230,6 +230,22 @@ div.wc-modal, div.wc-modal-none, div.wc-highlighted, div.wc-highlighted-none {
margin-right: 2px;
}
.desktop-tabbox .z-tab .z-tab-hl, .desktop-tabbox .z-tab .z-tab-hr,
.desktop-tabbox .z-tab .z-tab-hm {
height: 22px;
}
.desktop-tabbox .z-tab-seld .z-tab-hl, .desktop-tabbox .z-tab-seld .z-tab-hr,
.desktop-tabbox .z-tab-seld .z-tab-hm {
height: 21px;
}
.desktop-tabbox .z-tab-seld {
border-top: 2px solid #666;
border-top-left-radius: 5px 5px;
border-top-right-radius: 5px 5px;
}
.desktop-north, .desktop-center {
border: none;
}
@ -485,8 +501,13 @@ div.wc-modal, div.wc-modal-none, div.wc-highlighted, div.wc-highlighted-none {
position: absolute;
}
.current-row-indicator {
background-color: #FA962F !important;
.row-indicator-seld {
background-color: #666 !important;
background-image: none !important;
}
.row-indicator {
background-color: transparent !important;
background-image: none !important;
}
@ -864,4 +885,17 @@ tbody.z-grid-empty-body td {
border-left: 6px dashed transparent;
border-right: 6px dashed transparent;
border-bottom: 6px solid #FFF;
}
.adwindow-detailpane-sub-tab::before {
content: '';
position: absolute;
width: 0px;
height: 0px;
top: 6px;
left: 4px;
border-top: 5px dashed transparent;
border-left: 5px dashed #696969;
border-right: 5px dashed transparent;
border-bottom: 5px solid transparent;
}