IDEMPIERE-5570 Zk: Improve readability of code (#1666)
This commit is contained in:
parent
801d1fb898
commit
19459be87b
|
@ -53,11 +53,13 @@ public class AtmosphereServerPush implements ServerPush {
|
||||||
|
|
||||||
private static final String ON_ACTIVATE_DESKTOP = "onActivateDesktop";
|
private static final String ON_ACTIVATE_DESKTOP = "onActivateDesktop";
|
||||||
|
|
||||||
|
/** default timeout of of 2 minutes **/
|
||||||
public static final int DEFAULT_TIMEOUT = 1000 * 60 * 2;
|
public static final int DEFAULT_TIMEOUT = 1000 * 60 * 2;
|
||||||
|
|
||||||
private final AtomicReference<Desktop> desktop = new AtomicReference<Desktop>();
|
private final AtomicReference<Desktop> desktop = new AtomicReference<Desktop>();
|
||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||||
|
/** asynchronous request reference as AtmosphereResource **/
|
||||||
private final AtomicReference<AtmosphereResource> resource = new AtomicReference<AtmosphereResource>();
|
private final AtomicReference<AtmosphereResource> resource = new AtomicReference<AtmosphereResource>();
|
||||||
private final int timeout;
|
private final int timeout;
|
||||||
|
|
||||||
|
@ -66,6 +68,9 @@ public class AtmosphereServerPush implements ServerPush {
|
||||||
private final Object _mutex = new Object();
|
private final Object _mutex = new Object();
|
||||||
private List<Schedule<Event>> schedules = new ArrayList<>();
|
private List<Schedule<Event>> schedules = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default constructor
|
||||||
|
*/
|
||||||
public AtmosphereServerPush() {
|
public AtmosphereServerPush() {
|
||||||
String timeoutString = Library.getProperty("fi.jawsy.jawwa.zk.atmosphere.timeout");
|
String timeoutString = Library.getProperty("fi.jawsy.jawwa.zk.atmosphere.timeout");
|
||||||
if (timeoutString == null || timeoutString.trim().length() == 0) {
|
if (timeoutString == null || timeoutString.trim().length() == 0) {
|
||||||
|
@ -120,10 +125,19 @@ public class AtmosphereServerPush implements ServerPush {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* release current AtmosphereResource
|
||||||
|
* @param resource
|
||||||
|
*/
|
||||||
public void clearResource(AtmosphereResource resource) {
|
public void clearResource(AtmosphereResource resource) {
|
||||||
this.resource.compareAndSet(resource, null);
|
this.resource.compareAndSet(resource, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* commit/resume response for current AtmosphereResource
|
||||||
|
* @return true if resource is available
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
private boolean commitResponse() throws IOException {
|
private boolean commitResponse() throws IOException {
|
||||||
AtmosphereResource resource = this.resource.getAndSet(null);
|
AtmosphereResource resource = this.resource.getAndSet(null);
|
||||||
if (resource != null) {
|
if (resource != null) {
|
||||||
|
@ -224,6 +238,10 @@ public class AtmosphereServerPush implements ServerPush {
|
||||||
startClientPush(desktop);
|
startClientPush(desktop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* start serverpush request at client side
|
||||||
|
* @param desktop
|
||||||
|
*/
|
||||||
private void startClientPush(Desktop desktop) {
|
private void startClientPush(Desktop desktop) {
|
||||||
Clients.response("jawwa.atmosphere.serverpush", new AuScript(null, "jawwa.atmosphere.startServerPush('" + desktop.getId() + "', " + timeout
|
Clients.response("jawwa.atmosphere.serverpush", new AuScript(null, "jawwa.atmosphere.startServerPush('" + desktop.getId() + "', " + timeout
|
||||||
+ ");"));
|
+ ");"));
|
||||||
|
@ -256,6 +274,10 @@ public class AtmosphereServerPush implements ServerPush {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle asynchronous server push request (long polling request)
|
||||||
|
* @param resource
|
||||||
|
*/
|
||||||
public void onRequest(AtmosphereResource resource) {
|
public void onRequest(AtmosphereResource resource) {
|
||||||
if (log.isTraceEnabled()) {
|
if (log.isTraceEnabled()) {
|
||||||
log.trace(resource.transport().name());
|
log.trace(resource.transport().name());
|
||||||
|
@ -267,6 +289,7 @@ public class AtmosphereServerPush implements ServerPush {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//suspend request for server push event
|
||||||
if (!resource.isSuspended()) {
|
if (!resource.isSuspended()) {
|
||||||
//browser default timeout is 2 minutes
|
//browser default timeout is 2 minutes
|
||||||
resource.suspend(5, TimeUnit.MINUTES);
|
resource.suspend(5, TimeUnit.MINUTES);
|
||||||
|
|
|
@ -1,18 +1,59 @@
|
||||||
|
/***********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* 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., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - hengsin *
|
||||||
|
**********************************************************************/
|
||||||
package fi.jawsy.jawwa.zk.atmosphere;
|
package fi.jawsy.jawwa.zk.atmosphere;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class to hold two value, left and right
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
* @param <L>
|
||||||
|
* @param <R>
|
||||||
|
*/
|
||||||
public class Either<L, R> {
|
public class Either<L, R> {
|
||||||
private L left;
|
private L left;
|
||||||
private R right;
|
private R right;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param l left value
|
||||||
|
* @param r right value
|
||||||
|
*/
|
||||||
public Either(L l, R r) {
|
public Either(L l, R r) {
|
||||||
left = l;
|
left = l;
|
||||||
right = r;
|
right = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return left value
|
||||||
|
*/
|
||||||
public L getLeftValue() {
|
public L getLeftValue() {
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return right value
|
||||||
|
*/
|
||||||
public R getRightValue() {
|
public R getRightValue() {
|
||||||
return right;
|
return right;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,12 @@ public class ZkAtmosphereHandler implements AtmosphereHandler {
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Zk {@link Desktop} instance from session by desktop id
|
||||||
|
* @param session
|
||||||
|
* @param dtid desktop id
|
||||||
|
* @return left as error message and right as {@link Desktop} reference
|
||||||
|
*/
|
||||||
private Either<String, Desktop> getDesktop(Session session, String dtid) {
|
private Either<String, Desktop> getDesktop(Session session, String dtid) {
|
||||||
if (session.getWebApp() instanceof WebAppCtrl) {
|
if (session.getWebApp() instanceof WebAppCtrl) {
|
||||||
WebAppCtrl webAppCtrl = (WebAppCtrl) session.getWebApp();
|
WebAppCtrl webAppCtrl = (WebAppCtrl) session.getWebApp();
|
||||||
|
@ -64,11 +70,21 @@ public class ZkAtmosphereHandler implements AtmosphereHandler {
|
||||||
return new Either<String, Desktop>("Webapp does not implement WebAppCtrl", null);
|
return new Either<String, Desktop>("Webapp does not implement WebAppCtrl", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Zk {@link Desktop} id from HttpServletRequest parameter (dtid)
|
||||||
|
* @param request
|
||||||
|
* @return left as desktop id and right as error message
|
||||||
|
*/
|
||||||
private Either<String, String> getDesktopId(HttpServletRequest request) {
|
private Either<String, String> getDesktopId(HttpServletRequest request) {
|
||||||
String dtid = request.getParameter("dtid");
|
String dtid = request.getParameter("dtid");
|
||||||
return new Either<String, String>(dtid, DESKTOP_NOT_FOUND);
|
return new Either<String, String>(dtid, DESKTOP_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get {@link AtmosphereServerPush} instance from {@link AtmosphereResource}
|
||||||
|
* @param resource {@link AtmosphereResource}
|
||||||
|
* @return left as error message and right as AtmosphereServerPush reference
|
||||||
|
*/
|
||||||
private Either<String, AtmosphereServerPush> getServerPush(AtmosphereResource resource) {
|
private Either<String, AtmosphereServerPush> getServerPush(AtmosphereResource resource) {
|
||||||
AtmosphereRequest request = resource.getRequest();
|
AtmosphereRequest request = resource.getRequest();
|
||||||
|
|
||||||
|
@ -96,6 +112,11 @@ public class ZkAtmosphereHandler implements AtmosphereHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get {@link AtmosphereServerPush} instance from {@link Desktop}
|
||||||
|
* @param desktop
|
||||||
|
* @return left as error message and right as {@link AtmosphereServerPush} reference
|
||||||
|
*/
|
||||||
private Either<String, AtmosphereServerPush> getServerPush(Desktop desktop) {
|
private Either<String, AtmosphereServerPush> getServerPush(Desktop desktop) {
|
||||||
if (desktop instanceof DesktopCtrl) {
|
if (desktop instanceof DesktopCtrl) {
|
||||||
DesktopCtrl desktopCtrl = (DesktopCtrl) desktop;
|
DesktopCtrl desktopCtrl = (DesktopCtrl) desktop;
|
||||||
|
@ -109,6 +130,12 @@ public class ZkAtmosphereHandler implements AtmosphereHandler {
|
||||||
return new Either<String, AtmosphereServerPush>("Desktop does not implement DesktopCtrl", null);
|
return new Either<String, AtmosphereServerPush>("Desktop does not implement DesktopCtrl", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get {@link Session} from request
|
||||||
|
* @param resource
|
||||||
|
* @param request
|
||||||
|
* @return left as error message and right as Session reference
|
||||||
|
*/
|
||||||
private Either<String, Session> getSession(AtmosphereResource resource, HttpServletRequest request) {
|
private Either<String, Session> getSession(AtmosphereResource resource, HttpServletRequest request) {
|
||||||
Session session = WebManager.getSession(resource.getAtmosphereConfig().getServletContext(), request, false);
|
Session session = WebManager.getSession(resource.getAtmosphereConfig().getServletContext(), request, false);
|
||||||
if (session == null) {
|
if (session == null) {
|
||||||
|
|
|
@ -90,23 +90,31 @@ import org.zkoss.zul.Window;
|
||||||
*/
|
*/
|
||||||
public class AdempiereWebUI extends Window implements EventListener<Event>, IWebClient
|
public class AdempiereWebUI extends Window implements EventListener<Event>, IWebClient
|
||||||
{
|
{
|
||||||
|
/** {@link Session} attribute to hold current login user id value **/
|
||||||
|
public static final String CHECK_AD_USER_ID_ATTR = "Check_AD_User_ID";
|
||||||
|
|
||||||
|
/** Boolean attribute to indicate the HTTP session of a Desktop have been invalidated **/
|
||||||
public static final String DESKTOP_SESSION_INVALIDATED_ATTR = "DesktopSessionInvalidated";
|
public static final String DESKTOP_SESSION_INVALIDATED_ATTR = "DesktopSessionInvalidated";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -6725805283410008847L;
|
private static final long serialVersionUID = -6725805283410008847L;
|
||||||
|
|
||||||
|
/** {@link Desktop} attribute to hold {@link IDesktop} reference **/
|
||||||
public static final String APPLICATION_DESKTOP_KEY = "application.desktop";
|
public static final String APPLICATION_DESKTOP_KEY = "application.desktop";
|
||||||
|
|
||||||
public static String APP_NAME = null;
|
public static String APP_NAME = null;
|
||||||
|
|
||||||
public static final String UID = "1.0.0";
|
public static final String UID = "1.0.0";
|
||||||
|
|
||||||
|
/** Attribute for widget instance name, use for Selenium test **/
|
||||||
public static final String WIDGET_INSTANCE_NAME = "instanceName";
|
public static final String WIDGET_INSTANCE_NAME = "instanceName";
|
||||||
|
|
||||||
|
/** login and role selection window **/
|
||||||
private WLogin loginDesktop;
|
private WLogin loginDesktop;
|
||||||
|
|
||||||
|
/** client info from browser **/
|
||||||
private ClientInfo clientInfo = new ClientInfo();
|
private ClientInfo clientInfo = new ClientInfo();
|
||||||
|
|
||||||
private String langSession;
|
private String langSession;
|
||||||
|
@ -119,16 +127,23 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
|
|
||||||
private static final CLogger logger = CLogger.getCLogger(AdempiereWebUI.class);
|
private static final CLogger logger = CLogger.getCLogger(AdempiereWebUI.class);
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true, since = "11")
|
||||||
public static final String EXECUTION_CARRYOVER_SESSION_KEY = "execution.carryover";
|
public static final String EXECUTION_CARRYOVER_SESSION_KEY = "execution.carryover";
|
||||||
|
|
||||||
|
/** Session attribute to hold {@link ClientInfo} reference **/
|
||||||
private static final String CLIENT_INFO = "client.info";
|
private static final String CLIENT_INFO = "client.info";
|
||||||
|
|
||||||
|
/** the use of event thread have been deprecated, this should always be false **/
|
||||||
private static boolean eventThreadEnabled = false;
|
private static boolean eventThreadEnabled = false;
|
||||||
|
|
||||||
private ConcurrentMap<String, String[]> m_URLParameters;
|
private ConcurrentMap<String, String[]> m_URLParameters;
|
||||||
|
|
||||||
|
/** Login completed event **/
|
||||||
private static final String ON_LOGIN_COMPLETED = "onLoginCompleted";
|
private static final String ON_LOGIN_COMPLETED = "onLoginCompleted";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default constructor
|
||||||
|
*/
|
||||||
public AdempiereWebUI()
|
public AdempiereWebUI()
|
||||||
{
|
{
|
||||||
this.setVisible(false);
|
this.setVisible(false);
|
||||||
|
@ -140,8 +155,12 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
this.addEventListener(ON_LOGIN_COMPLETED, this);
|
this.addEventListener(ON_LOGIN_COMPLETED, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle onCreate event from index.zul, don't call this directly.
|
||||||
|
*/
|
||||||
public void onCreate()
|
public void onCreate()
|
||||||
{
|
{
|
||||||
|
//handle ping request
|
||||||
String ping = Executions.getCurrent().getHeader("X-PING");
|
String ping = Executions.getCurrent().getHeader("X-PING");
|
||||||
if (!Util.isEmpty(ping, true))
|
if (!Util.isEmpty(ping, true))
|
||||||
{
|
{
|
||||||
|
@ -183,6 +202,9 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
eventThreadEnabled = Executions.getCurrent().getDesktop().getWebApp().getConfiguration().isEventThreadEnabled();
|
eventThreadEnabled = Executions.getCurrent().getDesktop().getWebApp().getConfiguration().isEventThreadEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* perform clean up for ping request
|
||||||
|
*/
|
||||||
private void cleanupForPing() {
|
private void cleanupForPing() {
|
||||||
final Desktop desktop = Executions.getCurrent().getDesktop();
|
final Desktop desktop = Executions.getCurrent().getDesktop();
|
||||||
final WebApp wapp = desktop.getWebApp();
|
final WebApp wapp = desktop.getWebApp();
|
||||||
|
@ -208,10 +230,16 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
}, 1, TimeUnit.SECONDS);
|
}, 1, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle onOK (enter key) event
|
||||||
|
*/
|
||||||
public void onOk()
|
public void onOk()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle onCancel(escape key) event
|
||||||
|
*/
|
||||||
public void onCancel()
|
public void onCancel()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -219,6 +247,7 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.adempiere.webui.IWebClient#loginCompleted()
|
* @see org.adempiere.webui.IWebClient#loginCompleted()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void loginCompleted()
|
public void loginCompleted()
|
||||||
{
|
{
|
||||||
if (loginDesktop != null)
|
if (loginDesktop != null)
|
||||||
|
@ -280,7 +309,7 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
mSession.saveEx();
|
mSession.saveEx();
|
||||||
}
|
}
|
||||||
|
|
||||||
currSess.setAttribute("Check_AD_User_ID", Env.getAD_User_ID(ctx));
|
currSess.setAttribute(CHECK_AD_USER_ID_ATTR, Env.getAD_User_ID(ctx));
|
||||||
|
|
||||||
//enable full interface, relook into this when doing preference
|
//enable full interface, relook into this when doing preference
|
||||||
Env.setContext(ctx, Env.SHOW_TRANSLATION, true);
|
Env.setContext(ctx, Env.SHOW_TRANSLATION, true);
|
||||||
|
@ -298,14 +327,14 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
keyListener.setCtrlKeys("@a@c@d@e@f@h@l@m@n@o@p@q@r@s@t@w@x@z@#left@#right@#up@#down@#home@#end#enter^u@u@#pgdn@#pgup$#f2^#f2");
|
keyListener.setCtrlKeys("@a@c@d@e@f@h@l@m@n@o@p@q@r@s@t@w@x@z@#left@#right@#up@#down@#home@#end#enter^u@u@#pgdn@#pgup$#f2^#f2");
|
||||||
keyListener.setAutoBlur(false);
|
keyListener.setAutoBlur(false);
|
||||||
|
|
||||||
//create new desktop
|
//create IDesktop instance
|
||||||
IDesktop appDesktop = createDesktop();
|
IDesktop appDesktop = createDesktop();
|
||||||
appDesktop.setClientInfo(clientInfo);
|
appDesktop.setClientInfo(clientInfo);
|
||||||
appDesktop.createPart(this.getPage());
|
appDesktop.createPart(this.getPage());
|
||||||
this.getPage().getDesktop().setAttribute(APPLICATION_DESKTOP_KEY, new WeakReference<IDesktop>(appDesktop));
|
this.getPage().getDesktop().setAttribute(APPLICATION_DESKTOP_KEY, new WeakReference<IDesktop>(appDesktop));
|
||||||
appDesktop.getComponent().getRoot().addEventListener(Events.ON_CLIENT_INFO, this);
|
appDesktop.getComponent().getRoot().addEventListener(Events.ON_CLIENT_INFO, this);
|
||||||
|
|
||||||
//track browser tab per session
|
//track browser tab per session, 1 browser tab = 1 zk Desktop
|
||||||
SessionContextListener.addDesktopId(mSession.getAD_Session_ID(), getPage().getDesktop().getId());
|
SessionContextListener.addDesktopId(mSession.getAD_Session_ID(), getPage().getDesktop().getId());
|
||||||
|
|
||||||
//ensure server push is on
|
//ensure server push is on
|
||||||
|
@ -330,7 +359,7 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
Env.setContext(ctx, Env.IS_CAN_APPROVE_OWN_DOC, MRole.getDefault().isCanApproveOwnDoc());
|
Env.setContext(ctx, Env.IS_CAN_APPROVE_OWN_DOC, MRole.getDefault().isCanApproveOwnDoc());
|
||||||
Clients.response(new AuScript("zAu.cmd0.clearBusy()"));
|
Clients.response(new AuScript("zAu.cmd0.clearBusy()"));
|
||||||
|
|
||||||
//add dynamic style
|
//add dynamic style for AD tab
|
||||||
StringBuilder cssContent = new StringBuilder();
|
StringBuilder cssContent = new StringBuilder();
|
||||||
cssContent.append(".adtab-form-borderlayout .z-south-collapsed:before { ");
|
cssContent.append(".adtab-form-borderlayout .z-south-collapsed:before { ");
|
||||||
cssContent.append("content: \"");
|
cssContent.append("content: \"");
|
||||||
|
@ -347,6 +376,9 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
processParameters();
|
processParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* process URL parameters from browser
|
||||||
|
*/
|
||||||
private void processParameters() {
|
private void processParameters() {
|
||||||
String action = getPrmString("Action");
|
String action = getPrmString("Action");
|
||||||
if ("Zoom".equalsIgnoreCase(action)) {
|
if ("Zoom".equalsIgnoreCase(action)) {
|
||||||
|
@ -368,6 +400,10 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
m_URLParameters = null;
|
m_URLParameters = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param prm parameter name
|
||||||
|
* @return string value for parameter
|
||||||
|
*/
|
||||||
private String getPrmString(String prm) {
|
private String getPrmString(String prm) {
|
||||||
String retValue = "";
|
String retValue = "";
|
||||||
if (m_URLParameters != null) {
|
if (m_URLParameters != null) {
|
||||||
|
@ -378,6 +414,10 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
return retValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param prm parameter name
|
||||||
|
* @return integer value for parameter
|
||||||
|
*/
|
||||||
private int getPrmInt(String prm) {
|
private int getPrmInt(String prm) {
|
||||||
int retValue = 0;
|
int retValue = 0;
|
||||||
String str = getPrmString(prm);
|
String str = getPrmString(prm);
|
||||||
|
@ -398,6 +438,10 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
return keyListener;
|
return keyListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create IDesktop instance. Default is {@link DefaultDesktop}
|
||||||
|
* @return {@link IDesktop}
|
||||||
|
*/
|
||||||
private IDesktop createDesktop()
|
private IDesktop createDesktop()
|
||||||
{
|
{
|
||||||
IDesktop appDesktop = null;
|
IDesktop appDesktop = null;
|
||||||
|
@ -424,6 +468,7 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.adempiere.webui.IWebClient#logout()
|
* @see org.adempiere.webui.IWebClient#logout()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void logout()
|
public void logout()
|
||||||
{
|
{
|
||||||
final Desktop desktop = Executions.getCurrent().getDesktop();
|
final Desktop desktop = Executions.getCurrent().getDesktop();
|
||||||
|
@ -447,6 +492,10 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* after logout action for Session
|
||||||
|
* @param session
|
||||||
|
*/
|
||||||
private void afterLogout(final Session session) {
|
private void afterLogout(final Session session) {
|
||||||
try {
|
try {
|
||||||
((SessionCtrl)session).onDestroyed();
|
((SessionCtrl)session).onDestroyed();
|
||||||
|
@ -457,7 +506,7 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform logout after user close a browser tab without first logging out
|
* Auto logout after user close browser tab without first logging out
|
||||||
*/
|
*/
|
||||||
public void logoutAfterTabDestroyed(){
|
public void logoutAfterTabDestroyed(){
|
||||||
Desktop desktop = Executions.getCurrent().getDesktop();
|
Desktop desktop = Executions.getCurrent().getDesktop();
|
||||||
|
@ -472,7 +521,10 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
afterLogout(session);
|
afterLogout(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logout current session
|
||||||
|
* @return {@link Session}
|
||||||
|
*/
|
||||||
protected Session logout0() {
|
protected Session logout0() {
|
||||||
Session session = Executions.getCurrent() != null ? Executions.getCurrent().getDesktop().getSession() : null;
|
Session session = Executions.getCurrent() != null ? Executions.getCurrent().getDesktop().getSession() : null;
|
||||||
|
|
||||||
|
@ -502,6 +554,7 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
/**
|
/**
|
||||||
* @return IDesktop
|
* @return IDesktop
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public IDesktop getAppDeskop()
|
public IDesktop getAppDeskop()
|
||||||
{
|
{
|
||||||
Desktop desktop = Executions.getCurrent() != null ? Executions.getCurrent().getDesktop() : null;
|
Desktop desktop = Executions.getCurrent() != null ? Executions.getCurrent().getDesktop() : null;
|
||||||
|
@ -519,6 +572,7 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
return appDesktop;
|
return appDesktop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onEvent(Event event) {
|
public void onEvent(Event event) {
|
||||||
if (event instanceof ClientInfoEvent) {
|
if (event instanceof ClientInfoEvent) {
|
||||||
ClientInfoEvent c = (ClientInfoEvent)event;
|
ClientInfoEvent c = (ClientInfoEvent)event;
|
||||||
|
@ -564,6 +618,11 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle change role event
|
||||||
|
* @param locale
|
||||||
|
* @param context
|
||||||
|
*/
|
||||||
private void onChangeRole(Locale locale, Properties context) {
|
private void onChangeRole(Locale locale, Properties context) {
|
||||||
SessionManager.setSessionApplication(this);
|
SessionManager.setSessionApplication(this);
|
||||||
loginDesktop = new WLogin(this);
|
loginDesktop = new WLogin(this);
|
||||||
|
@ -576,6 +635,7 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
* @param userId
|
* @param userId
|
||||||
* @return UserPreference
|
* @return UserPreference
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public UserPreference loadUserPreference(int userId) {
|
public UserPreference loadUserPreference(int userId) {
|
||||||
userPreference.loadPreference(userId);
|
userPreference.loadPreference(userId);
|
||||||
return userPreference;
|
return userPreference;
|
||||||
|
@ -584,10 +644,15 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
/**
|
/**
|
||||||
* @return UserPrerence
|
* @return UserPrerence
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public UserPreference getUserPreference() {
|
public UserPreference getUserPreference() {
|
||||||
return userPreference;
|
return userPreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should always return false
|
||||||
|
* @return true if event thread is enabled
|
||||||
|
*/
|
||||||
public static boolean isEventThreadEnabled() {
|
public static boolean isEventThreadEnabled() {
|
||||||
return eventThreadEnabled;
|
return eventThreadEnabled;
|
||||||
}
|
}
|
||||||
|
@ -635,6 +700,12 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
appDesktop.logout(T -> {if (T) asyncChangeRole(session, locale, properties);});
|
appDesktop.logout(T -> {if (T) asyncChangeRole(session, locale, properties);});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* change role, asynchronous callback from {@link IDesktop#logout(org.adempiere.util.Callback)}
|
||||||
|
* @param httpSession
|
||||||
|
* @param locale
|
||||||
|
* @param properties
|
||||||
|
*/
|
||||||
private void asyncChangeRole(HttpSession httpSession, Locale locale, Properties properties) {
|
private void asyncChangeRole(HttpSession httpSession, Locale locale, Properties properties) {
|
||||||
//stop key listener
|
//stop key listener
|
||||||
if (keyListener != null) {
|
if (keyListener != null) {
|
||||||
|
@ -675,8 +746,8 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string for setupload
|
* @return setting for setUpload call
|
||||||
*/
|
*/
|
||||||
public static String getUploadSetting() {
|
public static String getUploadSetting() {
|
||||||
StringBuilder uploadSetting = new StringBuilder("true,native");
|
StringBuilder uploadSetting = new StringBuilder("true,native");
|
||||||
int size = MSysConfig.getIntValue(MSysConfig.ZK_MAX_UPLOAD_SIZE, 0);
|
int size = MSysConfig.getIntValue(MSysConfig.ZK_MAX_UPLOAD_SIZE, 0);
|
||||||
|
|
|
@ -29,16 +29,17 @@ import org.zkoss.zk.ui.event.Events;
|
||||||
import org.zkoss.zk.ui.sys.ComponentCtrl;
|
import org.zkoss.zk.ui.sys.ComponentCtrl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Model for client info from browser
|
||||||
* @author Low Heng Sin
|
* @author Low Heng Sin
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ClientInfo implements Serializable {
|
public class ClientInfo implements Serializable {
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -2686811277627911861L;
|
private static final long serialVersionUID = -2686811277627911861L;
|
||||||
|
|
||||||
|
//values from browser
|
||||||
public int colorDepth;
|
public int colorDepth;
|
||||||
public int desktopWidth;
|
public int desktopWidth;
|
||||||
public int desktopHeight;
|
public int desktopHeight;
|
||||||
|
@ -52,6 +53,7 @@ public class ClientInfo implements Serializable {
|
||||||
public boolean tablet;
|
public boolean tablet;
|
||||||
public double devicePixelRatio;
|
public double devicePixelRatio;
|
||||||
|
|
||||||
|
//size constants for responsive layout
|
||||||
public static final int LARGE_WIDTH = 1200;
|
public static final int LARGE_WIDTH = 1200;
|
||||||
public static final int MEDIUM_WIDTH = 1000;
|
public static final int MEDIUM_WIDTH = 1000;
|
||||||
public static final int SMALL_WIDTH = 700;
|
public static final int SMALL_WIDTH = 700;
|
||||||
|
|
|
@ -67,7 +67,7 @@ public class DefaultWebAppInit implements WebAppInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process modle event of table system config
|
* Process model event of table system config
|
||||||
* @author hieplq
|
* @author hieplq
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -10,6 +10,7 @@ import javax.servlet.ServletRequest;
|
||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.ServletResponse;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true, since = "11")
|
||||||
public class DelegatingServlet extends HttpServlet {
|
public class DelegatingServlet extends HttpServlet {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -50,7 +50,7 @@ import org.idempiere.ui.zk.media.IMediaViewProvider;
|
||||||
import org.zkoss.zk.ui.Component;
|
import org.zkoss.zk.ui.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Entry point to get implementation instance for UI extensions (through OSGI service or Equinox extension).
|
||||||
* @author viola
|
* @author viola
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
*
|
||||||
|
@ -372,8 +372,8 @@ public class Extensions {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param tabType
|
* @param tabType build in - FORM or SORT, custom - through IADTabPanelFactory extension
|
||||||
* @return {@link IADTabpanel}
|
* @return {@link IADTabpanel}
|
||||||
*/
|
*/
|
||||||
public static IADTabpanel getADTabPanel(String tabType)
|
public static IADTabpanel getADTabPanel(String tabType)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,56 +18,61 @@ import org.compiere.model.MUser;
|
||||||
import org.zkforge.keylistener.Keylistener;
|
import org.zkforge.keylistener.Keylistener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Interface for web client
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface IWebClient {
|
public interface IWebClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* login completed
|
* handle login completed
|
||||||
*/
|
*/
|
||||||
public void loginCompleted();
|
public void loginCompleted();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* logout
|
* handle logout
|
||||||
*/
|
*/
|
||||||
public void logout();
|
public void logout();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* logout after browser destroyed
|
* auto logout after close of browser tab
|
||||||
*/
|
*/
|
||||||
public void logoutAfterTabDestroyed();
|
public void logoutAfterTabDestroyed();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Get {@link IDesktop} instance
|
||||||
* @return IDesktop
|
* @return IDesktop
|
||||||
*/
|
*/
|
||||||
public IDesktop getAppDeskop();
|
public IDesktop getAppDeskop();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* load user preference by user id
|
||||||
* @param userId
|
* @param userId
|
||||||
* @return UserPreference
|
* @return UserPreference
|
||||||
*/
|
*/
|
||||||
public UserPreference loadUserPreference(int userId);
|
public UserPreference loadUserPreference(int userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Get current user preference
|
||||||
* @return UserPreference
|
* @return UserPreference
|
||||||
*/
|
*/
|
||||||
public UserPreference getUserPreference();
|
public UserPreference getUserPreference();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* change Role
|
* handle change Role
|
||||||
*/
|
*/
|
||||||
public void changeRole(MUser user);
|
public void changeRole(MUser user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return keylistener
|
* Get global key listener
|
||||||
|
* @return {@link Keylistener}
|
||||||
*/
|
*/
|
||||||
public abstract Keylistener getKeylistener();
|
public abstract Keylistener getKeylistener();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current ClientInfo
|
||||||
|
* @return {@link ClientInfo}
|
||||||
|
*/
|
||||||
default ClientInfo getClientInfo() {
|
default ClientInfo getClientInfo() {
|
||||||
return getAppDeskop().getClientInfo();
|
return getAppDeskop().getClientInfo();
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ import org.zkoss.zul.Window;
|
||||||
import org.zkoss.zul.Window.Mode;
|
import org.zkoss.zul.Window.Mode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Some static UI helper methods
|
||||||
* @author Low Heng Sin
|
* @author Low Heng Sin
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -55,7 +55,7 @@ public final class LayoutUtils {
|
||||||
/**
|
/**
|
||||||
* @param layout
|
* @param layout
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated(forRemoval = true, since = "11")
|
||||||
public static void sendDeferLayoutEvent(org.zkoss.zul.Borderlayout layout, int timeout) {
|
public static void sendDeferLayoutEvent(org.zkoss.zul.Borderlayout layout, int timeout) {
|
||||||
/* this is not required anymore */
|
/* this is not required anymore */
|
||||||
// StringBuilder content = new StringBuilder();
|
// StringBuilder content = new StringBuilder();
|
||||||
|
@ -68,7 +68,7 @@ public final class LayoutUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* append cls to target's sclass property
|
||||||
* @param cls
|
* @param cls
|
||||||
* @param target
|
* @param target
|
||||||
*/
|
*/
|
||||||
|
@ -82,7 +82,7 @@ public final class LayoutUtils {
|
||||||
*
|
*
|
||||||
* @param cls
|
* @param cls
|
||||||
* @param target
|
* @param target
|
||||||
* @return boolean
|
* @return true if target's sclass property contain cls
|
||||||
*/
|
*/
|
||||||
public static boolean hasSclass(String cls, HtmlBasedComponent target) {
|
public static boolean hasSclass(String cls, HtmlBasedComponent target) {
|
||||||
String sclass = target.getSclass();
|
String sclass = target.getSclass();
|
||||||
|
@ -93,9 +93,9 @@ public final class LayoutUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* create right align label (wrapped in div)
|
||||||
* @param label
|
* @param label
|
||||||
* @return wrapped label
|
* @return right align label (wrapped in div)
|
||||||
*/
|
*/
|
||||||
public static Component makeRightAlign(Label label) {
|
public static Component makeRightAlign(Label label) {
|
||||||
Div div = new Div();
|
Div div = new Div();
|
||||||
|
@ -105,28 +105,41 @@ public final class LayoutUtils {
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* open popup window overlapping ref component
|
||||||
|
* @param ref
|
||||||
|
* @param window
|
||||||
|
*/
|
||||||
public static void openPopupWindow(Component ref, Window window) {
|
public static void openPopupWindow(Component ref, Window window) {
|
||||||
openPopupWindow(ref, window, 0);
|
openPopupWindow(ref, window, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* open popup window overlapping the ref component
|
* open popup window overlapping ref component
|
||||||
* @param ref
|
* @param ref
|
||||||
* @param window
|
* @param window
|
||||||
|
* @param delayMs
|
||||||
*/
|
*/
|
||||||
public static void openPopupWindow(Component ref, Window window, int delayMs) {
|
public static void openPopupWindow(Component ref, Window window, int delayMs) {
|
||||||
openPopupWindow(ref, window, "overlap", delayMs);
|
openPopupWindow(ref, window, "overlap", delayMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* open popup window relative to ref component
|
||||||
|
* @param ref
|
||||||
|
* @param window
|
||||||
|
* @param position Refer to https://www.zkoss.org/javadoc/latest/jsdoc/_global_/jqzk.html#position-_global_.Dimension-_global_.String-_global_.Map-
|
||||||
|
*/
|
||||||
public static void openPopupWindow(Component ref, Window window, String position) {
|
public static void openPopupWindow(Component ref, Window window, String position) {
|
||||||
openPopupWindow(ref, window, position, 0);
|
openPopupWindow(ref, window, position, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* open popup window relative to the ref component
|
* open popup window relative to ref component
|
||||||
* @param ref
|
* @param ref
|
||||||
* @param window
|
* @param window
|
||||||
* @param position
|
* @param position Refer to https://www.zkoss.org/javadoc/latest/jsdoc/_global_/jqzk.html#position-_global_.Dimension-_global_.String-_global_.Map-
|
||||||
|
* @param delayMs
|
||||||
*/
|
*/
|
||||||
public static void openPopupWindow(Component ref, Window window, String position, int delayMs) {
|
public static void openPopupWindow(Component ref, Window window, String position, int delayMs) {
|
||||||
if (window.getPage() == null)
|
if (window.getPage() == null)
|
||||||
|
@ -152,10 +165,10 @@ public final class LayoutUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* open popup window relative to the ref component
|
* open overlapped window (mode overlapped) relative to ref component
|
||||||
* @param ref
|
* @param ref
|
||||||
* @param window
|
* @param window
|
||||||
* @param position
|
* @param position Refer to https://www.zkoss.org/javadoc/latest/jsdoc/_global_/jqzk.html#position-_global_.Dimension-_global_.String-_global_.Map-
|
||||||
*/
|
*/
|
||||||
public static void openOverlappedWindow(Component ref, Window window, String position) {
|
public static void openOverlappedWindow(Component ref, Window window, String position) {
|
||||||
if (window.getPage() == null)
|
if (window.getPage() == null)
|
||||||
|
@ -173,10 +186,10 @@ public final class LayoutUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* position opened window relative to the ref component
|
* position opened window relative to ref component
|
||||||
* @param ref
|
* @param ref
|
||||||
* @param window
|
* @param window
|
||||||
* @param position
|
* @param position Refer to https://www.zkoss.org/javadoc/latest/jsdoc/_global_/jqzk.html#position-_global_.Dimension-_global_.String-_global_.Map-
|
||||||
*/
|
*/
|
||||||
public static void positionWindow(Component ref, Window window, String position) {
|
public static void positionWindow(Component ref, Window window, String position) {
|
||||||
StringBuilder script = new StringBuilder();
|
StringBuilder script = new StringBuilder();
|
||||||
|
@ -191,10 +204,10 @@ public final class LayoutUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* open embedded window relative to the ref component
|
* open embedded window relative to ref component
|
||||||
* @param ref
|
* @param ref
|
||||||
* @param window
|
* @param window
|
||||||
* @param position
|
* @param position Refer to https://www.zkoss.org/javadoc/latest/jsdoc/_global_/jqzk.html#position-_global_.Dimension-_global_.String-_global_.Map-
|
||||||
*/
|
*/
|
||||||
public static void openEmbeddedWindow(Component ref, Window window, String position) {
|
public static void openEmbeddedWindow(Component ref, Window window, String position) {
|
||||||
StringBuilder script = new StringBuilder();
|
StringBuilder script = new StringBuilder();
|
||||||
|
@ -211,10 +224,10 @@ public final class LayoutUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* open highlighted window relative to the ref component
|
* open highlighted window relative to ref component
|
||||||
* @param ref
|
* @param ref
|
||||||
* @param window
|
* @param window
|
||||||
* @param position
|
* @param position Refer to https://www.zkoss.org/javadoc/latest/jsdoc/_global_/jqzk.html#position-_global_.Dimension-_global_.String-_global_.Map-
|
||||||
*/
|
*/
|
||||||
public static void openHighlightedWindow(Component ref, Window window, String position) {
|
public static void openHighlightedWindow(Component ref, Window window, String position) {
|
||||||
StringBuilder script = new StringBuilder();
|
StringBuilder script = new StringBuilder();
|
||||||
|
@ -230,7 +243,7 @@ public final class LayoutUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Force redraw of component
|
||||||
* @param component
|
* @param component
|
||||||
*/
|
*/
|
||||||
public static void redraw(AbstractComponent component) {
|
public static void redraw(AbstractComponent component) {
|
||||||
|
@ -259,6 +272,11 @@ public final class LayoutUtils {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove cls from target's sclass property
|
||||||
|
* @param cls
|
||||||
|
* @param target
|
||||||
|
*/
|
||||||
public static void removeSclass(String cls, HtmlBasedComponent target) {
|
public static void removeSclass(String cls, HtmlBasedComponent target) {
|
||||||
String sclass = target.getSclass();
|
String sclass = target.getSclass();
|
||||||
if (Util.isEmpty(sclass))
|
if (Util.isEmpty(sclass))
|
||||||
|
@ -281,13 +299,13 @@ public final class LayoutUtils {
|
||||||
/**
|
/**
|
||||||
* show window with a mask below. mask over tabPanel, all window or only over a control, dependency ownModel flag.
|
* show window with a mask below. mask over tabPanel, all window or only over a control, dependency ownModel flag.
|
||||||
* when ownModel == {@link #OVERLAP_SELF}, window show overlap childOfOwn,
|
* when ownModel == {@link #OVERLAP_SELF}, window show overlap childOfOwn,
|
||||||
* when childOfOwn isn't implement {@link ISupportMask} make new {@link Mask} object to make mask layout
|
* when childOfOwn doesn't implement {@link ISupportMask} make new {@link Mask} object to make mask layout
|
||||||
* ownModel == {@link #OVERLAP_ALL_PAGE}, window show overlap all page
|
* ownModel == {@link #OVERLAP_ALL_PAGE}, window show overlap all page
|
||||||
* ownModel == {@link #OVERLAP_TAB_PANEL}, window show overlap tabPanel
|
* ownModel == {@link #OVERLAP_TAB_PANEL}, window show overlap tabPanel
|
||||||
* ownModel == {@link #OVERLAP_PARENT}, search near parent of childOfOwn implement {@link ISupportMask} if not exist user as OVERLAP_ALL_PAGE
|
* ownModel == {@link #OVERLAP_PARENT}, search near parent of childOfOwn implement {@link ISupportMask} if not exist user as OVERLAP_ALL_PAGE
|
||||||
* @param window
|
* @param window
|
||||||
* @param childOfOwn
|
* @param childOfOwn
|
||||||
* @param ownModel
|
* @param ownModel OVERLAP_TAB_PANEL, OVERLAP_ALL_PAGE, OVERLAP_PARENT or OVERLAP_SELF
|
||||||
* @return when show success return IMask object, it is own window, use {@link ISupportMask#hideMask()} to hidden mask.
|
* @return when show success return IMask object, it is own window, use {@link ISupportMask#hideMask()} to hidden mask.
|
||||||
* other return null.
|
* other return null.
|
||||||
*/
|
*/
|
||||||
|
@ -316,7 +334,7 @@ public final class LayoutUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show window in center of component
|
* Show window in center of mask
|
||||||
* @param window
|
* @param window
|
||||||
* @param mask
|
* @param mask
|
||||||
*/
|
*/
|
||||||
|
@ -334,7 +352,7 @@ public final class LayoutUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show window over ownWindow with a mask, use when ownWindow isn't implement {@link ISupportMask}
|
* Show window over ownWindow with a mask, use when ownWindow doesn't implement {@link ISupportMask}
|
||||||
* @param window
|
* @param window
|
||||||
* @param ownWindow
|
* @param ownWindow
|
||||||
* @param mask if mask = null, make new and return it
|
* @param mask if mask = null, make new and return it
|
||||||
|
@ -353,11 +371,11 @@ public final class LayoutUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find parent control of child control, parent must implement {@link ISupportMask}
|
* find parent of child component, parent must implement {@link ISupportMask}
|
||||||
* if parentClass != null, parent class must extends parentClass
|
* if parentClass != null, parent class must extends parentClass
|
||||||
* @param child
|
* @param child
|
||||||
* @param parentClass
|
* @param parentClass
|
||||||
* @return
|
* @return {@link ISupportMask}
|
||||||
*/
|
*/
|
||||||
public static ISupportMask findMaskParent (Component child, Class<?> parentClass){
|
public static ISupportMask findMaskParent (Component child, Class<?> parentClass){
|
||||||
Component parent = child;
|
Component parent = child;
|
||||||
|
@ -429,6 +447,11 @@ public final class LayoutUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expand number of grid column to min (for e.g, to min of 2 column)
|
||||||
|
* @param grid
|
||||||
|
* @param min
|
||||||
|
*/
|
||||||
public static void expandTo(Grid grid, int min) {
|
public static void expandTo(Grid grid, int min) {
|
||||||
expandTo(grid, min, false);
|
expandTo(grid, min, false);
|
||||||
}
|
}
|
||||||
|
@ -488,6 +511,7 @@ public final class LayoutUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Event listener to add/remove slide from target component's sclass property **/
|
||||||
private static final EventListener<OpenEvent> addSlideEventListener = (OpenEvent evt) -> {
|
private static final EventListener<OpenEvent> addSlideEventListener = (OpenEvent evt) -> {
|
||||||
if (evt.isOpen())
|
if (evt.isOpen())
|
||||||
LayoutUtils.removeSclass("slide", (HtmlBasedComponent) evt.getTarget());
|
LayoutUtils.removeSclass("slide", (HtmlBasedComponent) evt.getTarget());
|
||||||
|
@ -504,7 +528,7 @@ public final class LayoutUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find popup ancestor of comp
|
* find first popup ancestor of comp
|
||||||
* @param comp
|
* @param comp
|
||||||
* @return {@link Popup} if comp or one of its ancestor is Popup
|
* @return {@link Popup} if comp or one of its ancestor is Popup
|
||||||
*/
|
*/
|
||||||
|
@ -519,7 +543,7 @@ public final class LayoutUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* call popup.detach when it is close
|
* Auto call popup.detach when popup is close
|
||||||
* @param popup
|
* @param popup
|
||||||
*/
|
*/
|
||||||
public static void autoDetachOnClose(Popup popup) {
|
public static void autoDetachOnClose(Popup popup) {
|
||||||
|
@ -531,7 +555,7 @@ public final class LayoutUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set target same width as ref using client side script
|
* Make target same width as ref using client side script
|
||||||
* @param target
|
* @param target
|
||||||
* @param ref
|
* @param ref
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,3 +1,25 @@
|
||||||
|
/***********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* 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., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
**********************************************************************/
|
||||||
package org.adempiere.webui;
|
package org.adempiere.webui;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -23,6 +45,9 @@ import org.compiere.util.DB;
|
||||||
import org.compiere.util.Ini;
|
import org.compiere.util.Ini;
|
||||||
import org.compiere.util.WebUtil;
|
import org.compiere.util.WebUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sync state of {@link HttpSession} and AD_Session
|
||||||
|
*/
|
||||||
public class LoggedSessionListener implements HttpSessionListener, ServletContextListener, ServerStateChangeListener{
|
public class LoggedSessionListener implements HttpSessionListener, ServletContextListener, ServerStateChangeListener{
|
||||||
private static Hashtable<String, HttpSession> AD_SessionList = new Hashtable<String, HttpSession>();
|
private static Hashtable<String, HttpSession> AD_SessionList = new Hashtable<String, HttpSession>();
|
||||||
private static final CLogger logger = CLogger.getCLogger(LoggedSessionListener.class);
|
private static final CLogger logger = CLogger.getCLogger(LoggedSessionListener.class);
|
||||||
|
@ -83,7 +108,7 @@ public class LoggedSessionListener implements HttpSessionListener, ServletContex
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DestroyAllSession() {
|
private void DestroyAllSession() {
|
||||||
if (!Adempiere.isStarted())
|
if (!Adempiere.isStarted())
|
||||||
{
|
{
|
||||||
Adempiere.addServerStateChangeListener(this);
|
Adempiere.addServerStateChangeListener(this);
|
||||||
|
@ -100,7 +125,7 @@ public class LoggedSessionListener implements HttpSessionListener, ServletContex
|
||||||
Adempiere.removeServerStateChangeListener(this);
|
Adempiere.removeServerStateChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeADSession(String sessionID, String serverName) {
|
private void removeADSession(String sessionID, String serverName) {
|
||||||
String sql = "UPDATE AD_Session SET Processed='Y' WHERE WebSession=? AND ServerName=? AND Processed='N'";
|
String sql = "UPDATE AD_Session SET Processed='Y' WHERE WebSession=? AND ServerName=? AND Processed='N'";
|
||||||
int no = DB.executeUpdate(sql, new Object[] {sessionID, serverName}, false, null);
|
int no = DB.executeUpdate(sql, new Object[] {sessionID, serverName}, false, null);
|
||||||
if (no < 0) {
|
if (no < 0) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ import org.zkoss.zk.ui.Component;
|
||||||
import org.zkoss.zk.ui.util.Clients;
|
import org.zkoss.zk.ui.util.Clients;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class for any component want implement {@link ISupportMask}
|
* Helper class for {@link ISupportMask} implementation
|
||||||
* Just make a instance of this class and let it do everything
|
* Just make a instance of this class and let it do everything
|
||||||
* @author hieplq
|
* @author hieplq
|
||||||
*
|
*
|
||||||
|
@ -39,7 +39,7 @@ public class ShowMaskWrapper implements ISupportMask {
|
||||||
private Mask maskObj;
|
private Mask maskObj;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* comp is component want implement this interface
|
* comp is component that implement ISupportMask
|
||||||
* @param comp
|
* @param comp
|
||||||
*/
|
*/
|
||||||
public ShowMaskWrapper (Component comp){
|
public ShowMaskWrapper (Component comp){
|
||||||
|
|
|
@ -20,8 +20,8 @@ import org.zkoss.zk.ui.ShadowElement;
|
||||||
import org.zkoss.zk.ui.util.UiLifeCycle;
|
import org.zkoss.zk.ui.util.UiLifeCycle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Utility class for selenium support
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class UiLifeCycleListener implements UiLifeCycle {
|
public class UiLifeCycleListener implements UiLifeCycle {
|
||||||
|
|
||||||
|
|
|
@ -68,12 +68,12 @@ import org.zkoss.zul.Vlayout;
|
||||||
public class ValuePreference extends Window implements EventListener<Event>
|
public class ValuePreference extends Window implements EventListener<Event>
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 7594680475358417813L;
|
private static final long serialVersionUID = 7594680475358417813L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory
|
* Show value preference dialog
|
||||||
* @param ref
|
* @param ref
|
||||||
* @param mField field
|
* @param mField field
|
||||||
* @param aValue value
|
* @param aValue value
|
||||||
|
@ -89,7 +89,7 @@ public class ValuePreference extends Window implements EventListener<Event>
|
||||||
} // start
|
} // start
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory
|
* Show value preference dialog
|
||||||
* @param ref
|
* @param ref
|
||||||
* @param mField field
|
* @param mField field
|
||||||
* @param aValue value
|
* @param aValue value
|
||||||
|
@ -127,7 +127,7 @@ public class ValuePreference extends Window implements EventListener<Event>
|
||||||
int AD_Org_ID = Env.getContextAsInt(Env.getCtx(), WindowNo, "AD_Org_ID");
|
int AD_Org_ID = Env.getContextAsInt(Env.getCtx(), WindowNo, "AD_Org_ID");
|
||||||
int AD_User_ID = Env.getAD_User_ID(Env.getCtx());
|
int AD_User_ID = Env.getAD_User_ID(Env.getCtx());
|
||||||
|
|
||||||
// Create Editor
|
// Create and show value preference dialog
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
ValuePreference vp = new ValuePreference (WindowNo,
|
ValuePreference vp = new ValuePreference (WindowNo,
|
||||||
AD_Client_ID, AD_Org_ID, AD_User_ID, AD_Window_ID, mField.getAD_Process_ID_Of_Panel(), mField.getAD_InfoWindow_ID_of_Panel(),
|
AD_Client_ID, AD_Org_ID, AD_User_ID, AD_Window_ID, mField.getAD_Process_ID_Of_Panel(), mField.getAD_InfoWindow_ID_of_Panel(),
|
||||||
|
@ -135,42 +135,8 @@ public class ValuePreference extends Window implements EventListener<Event>
|
||||||
displayType, AD_Reference_ID, ref);
|
displayType, AD_Reference_ID, ref);
|
||||||
} // create
|
} // create
|
||||||
|
|
||||||
/**
|
/** The Name of the Dialog */
|
||||||
* Create the popup menu item to start the ValuePreference editor.
|
|
||||||
* <code>
|
|
||||||
* .. add method
|
|
||||||
* public void setField (MField mField)
|
|
||||||
* {
|
|
||||||
* m_mField = mField;
|
|
||||||
* if (m_mField != null)
|
|
||||||
* ValuePreference.addMenu (this, m_popupMenu);
|
|
||||||
* } // setField
|
|
||||||
*
|
|
||||||
* .. in actionPerformed add ..
|
|
||||||
* if (e.getActionCommand().equals(ValuePreference.NAME))
|
|
||||||
* {
|
|
||||||
* ValuePreference.start (m_mField, getValue(), DisplayValue);
|
|
||||||
* return;
|
|
||||||
* }
|
|
||||||
* </code>
|
|
||||||
* @param l listener
|
|
||||||
* @param popupMenu menu
|
|
||||||
* @return JMenuItem
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
public static CMenuItem addMenu (ActionListener l, JPopupMenu popupMenu)
|
|
||||||
{
|
|
||||||
CMenuItem mi = new CMenuItem (Msg.getMsg(Env.getCtx(), NAME), s_icon);
|
|
||||||
mi.setActionCommand(NAME);
|
|
||||||
mi.addActionListener(l);
|
|
||||||
popupMenu.add(mi);
|
|
||||||
return mi;
|
|
||||||
}*/ // addMenu
|
|
||||||
|
|
||||||
/** The Name of the Editor */
|
|
||||||
public static final String NAME = "ValuePreference";
|
public static final String NAME = "ValuePreference";
|
||||||
/** The Menu Icon */
|
|
||||||
//private static String ICON_URL = "images/VPreference16.png";
|
|
||||||
/** Logger */
|
/** Logger */
|
||||||
private static final CLogger log = CLogger.getCLogger(ValuePreference.class);
|
private static final CLogger log = CLogger.getCLogger(ValuePreference.class);
|
||||||
private AbstractADWindowContent adwindowContent;
|
private AbstractADWindowContent adwindowContent;
|
||||||
|
@ -189,7 +155,7 @@ public class ValuePreference extends Window implements EventListener<Event>
|
||||||
* @param DisplayValue value display
|
* @param DisplayValue value display
|
||||||
* @param displayType display type
|
* @param displayType display type
|
||||||
* @param AD_Reference_ID reference
|
* @param AD_Reference_ID reference
|
||||||
* @param ref
|
* @param ref
|
||||||
*/
|
*/
|
||||||
public ValuePreference (int WindowNo,
|
public ValuePreference (int WindowNo,
|
||||||
int AD_Client_ID, int AD_Org_ID, int AD_User_ID, int AD_Window_ID, int AD_Process_ID_Of_Panel, int AD_Infowindow_ID,
|
int AD_Client_ID, int AD_Org_ID, int AD_User_ID, int AD_Window_ID, int AD_Process_ID_Of_Panel, int AD_Infowindow_ID,
|
||||||
|
@ -439,7 +405,6 @@ public class ValuePreference extends Window implements EventListener<Event>
|
||||||
// ActionListener
|
// ActionListener
|
||||||
cbClient.setEnabled(false);
|
cbClient.setEnabled(false);
|
||||||
cbClient.setChecked(true);
|
cbClient.setChecked(true);
|
||||||
// cbClient.addActionListener(this);
|
|
||||||
|
|
||||||
// Can Change Org
|
// Can Change Org
|
||||||
if (MRole.PREFERENCETYPE_Client.equals(m_role.getPreferenceType()))
|
if (MRole.PREFERENCETYPE_Client.equals(m_role.getPreferenceType()))
|
||||||
|
@ -498,7 +463,7 @@ public class ValuePreference extends Window implements EventListener<Event>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
setExplanation();
|
setExplanation();
|
||||||
} // actionPerformed
|
}
|
||||||
|
|
||||||
private void onCancel() {
|
private void onCancel() {
|
||||||
this.detach();
|
this.detach();
|
||||||
|
@ -557,8 +522,6 @@ public class ValuePreference extends Window implements EventListener<Event>
|
||||||
*/
|
*/
|
||||||
public int delete()
|
public int delete()
|
||||||
{
|
{
|
||||||
log.info("");
|
|
||||||
|
|
||||||
StringBuilder sql = new StringBuilder ("DELETE FROM AD_Preference WHERE ");
|
StringBuilder sql = new StringBuilder ("DELETE FROM AD_Preference WHERE ");
|
||||||
sql.append("AD_Client_ID=").append(cbClient.isChecked() ? m_AD_Client_ID : 0);
|
sql.append("AD_Client_ID=").append(cbClient.isChecked() ? m_AD_Client_ID : 0);
|
||||||
sql.append(" AND AD_Org_ID=").append(cbOrg.isChecked() ? m_AD_Org_ID : 0);
|
sql.append(" AND AD_Org_ID=").append(cbOrg.isChecked() ? m_AD_Org_ID : 0);
|
||||||
|
@ -654,12 +617,10 @@ public class ValuePreference extends Window implements EventListener<Event>
|
||||||
} // getContextKey
|
} // getContextKey
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save to Disk
|
* Save to DB
|
||||||
*/
|
*/
|
||||||
public void insert()
|
public void insert()
|
||||||
{
|
{
|
||||||
log.info("");
|
|
||||||
|
|
||||||
// --- Delete first
|
// --- Delete first
|
||||||
int no = delete();
|
int no = delete();
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ public class WArchive implements EventListener<Event>
|
||||||
} // getZoomTargets
|
} // getZoomTargets
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listner
|
* Listener
|
||||||
* @param e event
|
* @param e event
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -151,6 +151,7 @@ public class WArchive implements EventListener<Event>
|
||||||
{
|
{
|
||||||
if (e.getTarget() instanceof Menuitem)
|
if (e.getTarget() instanceof Menuitem)
|
||||||
{
|
{
|
||||||
|
//open archive viewer
|
||||||
int AD_Form_ID = FORM_ARCHIVEVIEWER; // ArchiveViewer
|
int AD_Form_ID = FORM_ARCHIVEVIEWER; // ArchiveViewer
|
||||||
ADForm form = ADForm.openForm(AD_Form_ID);
|
ADForm form = ADForm.openForm(AD_Form_ID);
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ import org.zkoss.zul.West;
|
||||||
import org.zkoss.zul.Window;
|
import org.zkoss.zul.Window;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Manage login window for login and role selection
|
||||||
* @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a>
|
* @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a>
|
||||||
* @author Low Heng Sin
|
* @author Low Heng Sin
|
||||||
* @date Mar 3, 2007
|
* @date Mar 3, 2007
|
||||||
|
@ -42,17 +42,28 @@ import org.zkoss.zul.Window;
|
||||||
*/
|
*/
|
||||||
public class WLogin extends AbstractUIPart
|
public class WLogin extends AbstractUIPart
|
||||||
{
|
{
|
||||||
|
/** IWebClient instance ({@link AdempiereWebUI}) **/
|
||||||
private IWebClient app;
|
private IWebClient app;
|
||||||
|
/** Main layout **/
|
||||||
private Borderlayout layout;
|
private Borderlayout layout;
|
||||||
|
@Deprecated(forRemoval = true, since = "11")
|
||||||
private Window browserWarningWindow;
|
private Window browserWarningWindow;
|
||||||
|
/** embedded window for login and role selection **/
|
||||||
private LoginWindow loginWindow;
|
private LoginWindow loginWindow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param app
|
||||||
|
*/
|
||||||
public WLogin(IWebClient app)
|
public WLogin(IWebClient app)
|
||||||
{
|
{
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create UI from login.zul file. The main layout component ("layout") must be instance of {@link Borderlayout}.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
protected Component doCreatePart(Component parent)
|
protected Component doCreatePart(Component parent)
|
||||||
{
|
{
|
||||||
PageDefinition pageDefintion = Executions.getCurrent().getPageDefinition(ThemeManager.getThemeResource("zul/login/login.zul"));
|
PageDefinition pageDefintion = Executions.getCurrent().getPageDefinition(ThemeManager.getThemeResource("zul/login/login.zul"));
|
||||||
|
@ -107,6 +118,9 @@ public class WLogin extends AbstractUIPart
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* detach/dispose window content
|
||||||
|
*/
|
||||||
public void detach() {
|
public void detach() {
|
||||||
layout.detach();
|
layout.detach();
|
||||||
layout = null;
|
layout = null;
|
||||||
|
@ -114,12 +128,15 @@ public class WLogin extends AbstractUIPart
|
||||||
browserWarningWindow.detach();
|
browserWarningWindow.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link Component}
|
||||||
|
*/
|
||||||
public Component getComponent() {
|
public Component getComponent() {
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show change role window
|
* Show change role panel in {@link #loginWindow}
|
||||||
* @param locale
|
* @param locale
|
||||||
* @param properties env context
|
* @param properties env context
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -36,8 +36,8 @@ import org.zkoss.zul.Menupopup;
|
||||||
import org.zkoss.zul.Popup;
|
import org.zkoss.zul.Popup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request Button Action.
|
* Handle Request Button Action.
|
||||||
* Popup Menu
|
* Show Popup Menu.
|
||||||
*
|
*
|
||||||
* @author Jorg Janke
|
* @author Jorg Janke
|
||||||
* @version $Id: ARequest.java,v 1.2 2006/07/30 00:51:27 jjanke Exp $
|
* @version $Id: ARequest.java,v 1.2 2006/07/30 00:51:27 jjanke Exp $
|
||||||
|
@ -133,6 +133,7 @@ public class WRequest implements EventListener<Event>
|
||||||
{
|
{
|
||||||
if (e.getTarget() instanceof Menuitem)
|
if (e.getTarget() instanceof Menuitem)
|
||||||
{
|
{
|
||||||
|
//open request window
|
||||||
MQuery query = null;
|
MQuery query = null;
|
||||||
if (e.getTarget() == m_active)
|
if (e.getTarget() == m_active)
|
||||||
{
|
{
|
||||||
|
@ -171,6 +172,11 @@ public class WRequest implements EventListener<Event>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set initial values for new request record
|
||||||
|
* @param e
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
private void onNew(Event e, ADWindow frame) {
|
private void onNew(Event e, ADWindow frame) {
|
||||||
// New - set Table/Record
|
// New - set Table/Record
|
||||||
if (e.getTarget() == m_new)
|
if (e.getTarget() == m_new)
|
||||||
|
|
|
@ -37,11 +37,10 @@ import org.zkoss.zul.Menupopup;
|
||||||
import org.zkoss.zul.Popup;
|
import org.zkoss.zul.Popup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Application Zoom Across Launcher.
|
* Handle Zoom Across button action.
|
||||||
* Called from APanel; Queries available Zoom Targets for Table.
|
|
||||||
*
|
*
|
||||||
* @author Jorg Janke
|
* @author Jorg Janke
|
||||||
* @version $Id: AZoomAcross.java,v 1.2 2006/07/30 00:51:27 jjanke Exp $
|
* @version $Id: AZoomAcross.java,v 1.2 2006/07/30 00:51:27 jjanke Exp $
|
||||||
*
|
*
|
||||||
* @author Teo Sarca, SC ARHIPAC SERVICE SRL - FR [ 1762465 ]
|
* @author Teo Sarca, SC ARHIPAC SERVICE SRL - FR [ 1762465 ]
|
||||||
*
|
*
|
||||||
|
@ -64,6 +63,12 @@ public class WZoomAcross
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* show zoom across popup menu
|
||||||
|
* @param invoker
|
||||||
|
* @param po
|
||||||
|
* @param windowID
|
||||||
|
*/
|
||||||
public WZoomAcross(Component invoker, PO po, final int windowID) {
|
public WZoomAcross(Component invoker, PO po, final int windowID) {
|
||||||
|
|
||||||
if (log.isLoggable(Level.CONFIG)) log.config("PO=" + po+", WindowID="+windowID);
|
if (log.isLoggable(Level.CONFIG)) log.config("PO=" + po+", WindowID="+windowID);
|
||||||
|
@ -104,12 +109,18 @@ public class WZoomAcross
|
||||||
m_popup.open(invoker, "after_start");
|
m_popup.open(invoker, "after_start");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Menupopup m_popup = new Menupopup(); //"ZoomMenu"
|
/** popup menu for zoom across targets **/
|
||||||
|
private Menupopup m_popup = new Menupopup();
|
||||||
|
|
||||||
private static final CLogger log = CLogger.getCLogger(WZoomAcross.class);
|
private static final CLogger log = CLogger.getCLogger(WZoomAcross.class);
|
||||||
|
|
||||||
private final List<ZoomInfoFactory.ZoomInfo> zoomInfos = new ArrayList<ZoomInfoFactory.ZoomInfo>();
|
private final List<ZoomInfoFactory.ZoomInfo> zoomInfos = new ArrayList<ZoomInfoFactory.ZoomInfo>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find zoom across targets
|
||||||
|
* @param po
|
||||||
|
* @param windowID
|
||||||
|
*/
|
||||||
private void mkZoomTargets(final PO po, final int windowID) {
|
private void mkZoomTargets(final PO po, final int windowID) {
|
||||||
|
|
||||||
for (final ZoomInfoFactory.ZoomInfo zoomInfo : ZoomInfoFactory.retrieveZoomInfos(po,
|
for (final ZoomInfoFactory.ZoomInfo zoomInfo : ZoomInfoFactory.retrieveZoomInfos(po,
|
||||||
|
@ -125,18 +136,18 @@ public class WZoomAcross
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Launch Zoom
|
* Zoom to destination window
|
||||||
* @param pp KeyPair
|
* @param zoomInfo
|
||||||
*/
|
*/
|
||||||
private void launchZoom (final ZoomInfoFactory.ZoomInfo zoomInfo)
|
private void launchZoom (final ZoomInfoFactory.ZoomInfo zoomInfo)
|
||||||
{
|
{
|
||||||
final int AD_Window_ID = zoomInfo.windowId;
|
final int AD_Window_ID = zoomInfo.windowId;
|
||||||
final MQuery query = zoomInfo.query;
|
final MQuery query = zoomInfo.query;
|
||||||
|
|
||||||
log.info("AD_Window_ID=" + AD_Window_ID
|
if (log.isLoggable(Level.INFO))
|
||||||
+ " - " + query);
|
log.info("AD_Window_ID=" + AD_Window_ID + " - " + query);
|
||||||
|
|
||||||
AEnv.zoom(AD_Window_ID, query);
|
AEnv.zoom(AD_Window_ID, query);
|
||||||
} // launchZoom
|
} // launchZoom
|
||||||
|
|
||||||
} // AZoom
|
}
|
||||||
|
|
|
@ -18,8 +18,9 @@ import org.osgi.framework.BundleActivator;
|
||||||
import org.osgi.framework.BundleContext;
|
import org.osgi.framework.BundleContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* {@link BundleActivator} for web UI
|
||||||
|
* Start {@link WindowValidatorManager}
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class WebUIActivator implements BundleActivator {
|
public class WebUIActivator implements BundleActivator {
|
||||||
|
|
||||||
|
@ -44,6 +45,10 @@ public class WebUIActivator implements BundleActivator {
|
||||||
WindowValidatorManager.getInstance().stop(context);
|
WindowValidatorManager.getInstance().stop(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return {@link BundleContext}
|
||||||
|
*/
|
||||||
public static BundleContext getBundleContext() {
|
public static BundleContext getBundleContext() {
|
||||||
return bundleContext;
|
return bundleContext;
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,11 +104,10 @@ import org.zkoss.zul.Space;
|
||||||
* @author Elaine Tan
|
* @author Elaine Tan
|
||||||
* @author Low Heng Sin
|
* @author Low Heng Sin
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class WAcctViewer extends Window implements EventListener<Event>
|
public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 3440375640756094077L;
|
private static final long serialVersionUID = 3440375640756094077L;
|
||||||
|
|
||||||
|
@ -207,7 +206,6 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
/**
|
/**
|
||||||
* Default constructor
|
* Default constructor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public WAcctViewer()
|
public WAcctViewer()
|
||||||
{
|
{
|
||||||
this (0, 0, 0);
|
this (0, 0, 0);
|
||||||
|
@ -220,14 +218,13 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
* @param AD_Table_ID Table
|
* @param AD_Table_ID Table
|
||||||
* @param Record_ID Record
|
* @param Record_ID Record
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public WAcctViewer(int AD_Client_ID, int AD_Table_ID, int Record_ID)
|
public WAcctViewer(int AD_Client_ID, int AD_Table_ID, int Record_ID)
|
||||||
{
|
{
|
||||||
super ();
|
super ();
|
||||||
|
|
||||||
log.info("AD_Table_ID=" + AD_Table_ID + ", Record_ID=" + Record_ID);
|
if (log.isLoggable(Level.INFO))
|
||||||
|
log.info("AD_Table_ID=" + AD_Table_ID + ", Record_ID=" + Record_ID);
|
||||||
|
|
||||||
//setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
|
||||||
m_windowNo = SessionManager.getAppDesktop().registerWindow(this);
|
m_windowNo = SessionManager.getAppDesktop().registerWindow(this);
|
||||||
m_data = new WAcctViewerData (Env.getCtx(), m_windowNo, AD_Client_ID, AD_Table_ID);
|
m_data = new WAcctViewerData (Env.getCtx(), m_windowNo, AD_Client_ID, AD_Table_ID);
|
||||||
|
|
||||||
|
@ -242,9 +239,8 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
log.log(Level.SEVERE, "", e);
|
log.log(Level.SEVERE, "", e);
|
||||||
//dispose();
|
|
||||||
}
|
}
|
||||||
} // AcctViewer
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static Init.
|
* Static Init.
|
||||||
|
@ -257,7 +253,6 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
* </pre>
|
* </pre>
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private void init() throws Exception
|
private void init() throws Exception
|
||||||
{
|
{
|
||||||
// Selection Panel
|
// Selection Panel
|
||||||
|
@ -450,8 +445,6 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
ZKUpdateUtil.setHflex(sortBy4, "1");
|
ZKUpdateUtil.setHflex(sortBy4, "1");
|
||||||
row.appendChild(group4);
|
row.appendChild(group4);
|
||||||
|
|
||||||
//"images/InfoAccount16.png"
|
|
||||||
|
|
||||||
Groupbox groupDisplay = new Groupbox();
|
Groupbox groupDisplay = new Groupbox();
|
||||||
Caption capDisplay = new Caption(Msg.getMsg(Env.getCtx(), "Display"));
|
Caption capDisplay = new Caption(Msg.getMsg(Env.getCtx(), "Display"));
|
||||||
groupDisplay.appendChild(capDisplay);
|
groupDisplay.appendChild(capDisplay);
|
||||||
|
@ -549,11 +542,8 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
resultPanel.appendChild(resultCenter);
|
resultPanel.appendChild(resultCenter);
|
||||||
ZKUpdateUtil.setHflex(table, "1");
|
ZKUpdateUtil.setHflex(table, "1");
|
||||||
ZKUpdateUtil.setVflex(table, true);
|
ZKUpdateUtil.setVflex(table, true);
|
||||||
//ZKUpdateUtil.setHeight(table, "99%");
|
|
||||||
//table.setStyle("position: absolute;");
|
|
||||||
resultCenter.appendChild(table);
|
resultCenter.appendChild(table);
|
||||||
ZKUpdateUtil.setHflex(table, "1");
|
ZKUpdateUtil.setHflex(table, "1");
|
||||||
//ZKUpdateUtil.setVflex(table, "1");
|
|
||||||
table.addEventListener(Events.ON_DOUBLE_CLICK, this);
|
table.addEventListener(Events.ON_DOUBLE_CLICK, this);
|
||||||
if (ClientInfo.isMobile())
|
if (ClientInfo.isMobile())
|
||||||
table.setSizedByContent(true);
|
table.setSizedByContent(true);
|
||||||
|
@ -599,7 +589,7 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
layout.setParent(this);
|
layout.setParent(this);
|
||||||
ZKUpdateUtil.setHeight(layout, "100%");
|
ZKUpdateUtil.setHeight(layout, "100%");
|
||||||
ZKUpdateUtil.setWidth(layout, "100%");
|
ZKUpdateUtil.setWidth(layout, "100%");
|
||||||
layout.setStyle("background-color: transparent; margin: 0; position: absolute; padding: 0;");
|
layout.setStyle("background-color: transparent; margin: 0; position: relative; padding: 0;");
|
||||||
|
|
||||||
Center center = new Center();
|
Center center = new Center();
|
||||||
center.setParent(layout);
|
center.setParent(layout);
|
||||||
|
@ -618,7 +608,7 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
|
|
||||||
this.setTitle(Msg.getMsg(Env.getCtx(), TITLE));
|
this.setTitle(Msg.getMsg(Env.getCtx(), TITLE));
|
||||||
this.setClosable(true);
|
this.setClosable(true);
|
||||||
this.setStyle("position: absolute; width: 100%; height: 100%;");
|
this.setStyle("position: relative; width: 100%; height: 100%;");
|
||||||
this.setSizable(true);
|
this.setSizable(true);
|
||||||
this.setMaximizable(true);
|
this.setMaximizable(true);
|
||||||
}
|
}
|
||||||
|
@ -629,7 +619,6 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
* @param AD_Table_ID table
|
* @param AD_Table_ID table
|
||||||
* @param Record_ID record
|
* @param Record_ID record
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private void dynInit (int AD_Table_ID, int Record_ID)
|
private void dynInit (int AD_Table_ID, int Record_ID)
|
||||||
{
|
{
|
||||||
m_data.validateAcctSchemas(Record_ID);
|
m_data.validateAcctSchemas(Record_ID);
|
||||||
|
@ -702,6 +691,12 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
stateChanged();
|
stateChanged();
|
||||||
} // dynInit
|
} // dynInit
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set selected table and record id
|
||||||
|
* @param AD_Table_ID
|
||||||
|
* @param Record_ID
|
||||||
|
* @return true if AD_Table_ID is found, false otherwise
|
||||||
|
*/
|
||||||
private boolean setSelectedTable(int AD_Table_ID, int Record_ID)
|
private boolean setSelectedTable(int AD_Table_ID, int Record_ID)
|
||||||
{
|
{
|
||||||
int cnt = selTable.getItemCount();
|
int cnt = selTable.getItemCount();
|
||||||
|
@ -727,9 +722,8 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispose
|
* Dispose window
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void dispose()
|
public void dispose()
|
||||||
{
|
{
|
||||||
m_data.dispose();
|
m_data.dispose();
|
||||||
|
@ -738,11 +732,10 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
} // dispose;
|
} // dispose;
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* Tab Changed
|
* After Tab Selection Changed
|
||||||
*/
|
*/
|
||||||
public void stateChanged()
|
public void stateChanged()
|
||||||
{
|
{
|
||||||
// log.info( "AcctViewer.stateChanged");
|
|
||||||
boolean visible = m_data.documentQuery && tabResult.isSelected();
|
boolean visible = m_data.documentQuery && tabResult.isSelected();
|
||||||
|
|
||||||
bRePost.setVisible(visible);
|
bRePost.setVisible(visible);
|
||||||
|
@ -756,11 +749,8 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
* Event Performed (Event Listener)
|
* Event Performed (Event Listener)
|
||||||
* @param e Event
|
* @param e Event
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void onEvent(Event e) throws Exception
|
public void onEvent(Event e) throws Exception
|
||||||
{
|
{
|
||||||
// log.info(e.getActionCommand());
|
|
||||||
|
|
||||||
Object source = e.getTarget();
|
Object source = e.getTarget();
|
||||||
|
|
||||||
if (source == tabResult)
|
if (source == tabResult)
|
||||||
|
@ -802,6 +792,10 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
}
|
}
|
||||||
} // onEvent
|
} // onEvent
|
||||||
|
|
||||||
|
/**
|
||||||
|
* export to excel
|
||||||
|
* show excel viewer if available
|
||||||
|
*/
|
||||||
private void actionExport() {
|
private void actionExport() {
|
||||||
if (m_rmodel != null && m_rmodel.getRowCount() > 0) {
|
if (m_rmodel != null && m_rmodel.getRowCount() > 0) {
|
||||||
RModelExcelExporter exporter = new RModelExcelExporter(m_rmodel);
|
RModelExcelExporter exporter = new RModelExcelExporter(m_rmodel);
|
||||||
|
@ -835,9 +829,8 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New Acct Schema
|
* Handle Acct Schema selection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private void actionAcctSchema()
|
private void actionAcctSchema()
|
||||||
{
|
{
|
||||||
Listitem listitem = selAcctSchema.getSelectedItem();
|
Listitem listitem = selAcctSchema.getSelectedItem();
|
||||||
|
@ -853,7 +846,8 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
m_data.C_AcctSchema_ID = kp.getKey();
|
m_data.C_AcctSchema_ID = kp.getKey();
|
||||||
m_data.ASchema = MAcctSchema.get(Env.getCtx(), m_data.C_AcctSchema_ID);
|
m_data.ASchema = MAcctSchema.get(Env.getCtx(), m_data.C_AcctSchema_ID);
|
||||||
|
|
||||||
log.info(m_data.ASchema.toString());
|
if (log.isLoggable(Level.INFO))
|
||||||
|
log.info(m_data.ASchema.toString());
|
||||||
|
|
||||||
// Sort Options
|
// Sort Options
|
||||||
|
|
||||||
|
@ -916,7 +910,6 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
* Add to Sort
|
* Add to Sort
|
||||||
* @param vn name pair
|
* @param vn name pair
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private void sortAddItem(ValueNamePair vn)
|
private void sortAddItem(ValueNamePair vn)
|
||||||
{
|
{
|
||||||
sortBy1.appendItem(vn.getName(), vn);
|
sortBy1.appendItem(vn.getName(), vn);
|
||||||
|
@ -926,9 +919,9 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
} // sortAddItem
|
} // sortAddItem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query
|
* Query.
|
||||||
|
* Delegate to {@link WAcctViewerData#query()}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private void actionQuery()
|
private void actionQuery()
|
||||||
{
|
{
|
||||||
// Parameter Info
|
// Parameter Info
|
||||||
|
@ -1171,7 +1164,6 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
/**
|
/**
|
||||||
* Document selection
|
* Document selection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private void actionDocument()
|
private void actionDocument()
|
||||||
{
|
{
|
||||||
boolean doc = selDocument.isChecked();
|
boolean doc = selDocument.isChecked();
|
||||||
|
@ -1193,9 +1185,8 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
} // actionDocument
|
} // actionDocument
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save Table selection (reset Record selection)
|
* Handle Table selection (reset Record selection)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private void actionTable()
|
private void actionTable()
|
||||||
{
|
{
|
||||||
Listitem listitem = selTable.getSelectedItem();
|
Listitem listitem = selTable.getSelectedItem();
|
||||||
|
@ -1217,17 +1208,15 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
} // actionTable
|
} // actionTable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action Button
|
* Handle Info Button action
|
||||||
|
* Show info window
|
||||||
*
|
*
|
||||||
* @param button pressed button
|
* @param button pressed button
|
||||||
* @return ID
|
* @throws Exception
|
||||||
* @throws Exception
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private void actionButton(final Button button) throws Exception
|
private void actionButton(final Button button) throws Exception
|
||||||
{
|
{
|
||||||
final String keyColumn = button.getName();
|
final String keyColumn = button.getName();
|
||||||
log.info(keyColumn);
|
|
||||||
String whereClause = "(IsSummary='N' OR IsSummary IS NULL)";
|
String whereClause = "(IsSummary='N' OR IsSummary IS NULL)";
|
||||||
String lookupColumn = keyColumn;
|
String lookupColumn = keyColumn;
|
||||||
|
|
||||||
|
@ -1321,14 +1310,12 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
AEnv.showWindow(info);
|
AEnv.showWindow(info);
|
||||||
|
|
||||||
} // actionButton
|
} // actionButton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RePost Record
|
* RePost Record
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private void actionRePost()
|
private void actionRePost()
|
||||||
{
|
{
|
||||||
if (m_data.documentQuery
|
if (m_data.documentQuery
|
||||||
|
@ -1362,7 +1349,9 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
}
|
}
|
||||||
} // actionRePost
|
} // actionRePost
|
||||||
|
|
||||||
// Elaine 2009/07/29
|
/**
|
||||||
|
* zoom to table id + record id
|
||||||
|
*/
|
||||||
private void actionZoom()
|
private void actionZoom()
|
||||||
{
|
{
|
||||||
int selected = table.getSelectedIndex();
|
int selected = table.getSelectedIndex();
|
||||||
|
@ -1380,8 +1369,10 @@ public class WAcctViewer extends Window implements EventListener<Event>
|
||||||
AEnv.zoom(AD_Table_ID, Record_ID);
|
AEnv.zoom(AD_Table_ID, Record_ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
|
||||||
|
/**
|
||||||
|
* zoom to fact acct window (double click action)
|
||||||
|
*/
|
||||||
private void actionZoomFactAcct() {
|
private void actionZoomFactAcct() {
|
||||||
int selected = table.getSelectedIndex();
|
int selected = table.getSelectedIndex();
|
||||||
if(selected == -1) return;
|
if(selected == -1) return;
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.compiere.model.MFactAcct;
|
||||||
import org.compiere.model.MJournal;
|
import org.compiere.model.MJournal;
|
||||||
import org.compiere.model.MLookupFactory;
|
import org.compiere.model.MLookupFactory;
|
||||||
import org.compiere.model.MRefList;
|
import org.compiere.model.MRefList;
|
||||||
|
import org.compiere.model.SystemIDs;
|
||||||
import org.compiere.report.core.RColumn;
|
import org.compiere.report.core.RColumn;
|
||||||
import org.compiere.report.core.RModel;
|
import org.compiere.report.core.RModel;
|
||||||
import org.compiere.util.CLogger;
|
import org.compiere.util.CLogger;
|
||||||
|
@ -53,8 +54,7 @@ import org.compiere.util.Msg;
|
||||||
import org.compiere.util.ValueNamePair;
|
import org.compiere.util.ValueNamePair;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Account Viewer State - maintains State information for the Account Viewer
|
* State and data access helper for {@link WAcctViewer}
|
||||||
* Based on class AcctViewerData
|
|
||||||
*
|
*
|
||||||
* @author Niraj Sohun
|
* @author Niraj Sohun
|
||||||
* July 27, 2007
|
* July 27, 2007
|
||||||
|
@ -68,68 +68,70 @@ public class WAcctViewerData
|
||||||
/** Client */
|
/** Client */
|
||||||
public int AD_Client_ID;
|
public int AD_Client_ID;
|
||||||
|
|
||||||
/** All Acct Schema */
|
/** All Accounting Schemas for client */
|
||||||
public MAcctSchema[] ASchemas = null;
|
public MAcctSchema[] ASchemas = null;
|
||||||
|
|
||||||
/** This Acct Schema */
|
/** Selected Accounting Schema */
|
||||||
public MAcctSchema ASchema = null;
|
public MAcctSchema ASchema = null;
|
||||||
|
|
||||||
// Selection Info
|
// Selection Info
|
||||||
|
|
||||||
/** Document Query */
|
/** Document Query - query with {@link #AD_Table_ID} and {@link #Record_ID} */
|
||||||
public boolean documentQuery = false;
|
public boolean documentQuery = false;
|
||||||
|
|
||||||
/** Acct Schema */
|
/** Selected Accounting Schema ID */
|
||||||
public int C_AcctSchema_ID = 0;
|
public int C_AcctSchema_ID = 0;
|
||||||
|
|
||||||
/** Posting Type */
|
/** Selected Posting Type */
|
||||||
public String PostingType = "";
|
public String PostingType = "";
|
||||||
|
|
||||||
/** Organization */
|
/** Selected Organization ID */
|
||||||
public int AD_Org_ID = 0;
|
public int AD_Org_ID = 0;
|
||||||
|
|
||||||
/** Date From */
|
/** Date From, for DateAcct filter */
|
||||||
public Timestamp DateFrom = null;
|
public Timestamp DateFrom = null;
|
||||||
|
|
||||||
/** Date To */
|
/** Date To, for DateAcct filter */
|
||||||
public Timestamp DateTo = null;
|
public Timestamp DateTo = null;
|
||||||
|
|
||||||
// Document Table Selection Info
|
// Document Table Selection Info
|
||||||
|
|
||||||
/** Table ID */
|
/** Selected Table ID for {@link #documentQuery} */
|
||||||
public int AD_Table_ID;
|
public int AD_Table_ID;
|
||||||
|
|
||||||
/** Record */
|
/** Selected Record ID for {@link #documentQuery} */
|
||||||
public int Record_ID;
|
public int Record_ID;
|
||||||
|
|
||||||
/** Containing Column and Query */
|
/** ColumnName:Filter */
|
||||||
public HashMap<String,String> whereInfo = new HashMap<String,String>();
|
public HashMap<String,String> whereInfo = new HashMap<String,String>();
|
||||||
|
|
||||||
/** Containing TableName and AD_Table_ID */
|
/** TableName:AD_Table_ID */
|
||||||
public HashMap<String,Integer> tableInfo = new HashMap<String,Integer>();
|
public HashMap<String,Integer> tableInfo = new HashMap<String,Integer>();
|
||||||
|
|
||||||
// Display Info
|
// Display Info
|
||||||
|
|
||||||
/** Display Qty */
|
/** Display Qty Columns */
|
||||||
boolean displayQty = false;
|
protected boolean displayQty = false;
|
||||||
|
|
||||||
/** Display Source Surrency */
|
/** Display Source Amount Columns */
|
||||||
boolean displaySourceAmt = false;
|
protected boolean displaySourceAmt = false;
|
||||||
|
|
||||||
/** Display Document info */
|
/** Display Document info */
|
||||||
boolean displayDocumentInfo = false;
|
protected boolean displayDocumentInfo = false;
|
||||||
|
|
||||||
String sortBy1 = "";
|
//order by
|
||||||
String sortBy2 = "";
|
protected String sortBy1 = "";
|
||||||
String sortBy3 = "";
|
protected String sortBy2 = "";
|
||||||
String sortBy4 = "";
|
protected String sortBy3 = "";
|
||||||
|
protected String sortBy4 = "";
|
||||||
|
|
||||||
boolean group1 = false;
|
//group by
|
||||||
boolean group2 = false;
|
protected boolean group1 = false;
|
||||||
boolean group3 = false;
|
protected boolean group2 = false;
|
||||||
boolean group4 = false;
|
protected boolean group3 = false;
|
||||||
|
protected boolean group4 = false;
|
||||||
|
|
||||||
/** Leasing Columns */
|
/** Leading Columns. Number of columns shown before Accounted and Source Amount Columns. */
|
||||||
private int m_leadingColumns = 0;
|
private int m_leadingColumns = 0;
|
||||||
|
|
||||||
/** UserElement1 Reference */
|
/** UserElement1 Reference */
|
||||||
|
@ -148,7 +150,6 @@ public class WAcctViewerData
|
||||||
* @param ad_Client_ID client
|
* @param ad_Client_ID client
|
||||||
* @param ad_Table_ID table
|
* @param ad_Table_ID table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public WAcctViewerData (Properties ctx, int windowNo, int ad_Client_ID, int ad_Table_ID)
|
public WAcctViewerData (Properties ctx, int windowNo, int ad_Client_ID, int ad_Table_ID)
|
||||||
{
|
{
|
||||||
WindowNo = windowNo;
|
WindowNo = windowNo;
|
||||||
|
@ -168,8 +169,7 @@ public class WAcctViewerData
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispose
|
* Dispose
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void dispose()
|
public void dispose()
|
||||||
{
|
{
|
||||||
ASchemas = null;
|
ASchemas = null;
|
||||||
|
@ -182,8 +182,8 @@ public class WAcctViewerData
|
||||||
} // dispose
|
} // dispose
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GL Journal only posts in one Accounting Schema
|
* GL Journal only posts in one Accounting Schema.
|
||||||
* if the record is a GL Journal, remove the others from the array
|
* If the record is a GL Journal, remove the other accounting schema from {@link #ASchemas}
|
||||||
* @param Record_ID
|
* @param Record_ID
|
||||||
*/
|
*/
|
||||||
protected void validateAcctSchemas(int Record_ID)
|
protected void validateAcctSchemas(int Record_ID)
|
||||||
|
@ -191,7 +191,7 @@ public class WAcctViewerData
|
||||||
if (Record_ID > 0 && AD_Table_ID == MJournal.Table_ID) {
|
if (Record_ID > 0 && AD_Table_ID == MJournal.Table_ID) {
|
||||||
MJournal journal = new MJournal(Env.getCtx(), Record_ID, null);
|
MJournal journal = new MJournal(Env.getCtx(), Record_ID, null);
|
||||||
|
|
||||||
if (journal != null) {
|
if (journal.getGL_Journal_ID() == Record_ID) {
|
||||||
ASchemas = new MAcctSchema[1];
|
ASchemas = new MAcctSchema[1];
|
||||||
ASchemas[0] = MAcctSchema.get(Env.getCtx(), journal.getC_AcctSchema_ID());
|
ASchemas[0] = MAcctSchema.get(Env.getCtx(), journal.getC_AcctSchema_ID());
|
||||||
ASchema = ASchemas[0];
|
ASchema = ASchemas[0];
|
||||||
|
@ -199,11 +199,10 @@ public class WAcctViewerData
|
||||||
}
|
}
|
||||||
} // validateAcctSchemas
|
} // validateAcctSchemas
|
||||||
|
|
||||||
/**************************************************************************
|
/**
|
||||||
* Fill Accounting Schema
|
* Fill Accounting Schema
|
||||||
* @param cb Listbox to be filled
|
* @param cb Listbox to be filled
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected void fillAcctSchema (Listbox cb)
|
protected void fillAcctSchema (Listbox cb)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < ASchemas.length; i++)
|
for (int i = 0; i < ASchemas.length; i++)
|
||||||
|
@ -214,10 +213,9 @@ public class WAcctViewerData
|
||||||
} // fillAcctSchema
|
} // fillAcctSchema
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill Posting Type
|
* Fill Posting Type from {@link SystemIDs#REFERENCE_POSTING_TYPE} list.
|
||||||
* @param cb Listox to be filled
|
* @param cb Listbox to be filled
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected void fillPostingType (Listbox cb)
|
protected void fillPostingType (Listbox cb)
|
||||||
{
|
{
|
||||||
int AD_Reference_ID = REFERENCE_POSTING_TYPE;
|
int AD_Reference_ID = REFERENCE_POSTING_TYPE;
|
||||||
|
@ -230,18 +228,15 @@ public class WAcctViewerData
|
||||||
} // fillPostingType
|
} // fillPostingType
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill Table with
|
* Fill Listbox with
|
||||||
* ValueNamePair (TableName, translatedKeyColumnName)
|
* ValueNamePair (TableName, translatedKeyColumnName)
|
||||||
* and tableInfo with (TableName, AD_Table_ID)
|
* and {@link #tableInfo} with (TableName, AD_Table_ID)
|
||||||
* and select the entry for AD_Table_ID
|
* and select the entry for AD_Table_ID
|
||||||
*
|
*
|
||||||
* @param cb Listbox to be filled
|
* @param cb Listbox to be filled
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected void fillTable (Listbox cb)
|
protected void fillTable (Listbox cb)
|
||||||
{
|
{
|
||||||
ValueNamePair select = null;
|
|
||||||
|
|
||||||
String sql = "SELECT AD_Table_ID, TableName FROM AD_Table t "
|
String sql = "SELECT AD_Table_ID, TableName FROM AD_Table t "
|
||||||
+ "WHERE EXISTS (SELECT * FROM AD_Column c"
|
+ "WHERE EXISTS (SELECT * FROM AD_Column c"
|
||||||
+ " WHERE t.AD_Table_ID=c.AD_Table_ID AND c.ColumnName='Posted')"
|
+ " WHERE t.AD_Table_ID=c.AD_Table_ID AND c.ColumnName='Posted')"
|
||||||
|
@ -261,10 +256,7 @@ public class WAcctViewerData
|
||||||
|
|
||||||
ValueNamePair pp = new ValueNamePair(tableName, name);
|
ValueNamePair pp = new ValueNamePair(tableName, name);
|
||||||
cb.appendItem(pp.getName(),pp);
|
cb.appendItem(pp.getName(),pp);
|
||||||
tableInfo.put (tableName, Integer.valueOf(id));
|
tableInfo.put (tableName, Integer.valueOf(id));
|
||||||
|
|
||||||
if (id == AD_Table_ID)
|
|
||||||
select = pp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SQLException e)
|
catch (SQLException e)
|
||||||
|
@ -276,18 +268,14 @@ public class WAcctViewerData
|
||||||
DB.close(rs, pstmt);
|
DB.close(rs, pstmt);
|
||||||
rs = null;
|
rs = null;
|
||||||
pstmt = null;
|
pstmt = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (select != null)
|
|
||||||
;//cb.setSelectedItem(select);
|
|
||||||
} // fillTable
|
} // fillTable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill Org
|
* Fill Org
|
||||||
*
|
*
|
||||||
* @param cb Listbox to be filled
|
* @param cb Listbox to be filled
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected void fillOrg (Listbox cb)
|
protected void fillOrg (Listbox cb)
|
||||||
{
|
{
|
||||||
KeyNamePair pp = new KeyNamePair(0, "");
|
KeyNamePair pp = new KeyNamePair(0, "");
|
||||||
|
@ -320,7 +308,7 @@ public class WAcctViewerData
|
||||||
} // fillOrg
|
} // fillOrg
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Button Text
|
* Get Info Button Text
|
||||||
*
|
*
|
||||||
* @param tableName table
|
* @param tableName table
|
||||||
* @param columnName column
|
* @param columnName column
|
||||||
|
@ -362,10 +350,9 @@ public class WAcctViewerData
|
||||||
return retValue;
|
return retValue;
|
||||||
} // getButtonText
|
} // getButtonText
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
/**
|
/**
|
||||||
* Create Query and submit
|
* Create query and execute
|
||||||
* @return Report Model
|
* @return {@link RModel} query result
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected RModel query()
|
protected RModel query()
|
||||||
|
@ -502,10 +489,9 @@ public class WAcctViewerData
|
||||||
} // query
|
} // query
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create Report Model (Columns)
|
* Create new Report Model (Setup Columns) instance
|
||||||
* @return Report Model
|
* @return {@link RModel}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private RModel getRModel()
|
private RModel getRModel()
|
||||||
{
|
{
|
||||||
Properties ctx = Env.getCtx();
|
Properties ctx = Env.getCtx();
|
||||||
|
@ -596,10 +582,9 @@ public class WAcctViewerData
|
||||||
} // createRModel
|
} // createRModel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the key columns in sequence
|
* Create the list of key/mandatory columns to display in viewer
|
||||||
* @return List of Key Columns
|
* @return List of Key Columns
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private ArrayList<String> createKeyColumns()
|
private ArrayList<String> createKeyColumns()
|
||||||
{
|
{
|
||||||
ArrayList<String> columns = new ArrayList<String>();
|
ArrayList<String> columns = new ArrayList<String>();
|
||||||
|
|
|
@ -25,7 +25,7 @@ import org.compiere.util.CCache;
|
||||||
import org.zkoss.image.AImage;
|
import org.zkoss.image.AImage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Static methods to get {@link IAction} osgi service instance.
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -58,7 +58,10 @@ public class Actions {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Image name: actionId+"24.png".
|
||||||
|
* Get image from current theme or plugin resource.
|
||||||
|
* For plugin resource, it will try the path /action/images/{theme}/{image name}, /action/images/default/{image name} and
|
||||||
|
* /action/images/{image name}
|
||||||
* @param actionId
|
* @param actionId
|
||||||
* @return {@link AImage}
|
* @return {@link AImage}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -22,7 +22,7 @@ import org.zkoss.zul.Toolbarbutton;
|
||||||
*/
|
*/
|
||||||
public interface IAction {
|
public interface IAction {
|
||||||
/**
|
/**
|
||||||
*
|
* execute action
|
||||||
* @param target
|
* @param target
|
||||||
*/
|
*/
|
||||||
public void execute(Object target);
|
public void execute(Object target);
|
||||||
|
|
|
@ -78,10 +78,13 @@ import org.zkoss.zul.event.ListDataEvent;
|
||||||
public class ADSortTab extends Panel implements IADTabpanel
|
public class ADSortTab extends Panel implements IADTabpanel
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 4302282658814599752L;
|
private static final long serialVersionUID = 4302282658814599752L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default constructor
|
||||||
|
*/
|
||||||
public ADSortTab()
|
public ADSortTab()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -133,7 +136,7 @@ public class ADSortTab extends Panel implements IADTabpanel
|
||||||
private Button bUp = ButtonFactory.createButton(null, ThemeManager.getThemeResource("images/MoveUp16.png"), null);
|
private Button bUp = ButtonFactory.createButton(null, ThemeManager.getThemeResource("images/MoveUp16.png"), null);
|
||||||
private Button bDown = ButtonFactory.createButton(null, ThemeManager.getThemeResource("images/MoveDown16.png"), null);
|
private Button bDown = ButtonFactory.createButton(null, ThemeManager.getThemeResource("images/MoveDown16.png"), null);
|
||||||
//
|
//
|
||||||
SimpleListModel noModel = new SimpleListModel() {
|
protected SimpleListModel noModel = new SimpleListModel() {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -153,12 +156,13 @@ public class ADSortTab extends Panel implements IADTabpanel
|
||||||
fireEvent(ListDataEvent.INTERVAL_ADDED, index, index);
|
fireEvent(ListDataEvent.INTERVAL_ADDED, index, index);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
SimpleListModel yesModel = new SimpleListModel();
|
protected SimpleListModel yesModel = new SimpleListModel();
|
||||||
Listbox noList = new Listbox();
|
protected Listbox noList = new Listbox();
|
||||||
Listbox yesList = new Listbox();
|
protected Listbox yesList = new Listbox();
|
||||||
|
|
||||||
private GridTab gridTab;
|
private GridTab gridTab;
|
||||||
private boolean uiCreated;
|
private boolean uiCreated;
|
||||||
|
/** true if tab have been activated **/
|
||||||
private boolean active = false;
|
private boolean active = false;
|
||||||
private boolean isChanged;
|
private boolean isChanged;
|
||||||
private boolean detailPaneMode;
|
private boolean detailPaneMode;
|
||||||
|
@ -277,7 +281,8 @@ public class ADSortTab extends Panel implements IADTabpanel
|
||||||
m_IdentifierSql = identifierSql.toString();
|
m_IdentifierSql = identifierSql.toString();
|
||||||
//
|
//
|
||||||
noLabel.setValue(Msg.getMsg(Env.getCtx(), "Available"));
|
noLabel.setValue(Msg.getMsg(Env.getCtx(), "Available"));
|
||||||
log.fine(m_ColumnSortName);
|
if (log.isLoggable(Level.FINE))
|
||||||
|
log.fine(m_ColumnSortName);
|
||||||
} // dynInit
|
} // dynInit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -520,14 +525,19 @@ public class ADSortTab extends Panel implements IADTabpanel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if tab has changes
|
||||||
|
*/
|
||||||
public boolean isChanged() {
|
public boolean isChanged() {
|
||||||
return isChanged;
|
return isChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Move an item between yes and no list.
|
||||||
|
* Delegate to {@link #migrateLists(Listbox, Listbox, int)}
|
||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
void migrateValueAcrossLists (Event event)
|
protected void migrateValueAcrossLists (Event event)
|
||||||
{
|
{
|
||||||
Object source = event.getTarget();
|
Object source = event.getTarget();
|
||||||
if (source instanceof ListItem) {
|
if (source instanceof ListItem) {
|
||||||
|
@ -544,7 +554,13 @@ public class ADSortTab extends Panel implements IADTabpanel
|
||||||
migrateLists (listFrom,listTo,endIndex);
|
migrateLists (listFrom,listTo,endIndex);
|
||||||
} // migrateValueAcrossLists
|
} // migrateValueAcrossLists
|
||||||
|
|
||||||
void migrateLists (Listbox listFrom , Listbox listTo , int endIndex)
|
/**
|
||||||
|
* Move an item from listFrom to listTo.
|
||||||
|
* @param listFrom
|
||||||
|
* @param listTo
|
||||||
|
* @param endIndex destination index
|
||||||
|
*/
|
||||||
|
protected void migrateLists (Listbox listFrom , Listbox listTo , int endIndex)
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
SimpleListModel lmFrom = (listFrom == yesList) ? yesModel:noModel;
|
SimpleListModel lmFrom = (listFrom == yesList) ? yesModel:noModel;
|
||||||
|
@ -577,10 +593,10 @@ public class ADSortTab extends Panel implements IADTabpanel
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move within Yes List
|
* Move an item within Yes List
|
||||||
* @param event event
|
* @param event event
|
||||||
*/
|
*/
|
||||||
void migrateValueWithinYesList (Event event)
|
protected void migrateValueWithinYesList (Event event)
|
||||||
{
|
{
|
||||||
Object[] selObjects = yesList.getSelectedItems().toArray();
|
Object[] selObjects = yesList.getSelectedItems().toArray();
|
||||||
if (selObjects == null)
|
if (selObjects == null)
|
||||||
|
@ -643,10 +659,10 @@ public class ADSortTab extends Panel implements IADTabpanel
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move within Yes List with Drag Event and Multiple Choice
|
* Move items within Yes List with Drag Event and Multiple Choice
|
||||||
* @param event event
|
* @param event event
|
||||||
*/
|
*/
|
||||||
void migrateValueWithinYesList (int endIndex, List<ListElement> selObjects)
|
protected void migrateValueWithinYesList (int endIndex, List<ListElement> selObjects)
|
||||||
{
|
{
|
||||||
int iniIndex =0;
|
int iniIndex =0;
|
||||||
Arrays.sort(selObjects.toArray());
|
Arrays.sort(selObjects.toArray());
|
||||||
|
@ -667,8 +683,9 @@ public class ADSortTab extends Panel implements IADTabpanel
|
||||||
setIsChanged(true);
|
setIsChanged(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/**
|
||||||
* @see org.compiere.grid.APanelTab#registerAPanel(APanel)
|
* Set AD Window content part that own this ADSortTab instance.
|
||||||
|
* @param panel
|
||||||
*/
|
*/
|
||||||
public void registerAPanel (AbstractADWindowContent panel)
|
public void registerAPanel (AbstractADWindowContent panel)
|
||||||
{
|
{
|
||||||
|
@ -676,14 +693,15 @@ public class ADSortTab extends Panel implements IADTabpanel
|
||||||
} // registerAPanel
|
} // registerAPanel
|
||||||
|
|
||||||
|
|
||||||
/** (non-Javadoc)
|
/**
|
||||||
|
* Save changes to db.
|
||||||
*/
|
*/
|
||||||
public void saveData()
|
public void saveData()
|
||||||
{
|
{
|
||||||
if (!adWindowPanel.getToolbar().isSaveEnable())
|
if (!adWindowPanel.getToolbar().isSaveEnable())
|
||||||
return;
|
return;
|
||||||
log.fine("");
|
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
|
//TODO: should use model instead to enable change log and event handling
|
||||||
StringBuilder info = new StringBuilder();
|
StringBuilder info = new StringBuilder();
|
||||||
StringBuffer sql = null;
|
StringBuffer sql = null;
|
||||||
// noList - Set SortColumn to null and optional YesNo Column to 'N'
|
// noList - Set SortColumn to null and optional YesNo Column to 'N'
|
||||||
|
@ -851,6 +869,7 @@ public class ADSortTab extends Panel implements IADTabpanel
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onEvent(Event event) throws Exception {
|
public void onEvent(Event event) throws Exception {
|
||||||
if (event instanceof DropEvent)
|
if (event instanceof DropEvent)
|
||||||
{
|
{
|
||||||
|
@ -884,6 +903,7 @@ public class ADSortTab extends Panel implements IADTabpanel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void activate(boolean b) {
|
public void activate(boolean b) {
|
||||||
if (b) {
|
if (b) {
|
||||||
if (getAttribute(ATTR_ON_ACTIVATE_POSTED) != null) {
|
if (getAttribute(ATTR_ON_ACTIVATE_POSTED) != null) {
|
||||||
|
@ -899,6 +919,7 @@ public class ADSortTab extends Panel implements IADTabpanel
|
||||||
Events.postEvent(event);
|
Events.postEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void createUI() {
|
public void createUI() {
|
||||||
if (uiCreated) return;
|
if (uiCreated) return;
|
||||||
try
|
try
|
||||||
|
@ -913,64 +934,80 @@ public class ADSortTab extends Panel implements IADTabpanel
|
||||||
uiCreated = true;
|
uiCreated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void dynamicDisplay(int i) {
|
public void dynamicDisplay(int i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true, since = "11")
|
||||||
public void editRecord(boolean b) {
|
public void editRecord(boolean b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getDisplayLogic() {
|
public String getDisplayLogic() {
|
||||||
return gridTab.getDisplayLogic();
|
return gridTab.getDisplayLogic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public GridTab getGridTab() {
|
public GridTab getGridTab() {
|
||||||
return gridTab;
|
return gridTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getTabLevel() {
|
public int getTabLevel() {
|
||||||
return gridTab.getTabLevel();
|
return gridTab.getTabLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getTableName()
|
public String getTableName()
|
||||||
{
|
{
|
||||||
return gridTab.getTableName();
|
return gridTab.getTableName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getRecord_ID() {
|
public int getRecord_ID() {
|
||||||
return gridTab.getRecord_ID();
|
return gridTab.getRecord_ID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return gridTab.getName();
|
return gridTab.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isCurrent() {
|
public boolean isCurrent() {
|
||||||
return gridTab != null ? gridTab.isCurrent() : false;
|
return gridTab != null ? gridTab.isCurrent() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void query() {
|
public void query() {
|
||||||
loadData();
|
loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void query(boolean currentRows, int currentDays, int i) {
|
public void query(boolean currentRows, int currentDays, int i) {
|
||||||
loadData();
|
loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
createUI();
|
createUI();
|
||||||
loadData();
|
loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void switchRowPresentation() {
|
public void switchRowPresentation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String get_ValueAsString(String variableName) {
|
public String get_ValueAsString(String variableName) {
|
||||||
return Env.getContext(Env.getCtx(), m_WindowNo, variableName);
|
return Env.getContext(Env.getCtx(), m_WindowNo, variableName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void afterSave(boolean onSaveEvent) {
|
public void afterSave(boolean onSaveEvent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean onEnterKey() {
|
public boolean onEnterKey() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -991,6 +1028,7 @@ public class ADSortTab extends Panel implements IADTabpanel
|
||||||
ZKUpdateUtil.setVflex(this, "true");
|
ZKUpdateUtil.setVflex(this, "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isDetailPaneMode() {
|
public boolean isDetailPaneMode() {
|
||||||
return this.detailPaneMode;
|
return this.detailPaneMode;
|
||||||
}
|
}
|
||||||
|
@ -1053,6 +1091,7 @@ public class ADSortTab extends Panel implements IADTabpanel
|
||||||
noList.setModel(noModel);
|
noList.setModel(noModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ADTreePanel getTreePanel() {
|
public ADTreePanel getTreePanel() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,7 @@ import org.zkoss.zul.West;
|
||||||
import org.zkoss.zul.impl.XulElement;
|
import org.zkoss.zul.impl.XulElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* UI for an AD_Tab content (AD_Tab + AD_Fields).
|
||||||
*
|
*
|
||||||
* This class is based on org.compiere.grid.GridController written by Jorg Janke.
|
* This class is based on org.compiere.grid.GridController written by Jorg Janke.
|
||||||
* Changes have been brought for UI compatibility.
|
* Changes have been brought for UI compatibility.
|
||||||
|
@ -142,6 +143,7 @@ import org.zkoss.zul.impl.XulElement;
|
||||||
public class ADTabpanel extends Div implements Evaluatee, EventListener<Event>,
|
public class ADTabpanel extends Div implements Evaluatee, EventListener<Event>,
|
||||||
DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
{
|
{
|
||||||
|
//css for slide animation
|
||||||
private static final String SLIDE_LEFT_IN_CSS = "slide-left-in";
|
private static final String SLIDE_LEFT_IN_CSS = "slide-left-in";
|
||||||
|
|
||||||
private static final String SLIDE_LEFT_OUT_CSS = "slide-left-out";
|
private static final String SLIDE_LEFT_OUT_CSS = "slide-left-out";
|
||||||
|
@ -151,19 +153,26 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
private static final String SLIDE_RIGHT_OUT_CSS = "slide-right-out";
|
private static final String SLIDE_RIGHT_OUT_CSS = "slide-right-out";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -5335610241895151024L;
|
private static final long serialVersionUID = -5335610241895151024L;
|
||||||
|
|
||||||
|
/** event to save open/close state of detail pane as user preference for ad window **/
|
||||||
private static final String ON_SAVE_OPEN_PREFERENCE_EVENT = "onSaveOpenPreference";
|
private static final String ON_SAVE_OPEN_PREFERENCE_EVENT = "onSaveOpenPreference";
|
||||||
|
|
||||||
|
/** post init event for tab panel **/
|
||||||
public static final String ON_POST_INIT_EVENT = "onPostInit";
|
public static final String ON_POST_INIT_EVENT = "onPostInit";
|
||||||
|
|
||||||
|
/** event after tab panel had switch presentation between form and list view **/
|
||||||
public static final String ON_SWITCH_VIEW_EVENT = "onSwitchView";
|
public static final String ON_SWITCH_VIEW_EVENT = "onSwitchView";
|
||||||
|
|
||||||
|
/** Event after execution of {@link #dynamicDisplay(int)} **/
|
||||||
public static final String ON_DYNAMIC_DISPLAY_EVENT = "onDynamicDisplay";
|
public static final String ON_DYNAMIC_DISPLAY_EVENT = "onDynamicDisplay";
|
||||||
|
|
||||||
|
/** defer event to set selected tree node **/
|
||||||
private static final String ON_DEFER_SET_SELECTED_NODE = "onDeferSetSelectedNode";
|
private static final String ON_DEFER_SET_SELECTED_NODE = "onDeferSetSelectedNode";
|
||||||
|
|
||||||
|
/** ADTabpanel attribute to prevent ON_DEFER_SET_SELECTED_NODE event posted twice within 1 execution **/
|
||||||
private static final String ON_DEFER_SET_SELECTED_NODE_ATTR = "onDeferSetSelectedNode.Event.Posted";
|
private static final String ON_DEFER_SET_SELECTED_NODE_ATTR = "onDeferSetSelectedNode.Event.Posted";
|
||||||
|
|
||||||
private static final CLogger logger;
|
private static final CLogger logger;
|
||||||
|
@ -177,68 +186,95 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
|
|
||||||
private GridWindow gridWindow;
|
private GridWindow gridWindow;
|
||||||
|
|
||||||
|
/** AD Window content part that own this ADTabpanel instance **/
|
||||||
private AbstractADWindowContent windowPanel;
|
private AbstractADWindowContent windowPanel;
|
||||||
|
|
||||||
private int windowNo;
|
private int windowNo;
|
||||||
|
|
||||||
|
/** form view for center of {@link #formContainer} **/
|
||||||
private Grid form;
|
private Grid form;
|
||||||
|
|
||||||
|
/** field editors **/
|
||||||
private ArrayList<WEditor> editors = new ArrayList<WEditor>();
|
private ArrayList<WEditor> editors = new ArrayList<WEditor>();
|
||||||
|
|
||||||
|
/** components for field editors **/
|
||||||
private ArrayList<Component> editorComps = new ArrayList<Component>();
|
private ArrayList<Component> editorComps = new ArrayList<Component>();
|
||||||
|
|
||||||
|
/** editor toolbar buttons**/
|
||||||
private ArrayList<WButtonEditor> toolbarButtonEditors = new ArrayList<WButtonEditor>();
|
private ArrayList<WButtonEditor> toolbarButtonEditors = new ArrayList<WButtonEditor>();
|
||||||
|
|
||||||
|
/** toolbar buttons for AD_ToolBarButton **/
|
||||||
private ArrayList<ToolbarProcessButton> toolbarProcessButtons = new ArrayList<ToolbarProcessButton>();
|
private ArrayList<ToolbarProcessButton> toolbarProcessButtons = new ArrayList<ToolbarProcessButton>();
|
||||||
|
|
||||||
|
/** true if UI have been created for form and list **/
|
||||||
private boolean uiCreated = false;
|
private boolean uiCreated = false;
|
||||||
|
|
||||||
|
/** list view for center of {@link #formContainer} **/
|
||||||
private GridView listPanel;
|
private GridView listPanel;
|
||||||
|
|
||||||
|
/** content rows for group **/
|
||||||
private Map<String, List<Row>> fieldGroupContents;
|
private Map<String, List<Row>> fieldGroupContents;
|
||||||
|
|
||||||
|
/** header row for group **/
|
||||||
private Map<String, List<org.zkoss.zul.Row>> fieldGroupHeaders;
|
private Map<String, List<org.zkoss.zul.Row>> fieldGroupHeaders;
|
||||||
|
|
||||||
|
/** tabs for group (for tab type field group) **/
|
||||||
private Map<String, List<Tab>> fieldGroupTabHeaders;
|
private Map<String, List<Tab>> fieldGroupTabHeaders;
|
||||||
|
|
||||||
|
/** all rows for current group (regardless of field group type) **/
|
||||||
private ArrayList<Row> rowList;
|
private ArrayList<Row> rowList;
|
||||||
|
|
||||||
|
/** all collapsible groups **/
|
||||||
protected List<Group> allCollapsibleGroups;
|
protected List<Group> allCollapsibleGroups;
|
||||||
|
|
||||||
|
/** main layout for header (center), tree (west) and detail pane (south) **/
|
||||||
private Borderlayout formContainer = null;
|
private Borderlayout formContainer = null;
|
||||||
|
|
||||||
|
/** Tree panel for west of {@link #formContainer} **/
|
||||||
private ADTreePanel treePanel = null;
|
private ADTreePanel treePanel = null;
|
||||||
|
|
||||||
|
/** Sync field editor changes to GridField **/
|
||||||
private GridTabDataBinder dataBinder;
|
private GridTabDataBinder dataBinder;
|
||||||
|
|
||||||
|
/** true if tab have been activated **/
|
||||||
protected boolean activated = false;
|
protected boolean activated = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* current group for collapsible type field group
|
||||||
|
*/
|
||||||
private Group currentGroup;
|
private Group currentGroup;
|
||||||
|
|
||||||
|
/** Panel for child tabs, south of {@link #formContainer} **/
|
||||||
private DetailPane detailPane;
|
private DetailPane detailPane;
|
||||||
|
|
||||||
|
/** true if this ADTabpanel instance is own by detail pane **/
|
||||||
private boolean detailPaneMode;
|
private boolean detailPaneMode;
|
||||||
|
|
||||||
|
/** tab no within an AD Window (sequence start from 0) **/
|
||||||
private int tabNo;
|
private int tabNo;
|
||||||
|
|
||||||
/** DefaultFocusField */
|
/** Default focus field */
|
||||||
private WEditor defaultFocusField = null;
|
private WEditor defaultFocusField = null;
|
||||||
|
|
||||||
|
/** number of columns for {@link #form} **/
|
||||||
private int numberOfFormColumns;
|
private int numberOfFormColumns;
|
||||||
|
|
||||||
|
/** event to toggle between form and list view **/
|
||||||
public static final String ON_TOGGLE_EVENT = "onToggle";
|
public static final String ON_TOGGLE_EVENT = "onToggle";
|
||||||
|
|
||||||
|
/** default width for west tree panel **/
|
||||||
private static final String DEFAULT_PANEL_WIDTH = "300px";
|
private static final String DEFAULT_PANEL_WIDTH = "300px";
|
||||||
|
|
||||||
private static CCache<Integer, Boolean> quickFormCache = new CCache<Integer, Boolean>(null, "QuickForm", 20, false);
|
private static CCache<Integer, Boolean> quickFormCache = new CCache<Integer, Boolean>(null, "QuickForm", 20, false);
|
||||||
|
|
||||||
/** Tab Box for Tab Field Groups */
|
/** Tab Box for Tab Type Field Groups */
|
||||||
private Tabbox tabbox = new Tabbox();
|
private Tabbox tabbox = new Tabbox();
|
||||||
/** List of Tab Group Grids */
|
/** List of Grid/Form for tab type field group */
|
||||||
private List<Grid> tabForms;
|
private List<Grid> tabGroupForms;
|
||||||
/** Current Tab Group Rows */
|
/** Current Rows for tab type field group */
|
||||||
private Rows currentTabRows;
|
private Rows currentTabGroupRows;
|
||||||
|
|
||||||
|
/** Event for south of {@link #formContainer} **/
|
||||||
private static enum SouthEvent {
|
private static enum SouthEvent {
|
||||||
SLIDE(),
|
SLIDE(),
|
||||||
OPEN(),
|
OPEN(),
|
||||||
|
@ -247,11 +283,17 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
private SouthEvent() {}
|
private SouthEvent() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default constructor
|
||||||
|
*/
|
||||||
public ADTabpanel()
|
public ADTabpanel()
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* init components and event listeners
|
||||||
|
*/
|
||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
initComponents();
|
initComponents();
|
||||||
|
@ -270,6 +312,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
ClientInfo.onClientInfo(this, this::onClientInfo);
|
ClientInfo.onClientInfo(this, this::onClientInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new {@link #form} and {@link #listPanel} instance.
|
||||||
|
*/
|
||||||
private void initComponents()
|
private void initComponents()
|
||||||
{
|
{
|
||||||
LayoutUtils.addSclass("adtab-content", this);
|
LayoutUtils.addSclass("adtab-content", this);
|
||||||
|
@ -282,6 +327,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
form.setVflex(false);
|
form.setVflex(false);
|
||||||
form.setSclass("grid-layout adwindow-form");
|
form.setSclass("grid-layout adwindow-form");
|
||||||
form.setWidgetAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, "form");
|
form.setWidgetAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, "form");
|
||||||
|
//swipe listener for mobile
|
||||||
if (ClientInfo.isMobile())
|
if (ClientInfo.isMobile())
|
||||||
{
|
{
|
||||||
form.addEventListener("onSwipeRight", e -> {
|
form.addEventListener("onSwipeRight", e -> {
|
||||||
|
@ -313,6 +359,10 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
listPanel.getListbox().addEventListener(Events.ON_DOUBLE_CLICK, this);
|
listPanel.getListbox().addEventListener(Events.ON_DOUBLE_CLICK, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup client side form swipe listener for mobile.
|
||||||
|
* Send onSwipeRight and onSwipeLeft event to server.
|
||||||
|
*/
|
||||||
private void setupFormSwipeListener() {
|
private void setupFormSwipeListener() {
|
||||||
String uuid = form.getUuid();
|
String uuid = form.getUuid();
|
||||||
StringBuilder script = new StringBuilder("(function(){let w=zk.Widget.$('")
|
StringBuilder script = new StringBuilder("(function(){let w=zk.Widget.$('")
|
||||||
|
@ -344,7 +394,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
public void setDetailPane(DetailPane component) {
|
public void setDetailPane(DetailPane component) {
|
||||||
detailPane = component;
|
detailPane = component;
|
||||||
|
|
||||||
Borderlayout borderLayout = (Borderlayout) formContainer;
|
Borderlayout borderLayout = formContainer;
|
||||||
South south = borderLayout.getSouth();
|
South south = borderLayout.getSouth();
|
||||||
if (south == null) {
|
if (south == null) {
|
||||||
south = new South();
|
south = new South();
|
||||||
|
@ -375,7 +425,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
ZKUpdateUtil.setHeight(formContainer.getSouth(), height);
|
ZKUpdateUtil.setHeight(formContainer.getSouth(), height);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// just ignore exception is harmless here, consequence is just not setting height so it will assume the default of theme
|
// just ignore, exception is harmless here, consequence is just not setting height so it will assume the default of theme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -386,7 +436,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* init tab panel layout ({@link #formContainer} and listeners
|
||||||
* @param winPanel
|
* @param winPanel
|
||||||
* @param gridTab
|
* @param gridTab
|
||||||
*/
|
*/
|
||||||
|
@ -487,7 +537,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create UI components if not already created
|
* Create UI for AD_Fields
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void createUI()
|
public void createUI()
|
||||||
|
@ -496,7 +546,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Create UI for AD_Fields
|
||||||
* @param update true if it is update instead of create new
|
* @param update true if it is update instead of create new
|
||||||
*/
|
*/
|
||||||
protected void createUI(boolean update)
|
protected void createUI(boolean update)
|
||||||
|
@ -515,7 +565,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
fieldGroupHeaders = new HashMap<String, List<org.zkoss.zul.Row>>();
|
fieldGroupHeaders = new HashMap<String, List<org.zkoss.zul.Row>>();
|
||||||
allCollapsibleGroups = new ArrayList<Group>();
|
allCollapsibleGroups = new ArrayList<Group>();
|
||||||
|
|
||||||
tabForms = new ArrayList<Grid>();
|
tabGroupForms = new ArrayList<Grid>();
|
||||||
fieldGroupTabHeaders = new HashMap<String, List<Tab>>();
|
fieldGroupTabHeaders = new HashMap<String, List<Tab>>();
|
||||||
|
|
||||||
int numCols=gridTab.getNumColumns();
|
int numCols=gridTab.getNumColumns();
|
||||||
|
@ -610,8 +660,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
|
|
||||||
if (numCols - actualxpos + 1 > 0)
|
if (numCols - actualxpos + 1 > 0)
|
||||||
row.appendCellChild(createSpacer(), numCols - actualxpos + 1);
|
row.appendCellChild(createSpacer(), numCols - actualxpos + 1);
|
||||||
if(currentTabRows != null) {
|
if (currentTabGroupRows != null) {
|
||||||
currentTabRows.appendChild(row);
|
currentTabGroupRows.appendChild(row);
|
||||||
} else {
|
} else {
|
||||||
row.setGroup(currentGroup);
|
row.setGroup(currentGroup);
|
||||||
rows.appendChild(row);
|
rows.appendChild(row);
|
||||||
|
@ -641,7 +691,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
rows.appendChild(row);
|
rows.appendChild(row);
|
||||||
headerRows.add(row);
|
headerRows.add(row);
|
||||||
currentGroup = null;
|
currentGroup = null;
|
||||||
currentTabRows = null;
|
currentTabGroupRows = null;
|
||||||
} else if(X_AD_FieldGroup.FIELDGROUPTYPE_Tab.equals(field.getFieldGroupType())) {
|
} else if(X_AD_FieldGroup.FIELDGROUPTYPE_Tab.equals(field.getFieldGroupType())) {
|
||||||
// Create New Tab for FieldGroup
|
// Create New Tab for FieldGroup
|
||||||
List<Tab> headerTabs = new ArrayList<Tab>();
|
List<Tab> headerTabs = new ArrayList<Tab>();
|
||||||
|
@ -658,7 +708,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
headerTabs.add(tab);
|
headerTabs.add(tab);
|
||||||
|
|
||||||
Grid tabForm = new Grid();
|
Grid tabForm = new Grid();
|
||||||
tabForms.add(tabForm);
|
tabGroupForms.add(tabForm);
|
||||||
ZKUpdateUtil.setHflex(tabForm, "1");
|
ZKUpdateUtil.setHflex(tabForm, "1");
|
||||||
ZKUpdateUtil.setHeight(tabForm, null);
|
ZKUpdateUtil.setHeight(tabForm, null);
|
||||||
tabForm.setVflex(false);
|
tabForm.setVflex(false);
|
||||||
|
@ -696,7 +746,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
tp.appendChild(tabForm);
|
tp.appendChild(tabForm);
|
||||||
|
|
||||||
currentGroup = null;
|
currentGroup = null;
|
||||||
currentTabRows = tabRows;
|
currentTabGroupRows = tabRows;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -710,7 +760,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
{
|
{
|
||||||
rowg.setOpen(false);
|
rowg.setOpen(false);
|
||||||
}
|
}
|
||||||
currentTabRows = null;
|
currentTabGroupRows = null;
|
||||||
currentGroup = rowg;
|
currentGroup = rowg;
|
||||||
rows.appendChild(rowg);
|
rows.appendChild(rowg);
|
||||||
headerRows.add(rowg);
|
headerRows.add(rowg);
|
||||||
|
@ -738,8 +788,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
if (numCols - actualxpos + 1 > 0)
|
if (numCols - actualxpos + 1 > 0)
|
||||||
row.appendCellChild(createSpacer(), numCols - actualxpos + 1);
|
row.appendCellChild(createSpacer(), numCols - actualxpos + 1);
|
||||||
// Tab Group vs Grid Group
|
// Tab Group vs Grid Group
|
||||||
if(currentTabRows != null) {
|
if (currentTabGroupRows != null) {
|
||||||
currentTabRows.appendChild(row);
|
currentTabGroupRows.appendChild(row);
|
||||||
} else {
|
} else {
|
||||||
row.setGroup(currentGroup);
|
row.setGroup(currentGroup);
|
||||||
rows.appendChild(row);
|
rows.appendChild(row);
|
||||||
|
@ -899,8 +949,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
if (numCols - actualxpos + 1 > 0)
|
if (numCols - actualxpos + 1 > 0)
|
||||||
row.appendCellChild(createSpacer(), numCols - actualxpos + 1);
|
row.appendCellChild(createSpacer(), numCols - actualxpos + 1);
|
||||||
// Tab Group vs Grid Group
|
// Tab Group vs Grid Group
|
||||||
if(currentTabRows != null) {
|
if (currentTabGroupRows != null) {
|
||||||
currentTabRows.appendChild(row);
|
currentTabGroupRows.appendChild(row);
|
||||||
} else {
|
} else {
|
||||||
row.setGroup(currentGroup);
|
row.setGroup(currentGroup);
|
||||||
rows.appendChild(row);
|
rows.appendChild(row);
|
||||||
|
@ -936,6 +986,10 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
switchRowPresentation();
|
switchRowPresentation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param field
|
||||||
|
* @return {@link WEditor} or null if not found
|
||||||
|
*/
|
||||||
private WEditor findEditor(GridField field) {
|
private WEditor findEditor(GridField field) {
|
||||||
for(WEditor editor : editors) {
|
for(WEditor editor : editors) {
|
||||||
if (editor.getGridField() == field)
|
if (editor.getGridField() == field)
|
||||||
|
@ -944,6 +998,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* load toolbar buttons from AD_ToolBarButton
|
||||||
|
*/
|
||||||
private void loadToolbarButtons() {
|
private void loadToolbarButtons() {
|
||||||
//get extra toolbar process buttons
|
//get extra toolbar process buttons
|
||||||
MToolBarButton[] mToolbarButtons = MToolBarButton.getProcessButtonOfTab(gridTab.getAD_Tab_ID(), null);
|
MToolBarButton[] mToolbarButtons = MToolBarButton.getProcessButtonOfTab(gridTab.getAD_Tab_ID(), null);
|
||||||
|
@ -976,7 +1033,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate display properties of fields of current row.
|
* Update state of fields (visibility, style, writable, etc)
|
||||||
* @param col
|
* @param col
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -987,6 +1044,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//css animation for slide
|
||||||
if (form.getSclass() != null && form.getSclass().contains(SLIDE_RIGHT_OUT_CSS)) {
|
if (form.getSclass() != null && form.getSclass().contains(SLIDE_RIGHT_OUT_CSS)) {
|
||||||
Executions.schedule(getDesktop(), e -> {
|
Executions.schedule(getDesktop(), e -> {
|
||||||
LayoutUtils.removeSclass(SLIDE_RIGHT_OUT_CSS, form);
|
LayoutUtils.removeSclass(SLIDE_RIGHT_OUT_CSS, form);
|
||||||
|
@ -1104,7 +1162,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
//hide row if all editor within the row is invisible in Tabbox grid
|
//hide row if all editor within the row is invisible in Tabbox grid
|
||||||
for(Grid tabForm: tabForms) {
|
for(Grid tabForm: tabGroupForms) {
|
||||||
List<Component> tabrows = tabForm.getRows().getChildren();
|
List<Component> tabrows = tabForm.getRows().getChildren();
|
||||||
for (Component comp : tabrows)
|
for (Component comp : tabrows)
|
||||||
{
|
{
|
||||||
|
@ -1217,6 +1275,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
LayoutUtils.removeSclass(SLIDE_RIGHT_IN_CSS, form);
|
LayoutUtils.removeSclass(SLIDE_RIGHT_IN_CSS, form);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* echo set selected node event for tree
|
||||||
|
*/
|
||||||
private void echoDeferSetSelectedNodeEvent() {
|
private void echoDeferSetSelectedNodeEvent() {
|
||||||
if (getAttribute(ON_DEFER_SET_SELECTED_NODE_ATTR) == null) {
|
if (getAttribute(ON_DEFER_SET_SELECTED_NODE_ATTR) == null) {
|
||||||
setAttribute(ON_DEFER_SET_SELECTED_NODE_ATTR, Boolean.TRUE);
|
setAttribute(ON_DEFER_SET_SELECTED_NODE_ATTR, Boolean.TRUE);
|
||||||
|
@ -1225,7 +1286,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return String
|
* @return display logic
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getDisplayLogic()
|
public String getDisplayLogic()
|
||||||
|
@ -1234,7 +1295,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return String
|
* @return title of tab
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getTitle()
|
public String getTitle()
|
||||||
|
@ -1244,6 +1305,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param variableName
|
* @param variableName
|
||||||
|
* @return value
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String get_ValueAsString(String variableName)
|
public String get_ValueAsString(String variableName)
|
||||||
|
@ -1270,7 +1332,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The record ID of this Tabpanel
|
* @return The record ID of current row
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int getRecord_ID()
|
public int getRecord_ID()
|
||||||
|
@ -1280,7 +1342,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is panel need refresh
|
* Is panel need refresh
|
||||||
* @return boolean
|
* @return true if GridTab need refresh
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isCurrent()
|
public boolean isCurrent()
|
||||||
|
@ -1298,7 +1360,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve from db
|
* Retrieve from db.
|
||||||
|
* Delegate to {@link GridTab#query(boolean)}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void query()
|
public void query()
|
||||||
|
@ -1311,9 +1374,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve from db
|
* Retrieve from db
|
||||||
* @param onlyCurrentRows
|
* @param onlyCurrentRows True to show only unprocessed or the one updated within x days (default is 1 day before today)
|
||||||
* @param onlyCurrentDays
|
* @param onlyCurrentDays if > 0, filter records with created >= current_date - onlyCurrentDays
|
||||||
* @param maxRows
|
* @param maxRows if > 0, maximum number of rows to load
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void query (boolean onlyCurrentRows, int onlyCurrentDays, int maxRows)
|
public void query (boolean onlyCurrentRows, int onlyCurrentDays, int maxRows)
|
||||||
|
@ -1339,7 +1402,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reset detail data grid for new parent record that's not saved yet
|
* Reset detail data grid for new parent record that's not saved yet.
|
||||||
|
* Delegate to {@link GridTab#resetDetailForNewParentRecord()}.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void resetDetailForNewParentRecord ()
|
public void resetDetailForNewParentRecord ()
|
||||||
|
@ -1364,7 +1428,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return TreePanel
|
* @return ADTreePanel
|
||||||
*/
|
*/
|
||||||
public ADTreePanel getTreePanel()
|
public ADTreePanel getTreePanel()
|
||||||
{
|
{
|
||||||
|
@ -1372,7 +1436,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return TreePanel
|
* @return master, detail or both
|
||||||
*/
|
*/
|
||||||
public String getTreeDisplayedOn()
|
public String getTreeDisplayedOn()
|
||||||
{
|
{
|
||||||
|
@ -1434,7 +1498,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Delegate to {@link #focusToEditor(WEditor, boolean)}
|
||||||
* @param checkCurrent
|
* @param checkCurrent
|
||||||
*/
|
*/
|
||||||
public void focusToFirstEditor(boolean checkCurrent) {
|
public void focusToFirstEditor(boolean checkCurrent) {
|
||||||
|
@ -1535,6 +1599,10 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle open/close event of south panel (detail pane)
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
private void onSouthEvent(SouthEvent event) {
|
private void onSouthEvent(SouthEvent event) {
|
||||||
if (event == SouthEvent.OPEN || event == SouthEvent.CLOSE) {
|
if (event == SouthEvent.OPEN || event == SouthEvent.CLOSE) {
|
||||||
boolean open = event == SouthEvent.OPEN ? true : false;
|
boolean open = event == SouthEvent.OPEN ? true : false;
|
||||||
|
@ -1563,6 +1631,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if detail pane is open/visible
|
||||||
|
*/
|
||||||
private boolean isOpenDetailPane() {
|
private boolean isOpenDetailPane() {
|
||||||
if (isMobile())
|
if (isMobile())
|
||||||
return false;
|
return false;
|
||||||
|
@ -1578,6 +1649,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
return open;
|
return open;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return height of detail pane from user preference
|
||||||
|
*/
|
||||||
private String heigthDetailPane() {
|
private String heigthDetailPane() {
|
||||||
String height = null;
|
String height = null;
|
||||||
int windowId = getGridTab().getAD_Window_ID();
|
int windowId = getGridTab().getAD_Window_ID();
|
||||||
|
@ -1588,6 +1662,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return width of tree panel from user preference (or default if no user preference)
|
||||||
|
*/
|
||||||
private String widthTreePanel() {
|
private String widthTreePanel() {
|
||||||
String width = null;
|
String width = null;
|
||||||
int windowId = getGridTab().getAD_Window_ID();
|
int windowId = getGridTab().getAD_Window_ID();
|
||||||
|
@ -1597,6 +1674,10 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
return Util.isEmpty(width) ? DEFAULT_PANEL_WIDTH : width;
|
return Util.isEmpty(width) ? DEFAULT_PANEL_WIDTH : width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigate to a tree node
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
private void navigateTo(DefaultTreeNode<MTreeNode> value) {
|
private void navigateTo(DefaultTreeNode<MTreeNode> value) {
|
||||||
MTreeNode treeNode = value.getData();
|
MTreeNode treeNode = value.getData();
|
||||||
// We Have a TreeNode
|
// We Have a TreeNode
|
||||||
|
@ -1654,7 +1735,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
Dialog.error(windowNo, msg);
|
Dialog.error(windowNo, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if (col >= 0)
|
|
||||||
|
//update UI state
|
||||||
if (!uiCreated)
|
if (!uiCreated)
|
||||||
createUI();
|
createUI();
|
||||||
dynamicDisplay(col);
|
dynamicDisplay(col);
|
||||||
|
@ -1750,6 +1832,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
treePanel.initTree(AD_Tree_ID, windowNo);
|
treePanel.initTree(AD_Tree_ID, windowNo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//update list view
|
||||||
if (listPanel.isVisible()) {
|
if (listPanel.isVisible()) {
|
||||||
listPanel.updateListIndex();
|
listPanel.updateListIndex();
|
||||||
listPanel.dynamicDisplay(col);
|
listPanel.dynamicDisplay(col);
|
||||||
|
@ -1760,6 +1844,10 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delete tree node by recordId
|
||||||
|
* @param recordId
|
||||||
|
*/
|
||||||
private void deleteNode(int recordId) {
|
private void deleteNode(int recordId) {
|
||||||
if (recordId <= 0) return;
|
if (recordId <= 0) return;
|
||||||
|
|
||||||
|
@ -1780,6 +1868,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add new tree node for current row
|
||||||
|
*/
|
||||||
private void addNewNode() {
|
private void addNewNode() {
|
||||||
if (gridTab.getRecord_ID() > 0) {
|
if (gridTab.getRecord_ID() > 0) {
|
||||||
String name = (String)gridTab.getValue("Name");
|
String name = (String)gridTab.getValue("Name");
|
||||||
|
@ -1817,6 +1908,10 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set selected tree node by recordId
|
||||||
|
* @param recordId
|
||||||
|
*/
|
||||||
private void setSelectedNode(int recordId) {
|
private void setSelectedNode(int recordId) {
|
||||||
if (recordId <= 0) return;
|
if (recordId <= 0) return;
|
||||||
|
|
||||||
|
@ -1921,15 +2016,15 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
|
|
||||||
static class ZoomListener implements EventListener<Event> {
|
static class ZoomListener implements EventListener<Event> {
|
||||||
|
|
||||||
private IZoomableEditor searchEditor;
|
private IZoomableEditor zoomableEditor;
|
||||||
|
|
||||||
ZoomListener(IZoomableEditor editor) {
|
ZoomListener(IZoomableEditor editor) {
|
||||||
searchEditor = editor;
|
zoomableEditor = editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onEvent(Event event) throws Exception {
|
public void onEvent(Event event) throws Exception {
|
||||||
if (Events.ON_CLICK.equals(event.getName())) {
|
if (Events.ON_CLICK.equals(event.getName())) {
|
||||||
searchEditor.actionZoom();
|
zoomableEditor.actionZoom();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1980,7 +2075,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return boolean
|
* @return true if list/grid view is visible
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isGridView() {
|
public boolean isGridView() {
|
||||||
|
@ -1989,7 +2084,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return GridPanel
|
* @return {@link GridView}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public GridView getGridView() {
|
public GridView getGridView() {
|
||||||
|
@ -2015,6 +2110,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show detail pane
|
||||||
|
*/
|
||||||
private void attachDetailPane() {
|
private void attachDetailPane() {
|
||||||
if (formContainer.getSouth() != null) {
|
if (formContainer.getSouth() != null) {
|
||||||
formContainer.getSouth().setVisible(true);
|
formContainer.getSouth().setVisible(true);
|
||||||
|
@ -2029,6 +2127,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide detail pane
|
||||||
|
*/
|
||||||
private void detachDetailPane() {
|
private void detachDetailPane() {
|
||||||
if (formContainer.getSouth() != null) {
|
if (formContainer.getSouth() != null) {
|
||||||
formContainer.getSouth().setVisible(false);
|
formContainer.getSouth().setVisible(false);
|
||||||
|
@ -2039,8 +2140,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all visible button editors
|
* Get all visible toolbar button editors
|
||||||
* @return List<WButtonEditor>
|
* @return List<Button>
|
||||||
*/
|
*/
|
||||||
public List<Button> getToolbarButtons() {
|
public List<Button> getToolbarButtons() {
|
||||||
List<Button> buttonList = new ArrayList<Button>();
|
List<Button> buttonList = new ArrayList<Button>();
|
||||||
|
@ -2085,7 +2186,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* activate current selected detail tab if it is visible
|
* activate selected detail tab if it is visible
|
||||||
*/
|
*/
|
||||||
public void activateDetailIfVisible() {
|
public void activateDetailIfVisible() {
|
||||||
if (isDetailVisible()) {
|
if (isDetailVisible()) {
|
||||||
|
@ -2110,7 +2211,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return true if the detailpane is visible
|
* @return true if {@link DetailPane} is visible
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isDetailVisible() {
|
public boolean isDetailVisible() {
|
||||||
|
@ -2124,7 +2225,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return true if have one or more detail tabs
|
* @return true if selected tab has one or more detail/child tab
|
||||||
*/
|
*/
|
||||||
public boolean hasDetailTabs() {
|
public boolean hasDetailTabs() {
|
||||||
if (formContainer.getSouth() == null || !formContainer.getSouth().isVisible()) {
|
if (formContainer.getSouth() == null || !formContainer.getSouth().isVisible()) {
|
||||||
|
@ -2196,6 +2297,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if tree is order by value
|
||||||
|
*/
|
||||||
private boolean isTreeDrivenByValue() {
|
private boolean isTreeDrivenByValue() {
|
||||||
SimpleTreeModel model = (SimpleTreeModel)(TreeModel<?>) treePanel.getTree().getModel();
|
SimpleTreeModel model = (SimpleTreeModel)(TreeModel<?>) treePanel.getTree().getModel();
|
||||||
boolean retValue = false;
|
boolean retValue = false;
|
||||||
|
@ -2203,6 +2307,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
return retValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if value is shown in tree
|
||||||
|
*/
|
||||||
private boolean isValueDisplayed() {
|
private boolean isValueDisplayed() {
|
||||||
SimpleTreeModel model = (SimpleTreeModel)(TreeModel<?>) treePanel.getTree().getModel();
|
SimpleTreeModel model = (SimpleTreeModel)(TreeModel<?>) treePanel.getTree().getModel();
|
||||||
boolean retValue = false;
|
boolean retValue = false;
|
||||||
|
@ -2233,7 +2340,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Save user preference for this AD Window
|
||||||
* @param attribute
|
* @param attribute
|
||||||
* @param value
|
* @param value
|
||||||
*/
|
*/
|
||||||
|
@ -2287,6 +2394,9 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if client is mobile
|
||||||
|
*/
|
||||||
protected boolean isMobile() {
|
protected boolean isMobile() {
|
||||||
return ClientInfo.isMobile();
|
return ClientInfo.isMobile();
|
||||||
}
|
}
|
||||||
|
@ -2323,7 +2433,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Visibility for Tabbox based on Children and Form Visibility
|
* Set Visibility for {@link #tabbox} based on {@link #form} Visibility and whether {@link #tabbox} is empty
|
||||||
*/
|
*/
|
||||||
private void setGroupTabboxVisibility() {
|
private void setGroupTabboxVisibility() {
|
||||||
boolean isGroupTabVisible = false;
|
boolean isGroupTabVisible = false;
|
||||||
|
|
|
@ -35,29 +35,40 @@ import org.zkoss.zul.Tree;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
* Tree panel for AD_Tab with HasTree=Y
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ADTreePanel extends Panel implements EventListener<Event>
|
public class ADTreePanel extends Panel implements EventListener<Event>
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 2718257463734592729L;
|
private static final long serialVersionUID = 2718257463734592729L;
|
||||||
|
/** event to expand/collapse all tree nodes **/
|
||||||
private static final String ON_EXPAND_MENU_EVENT = "onExpandMenu";
|
private static final String ON_EXPAND_MENU_EVENT = "onExpandMenu";
|
||||||
|
/** search/lookup panel for tree **/
|
||||||
private TreeSearchPanel pnlSearch;
|
private TreeSearchPanel pnlSearch;
|
||||||
private Tree tree;
|
private Tree tree;
|
||||||
|
|
||||||
|
/** ToolBarButton to expand or collapse all tree nodes **/
|
||||||
private ToolBarButton expandToggle; // Elaine 2009/02/27 - expand tree
|
private ToolBarButton expandToggle; // Elaine 2009/02/27 - expand tree
|
||||||
private int m_windowno = -1;
|
private int m_windowno = -1;
|
||||||
private int m_tabno = -1;
|
private int m_tabno = -1;
|
||||||
private int AD_Tree_ID = -1;
|
private int AD_Tree_ID = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default constructor
|
||||||
|
*/
|
||||||
public ADTreePanel()
|
public ADTreePanel()
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param windowno
|
||||||
|
* @param tabno
|
||||||
|
*/
|
||||||
public ADTreePanel(int windowno, int tabno)
|
public ADTreePanel(int windowno, int tabno)
|
||||||
{
|
{
|
||||||
m_windowno = windowno;
|
m_windowno = windowno;
|
||||||
|
@ -66,6 +77,7 @@ public class ADTreePanel extends Panel implements EventListener<Event>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Delegate to {@link #initTree(int, int, String, int)}
|
||||||
* @param AD_Tree_ID
|
* @param AD_Tree_ID
|
||||||
* @param windowNo
|
* @param windowNo
|
||||||
*/
|
*/
|
||||||
|
@ -74,6 +86,14 @@ public class ADTreePanel extends Panel implements EventListener<Event>
|
||||||
return initTree(AD_Tree_ID, windowNo, null, 0);
|
return initTree(AD_Tree_ID, windowNo, null, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init and load tree
|
||||||
|
* @param AD_Tree_ID
|
||||||
|
* @param windowNo
|
||||||
|
* @param linkColName
|
||||||
|
* @param linkID
|
||||||
|
* @return true if a new tree have been created and loaded, false if AD_Tree_ID have already been loaded
|
||||||
|
*/
|
||||||
public boolean initTree(int AD_Tree_ID, int windowNo, String linkColName, int linkID)
|
public boolean initTree(int AD_Tree_ID, int windowNo, String linkColName, int linkID)
|
||||||
{
|
{
|
||||||
if (this.AD_Tree_ID != AD_Tree_ID)
|
if (this.AD_Tree_ID != AD_Tree_ID)
|
||||||
|
@ -89,6 +109,9 @@ public class ADTreePanel extends Panel implements EventListener<Event>
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout panel
|
||||||
|
*/
|
||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
setWidgetAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, "treepanel");
|
setWidgetAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, "treepanel");
|
||||||
|
@ -191,6 +214,9 @@ public class ADTreePanel extends Panel implements EventListener<Event>
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset AD_Tree_ID to create a new Tree in next {@link #initTree(int, int, String, int)} call
|
||||||
|
*/
|
||||||
public void prepareForRefresh() {
|
public void prepareForRefresh() {
|
||||||
this.AD_Tree_ID = -1;
|
this.AD_Tree_ID = -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,30 +38,37 @@ import org.compiere.util.Env;
|
||||||
import org.zkoss.zk.ui.Component;
|
import org.zkoss.zk.ui.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* UI part for AD_Window
|
||||||
* @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a>
|
* @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a>
|
||||||
* @date Feb 25, 2007
|
* @date Feb 25, 2007
|
||||||
* @version $Revision: 0.10 $
|
* @version $Revision: 0.10 $
|
||||||
*/
|
*/
|
||||||
public class ADWindow extends AbstractUIPart
|
public class ADWindow extends AbstractUIPart
|
||||||
{
|
{
|
||||||
|
/** Component attribute to hold reference to ancestor ADWindow instance **/
|
||||||
public static final String AD_WINDOW_ATTRIBUTE_KEY = "org.adempiere.webui.adwindow";
|
public static final String AD_WINDOW_ATTRIBUTE_KEY = "org.adempiere.webui.adwindow";
|
||||||
|
/** Content part for AD_Window (toolbar, tabbox, statusbar, etc) **/
|
||||||
private ADWindowContent windowContent;
|
private ADWindowContent windowContent;
|
||||||
|
/** Environment Context **/
|
||||||
private Properties ctx;
|
private Properties ctx;
|
||||||
|
/** AD_Window_ID **/
|
||||||
private int adWindowId;
|
private int adWindowId;
|
||||||
private String _title;
|
private String windowTitle;
|
||||||
private int windowNo;
|
private int windowNo;
|
||||||
|
|
||||||
|
/** initial query when AD Window is first open **/
|
||||||
private MQuery query;
|
private MQuery query;
|
||||||
|
/** main component of ADWindowContent **/
|
||||||
private Component windowPanelComponent;
|
private Component windowPanelComponent;
|
||||||
|
/** image for window (desktop tab) title **/
|
||||||
private MImage image;
|
private MImage image;
|
||||||
|
/** AD_Tab_ID:BtnComponentName. List of toolbar buttons to exclude, loaded from AD_ToolBarButtonRestrict **/
|
||||||
private Map<Integer, List<String>> tabToolbarRestricMap = new HashMap<Integer, List<String>>();
|
private Map<Integer, List<String>> tabToolbarRestricMap = new HashMap<Integer, List<String>>();
|
||||||
|
/** List of BtnComponentName to exclude, loaded from AD_ToolBarButtonRestrict **/
|
||||||
private List<String> windowToolbarRestrictList = null;
|
private List<String> windowToolbarRestrictList = null;
|
||||||
|
/** List of advanced (IsAdvancedButton=Y) window toolbar buttons. Accessible by advanced role only. **/
|
||||||
private List<String> windowToolbarAdvancedList = null;
|
private List<String> windowToolbarAdvancedList = null;
|
||||||
|
/** AD_Window_UU value **/
|
||||||
private String adWindowUUID;
|
private String adWindowUUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,11 +107,14 @@ public class ADWindow extends AbstractUIPart
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init ADWindowContent
|
||||||
|
*/
|
||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
windowContent = new ADWindowContent(ctx, windowNo, adWindowId);
|
windowContent = new ADWindowContent(ctx, windowNo, adWindowId);
|
||||||
windowContent.setADWindow(this);
|
windowContent.setADWindow(this);
|
||||||
_title = windowContent.getTitle();
|
windowTitle = windowContent.getTitle();
|
||||||
image = windowContent.getImage();
|
image = windowContent.getImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,18 +124,22 @@ public class ADWindow extends AbstractUIPart
|
||||||
*/
|
*/
|
||||||
public String getTitle()
|
public String getTitle()
|
||||||
{
|
{
|
||||||
return _title;
|
return windowTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return image for window title
|
||||||
* @return image for the country
|
|
||||||
*/
|
*/
|
||||||
public MImage getMImage()
|
public MImage getMImage()
|
||||||
{
|
{
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create component for content part (ADWindowContent).
|
||||||
|
* @see ADWindowContent#createPart(Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
protected Component doCreatePart(Component parent)
|
protected Component doCreatePart(Component parent)
|
||||||
{
|
{
|
||||||
windowPanelComponent = windowContent.createPart(parent);
|
windowPanelComponent = windowContent.createPart(parent);
|
||||||
|
@ -154,6 +168,10 @@ public class ADWindow extends AbstractUIPart
|
||||||
return windowContent;
|
return windowContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param AD_Tab_ID
|
||||||
|
* @return list of toolbar button to exclude/restrict for current login role
|
||||||
|
*/
|
||||||
public List<String> getTabToolbarRestrictList(int AD_Tab_ID) {
|
public List<String> getTabToolbarRestrictList(int AD_Tab_ID) {
|
||||||
List<String> tabRestrictList = tabToolbarRestricMap.get(AD_Tab_ID);
|
List<String> tabRestrictList = tabToolbarRestricMap.get(AD_Tab_ID);
|
||||||
if (tabRestrictList == null) {
|
if (tabRestrictList == null) {
|
||||||
|
@ -174,6 +192,9 @@ public class ADWindow extends AbstractUIPart
|
||||||
return tabRestrictList;
|
return tabRestrictList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list of window toolbar button to exclude/restrict for current login role
|
||||||
|
*/
|
||||||
public List<String> getWindowToolbarRestrictList() {
|
public List<String> getWindowToolbarRestrictList() {
|
||||||
if (windowToolbarRestrictList == null) {
|
if (windowToolbarRestrictList == null) {
|
||||||
//load window restriction
|
//load window restriction
|
||||||
|
@ -192,6 +213,9 @@ public class ADWindow extends AbstractUIPart
|
||||||
return windowToolbarRestrictList;
|
return windowToolbarRestrictList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list of advance (IsAdvancedButton=Y) toolbar buttons for window
|
||||||
|
*/
|
||||||
public List<String> getWindowAdvancedButtonList() {
|
public List<String> getWindowAdvancedButtonList() {
|
||||||
if (windowToolbarAdvancedList == null) {
|
if (windowToolbarAdvancedList == null) {
|
||||||
//load window advance buttons
|
//load window advance buttons
|
||||||
|
@ -207,18 +231,23 @@ public class ADWindow extends AbstractUIPart
|
||||||
return windowToolbarAdvancedList;
|
return windowToolbarAdvancedList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return AD_Window_ID
|
||||||
|
*/
|
||||||
public int getAD_Window_ID() {
|
public int getAD_Window_ID() {
|
||||||
return adWindowId;
|
return adWindowId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return AD_Window_UU
|
||||||
|
*/
|
||||||
public String getAD_Window_UU() {
|
public String getAD_Window_UU() {
|
||||||
return adWindowUUID;
|
return adWindowUUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param windowNo
|
* @param windowNo
|
||||||
* @return adwindow instance for windowNo ( if any )
|
* @return {@link ADWindow} instance for windowNo ( if any )
|
||||||
*/
|
*/
|
||||||
public static ADWindow get(int windowNo) {
|
public static ADWindow get(int windowNo) {
|
||||||
Object window = SessionManager.getAppDesktop().findWindow(windowNo);
|
Object window = SessionManager.getAppDesktop().findWindow(windowNo);
|
||||||
|
@ -229,8 +258,9 @@ public class ADWindow extends AbstractUIPart
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Find ADWindow instance that's the ancestor of comp
|
||||||
* @param comp
|
* @param comp
|
||||||
* @return adwindow instance if found, null otherwise
|
* @return {@link ADWindow} instance if found, null otherwise
|
||||||
*/
|
*/
|
||||||
public static ADWindow findADWindow(Component comp) {
|
public static ADWindow findADWindow(Component comp) {
|
||||||
Component parent = comp;
|
Component parent = comp;
|
||||||
|
|
|
@ -46,7 +46,8 @@ import org.zkoss.zul.Tab;
|
||||||
import org.zkoss.zul.Vlayout;
|
import org.zkoss.zul.Vlayout;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Content area of {@link ADWindow}.
|
||||||
|
*
|
||||||
* This class is based on org.compiere.apps.APanel written by Jorg Janke.
|
* This class is based on org.compiere.apps.APanel written by Jorg Janke.
|
||||||
* @author Jorg Janke
|
* @author Jorg Janke
|
||||||
*
|
*
|
||||||
|
@ -60,15 +61,26 @@ public class ADWindowContent extends AbstractADWindowContent
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private static final CLogger logger = CLogger.getCLogger(ADWindowContent.class);
|
private static final CLogger logger = CLogger.getCLogger(ADWindowContent.class);
|
||||||
|
|
||||||
|
/** Main layout component **/
|
||||||
private Vlayout layout;
|
private Vlayout layout;
|
||||||
|
/** Center Div of {@link #layout}, host {@link CompositeADTabbox} **/
|
||||||
private Div contentArea;
|
private Div contentArea;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ctx
|
||||||
|
* @param windowNo
|
||||||
|
* @param adWindowId
|
||||||
|
*/
|
||||||
public ADWindowContent(Properties ctx, int windowNo, int adWindowId)
|
public ADWindowContent(Properties ctx, int windowNo, int adWindowId)
|
||||||
{
|
{
|
||||||
super(ctx, windowNo, adWindowId);
|
super(ctx, windowNo, adWindowId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout UI.
|
||||||
|
* Vertical layout of toolbar, breadCrumb, statusBar and {@link #contentArea}.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
protected Component doCreatePart(Component parent)
|
protected Component doCreatePart(Component parent)
|
||||||
{
|
{
|
||||||
layout = new ADWindowVlayout(this);
|
layout = new ADWindowVlayout(this);
|
||||||
|
@ -100,6 +112,7 @@ public class ADWindowContent extends AbstractADWindowContent
|
||||||
|
|
||||||
LayoutUtils.addSclass("adwindow-status", statusBar);
|
LayoutUtils.addSclass("adwindow-status", statusBar);
|
||||||
|
|
||||||
|
//IADTabbox
|
||||||
contentArea = new Div();
|
contentArea = new Div();
|
||||||
contentArea.setParent(layout);
|
contentArea.setParent(layout);
|
||||||
ZKUpdateUtil.setVflex(contentArea, "1");
|
ZKUpdateUtil.setVflex(contentArea, "1");
|
||||||
|
@ -119,12 +132,21 @@ public class ADWindowContent extends AbstractADWindowContent
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create {@link CompositeADTabbox}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
protected IADTabbox createADTab()
|
protected IADTabbox createADTab()
|
||||||
{
|
{
|
||||||
CompositeADTabbox composite = new CompositeADTabbox();
|
CompositeADTabbox composite = new CompositeADTabbox();
|
||||||
return composite;
|
return composite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get main layout component
|
||||||
|
* @return {@link Vlayout}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
public Vlayout getComponent() {
|
public Vlayout getComponent() {
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
@ -133,6 +155,7 @@ public class ADWindowContent extends AbstractADWindowContent
|
||||||
* @param event
|
* @param event
|
||||||
* @see EventListener#onEvent(Event)
|
* @see EventListener#onEvent(Event)
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void onEvent(Event event) {
|
public void onEvent(Event event) {
|
||||||
if (Events.ON_CTRL_KEY.equals(event.getName())) {
|
if (Events.ON_CTRL_KEY.equals(event.getName())) {
|
||||||
KeyEvent keyEvent = (KeyEvent) event;
|
KeyEvent keyEvent = (KeyEvent) event;
|
||||||
|
@ -154,6 +177,9 @@ public class ADWindowContent extends AbstractADWindowContent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ITabOnCloseHandler to call {@link ADWindowContent#onExit(Callback)} when user wants to close an AD Window
|
||||||
|
*/
|
||||||
class TabOnCloseHanlder implements ITabOnCloseHandler, Callback<Boolean> {
|
class TabOnCloseHanlder implements ITabOnCloseHandler, Callback<Boolean> {
|
||||||
private Tabpanel tabPanel;
|
private Tabpanel tabPanel;
|
||||||
public void onClose(Tabpanel tabPanel) {
|
public void onClose(Tabpanel tabPanel) {
|
||||||
|
@ -170,8 +196,8 @@ public class ADWindowContent extends AbstractADWindowContent
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* close tab contain this window
|
* Close tab related to tabPanel
|
||||||
* @param tabPanel
|
* @param tabPanel Tabpanel that represent AD_Window
|
||||||
*/
|
*/
|
||||||
protected void closeTab (Tabpanel tabPanel) {
|
protected void closeTab (Tabpanel tabPanel) {
|
||||||
Tab tab = tabPanel.getLinkedTab();
|
Tab tab = tabPanel.getLinkedTab();
|
||||||
|
@ -180,6 +206,9 @@ public class ADWindowContent extends AbstractADWindowContent
|
||||||
SessionManager.getAppDesktop().unregisterWindow(getWindowNo());
|
SessionManager.getAppDesktop().unregisterWindow(getWindowNo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vlayout subclass to override onPageDetached.
|
||||||
|
*/
|
||||||
public static class ADWindowVlayout extends Vlayout implements IHelpContext {
|
public static class ADWindowVlayout extends Vlayout implements IHelpContext {
|
||||||
/**
|
/**
|
||||||
* generated serial id
|
* generated serial id
|
||||||
|
@ -192,6 +221,9 @@ public class ADWindowContent extends AbstractADWindowContent
|
||||||
this.content = content;
|
this.content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clean up listeners
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onPageDetached(Page page) {
|
public void onPageDetached(Page page) {
|
||||||
super.onPageDetached(page);
|
super.onPageDetached(page);
|
||||||
|
|
|
@ -77,7 +77,7 @@ import org.zkoss.zul.Toolbarbutton;
|
||||||
import org.zkoss.zul.impl.LabelImageElement;
|
import org.zkoss.zul.impl.LabelImageElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Toolbar of AD_Window
|
||||||
* @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a>
|
* @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a>
|
||||||
* @date Feb 25, 2007
|
* @date Feb 25, 2007
|
||||||
* @version $Revision: 0.10 $
|
* @version $Revision: 0.10 $
|
||||||
|
@ -86,21 +86,29 @@ import org.zkoss.zul.impl.LabelImageElement;
|
||||||
* <li>FR [ 2076330 ] Add new methods in CWindowToolbar class
|
* <li>FR [ 2076330 ] Add new methods in CWindowToolbar class
|
||||||
*/
|
*/
|
||||||
public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -5151981978053022864L;
|
private static final long serialVersionUID = -5151981978053022864L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute for {@link #overflowPopup} to store the last close timestamp in ms.
|
||||||
|
* Use to prevent too rapid open and close of overflow popup.
|
||||||
|
*/
|
||||||
|
private static final String POPUP_CLOSE_TIMESTAMP_ATTR = "popup.close";
|
||||||
|
|
||||||
|
/** Prefix for Button Name **/
|
||||||
public static final String BTNPREFIX = "Btn";
|
public static final String BTNPREFIX = "Btn";
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true, since = "11")
|
||||||
public static final String MNITMPREFIX = "Mnitm";
|
public static final String MNITMPREFIX = "Mnitm";
|
||||||
|
|
||||||
private static final CLogger log = CLogger.getCLogger(ADWindowToolbar.class);
|
private static final CLogger log = CLogger.getCLogger(ADWindowToolbar.class);
|
||||||
|
|
||||||
/** Search messages using translation */
|
/** translated message for new query label (default for en is "** New Query **") */
|
||||||
private String m_sNew;
|
private String m_sNew;
|
||||||
|
/** combobox to select user query **/
|
||||||
private Combobox fQueryName;
|
private Combobox fQueryName;
|
||||||
private MUserQuery[] userQueries;
|
private MUserQuery[] userQueries;
|
||||||
private MUserQuery selectedUserQuery;
|
private MUserQuery selectedUserQuery;
|
||||||
|
@ -136,25 +144,31 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
private ToolBarButton btnProcess;
|
private ToolBarButton btnProcess;
|
||||||
|
|
||||||
private ToolBarButton btnQuickForm;
|
private ToolBarButton btnQuickForm;
|
||||||
|
/** button to open overflow popup for toolbar buttons with IsShowMore=Y (for non-mobile client) **/
|
||||||
private ToolBarButton btnShowMore;
|
private ToolBarButton btnShowMore;
|
||||||
|
/** Button Name:ToolBarButton. Map for all buttons **/
|
||||||
private HashMap<String, ToolBarButton> buttons = new HashMap<String, ToolBarButton>();
|
private HashMap<String, ToolBarButton> buttons = new HashMap<String, ToolBarButton>();
|
||||||
|
/**
|
||||||
|
* For mobile client, the list of toolbar button with IsShowMore=Y is first keep here
|
||||||
|
* and move to {@link #overflows} in {@link #onOverflowButton(Event) event}
|
||||||
|
* */
|
||||||
private ArrayList<ToolBarButton> mobileShowMoreButtons = new ArrayList<ToolBarButton>();
|
private ArrayList<ToolBarButton> mobileShowMoreButtons = new ArrayList<ToolBarButton>();
|
||||||
|
/** All register toolbar listener **/
|
||||||
// private ToolBarButton btnExit;
|
|
||||||
|
|
||||||
private ArrayList<ToolbarListener> listeners = new ArrayList<ToolbarListener>();
|
private ArrayList<ToolbarListener> listeners = new ArrayList<ToolbarListener>();
|
||||||
|
|
||||||
|
/** current ON_Click event that's being handle **/
|
||||||
private Event event;
|
private Event event;
|
||||||
|
/** shortcut key map without ctrl and alt **/
|
||||||
private Map<Integer, ToolBarButton> keyMap = new HashMap<Integer, ToolBarButton>();
|
private Map<Integer, ToolBarButton> keyMap = new HashMap<Integer, ToolBarButton>();
|
||||||
|
/** alt+key shortcut map **/
|
||||||
private Map<Integer, ToolBarButton> altKeyMap = new HashMap<Integer, ToolBarButton>();
|
private Map<Integer, ToolBarButton> altKeyMap = new HashMap<Integer, ToolBarButton>();
|
||||||
|
/** ctrl+key shortcut map **/
|
||||||
private Map<Integer, ToolBarButton> ctrlKeyMap = new HashMap<Integer, ToolBarButton>();
|
private Map<Integer, ToolBarButton> ctrlKeyMap = new HashMap<Integer, ToolBarButton>();
|
||||||
|
/** list of custom toolbar button (IsCustomization=Y) **/
|
||||||
private List<ToolbarCustomButton> toolbarCustomButtons = new ArrayList<ToolbarCustomButton>();
|
private List<ToolbarCustomButton> toolbarCustomButtons = new ArrayList<ToolbarCustomButton>();
|
||||||
|
/** Restriction list for window, loaded from AD_ToolBarButtonRestrict **/
|
||||||
private List<String> restrictionList;
|
private List<String> restrictionList;
|
||||||
|
/** List of toolbar button with IsAdvanced=Y **/
|
||||||
private List<String> advancedList;
|
private List<String> advancedList;
|
||||||
|
|
||||||
// Elaine 2008/12/04
|
// Elaine 2008/12/04
|
||||||
|
@ -163,34 +177,45 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
private boolean isAllowProductInfo = MRole.getDefault().canAccess_Info_Product();
|
private boolean isAllowProductInfo = MRole.getDefault().canAccess_Info_Product();
|
||||||
|
|
||||||
private int windowNo = 0;
|
private int windowNo = 0;
|
||||||
|
/** previous key event time in ms **/
|
||||||
private long prevKeyEventTime = 0;
|
private long prevKeyEventTime = 0;
|
||||||
|
/**
|
||||||
|
* Previous key event.
|
||||||
|
* Use together with prevKeyEventTime to detect double fire of key event from browser
|
||||||
|
*/
|
||||||
private KeyEvent prevKeyEvent;
|
private KeyEvent prevKeyEvent;
|
||||||
|
|
||||||
// Maintain hierarchical Quick form by its parent-child tab while open leaf
|
/**
|
||||||
// tab once & dispose and doing same action
|
* Maintain hierarchical Quick form by its parent-child tab while open leaf
|
||||||
private int quickFormTabHrchyLevel = 0;
|
* tab once & dispose and doing same action
|
||||||
|
*/
|
||||||
private A overflowButton;
|
private int quickFormTabHrchyLevel = 0;
|
||||||
|
/** show more button for mobile client **/
|
||||||
|
private A mobileOverflowButton;
|
||||||
|
/**
|
||||||
|
* list of toolbar button overflow to show more popup (or with IsShowMore=Y).
|
||||||
|
* Use for both mobile and desktop client.
|
||||||
|
* */
|
||||||
private ArrayList<ToolBarButton> overflows;
|
private ArrayList<ToolBarButton> overflows;
|
||||||
|
/** Popup for overflow/IsShowMore=Y toolbar buttons. Use for both mobile and desktop client. **/
|
||||||
private Popup overflowPopup;
|
private Popup overflowPopup;
|
||||||
|
/** width of toolbar from previous ON_AFTER_SIZE event **/
|
||||||
private int prevWidth;
|
private int prevWidth;
|
||||||
|
/** AD Window content part that own this toolbar **/
|
||||||
private AbstractADWindowContent windowContent;
|
private AbstractADWindowContent windowContent;
|
||||||
|
|
||||||
/** Last Modifier of Action Event */
|
/**
|
||||||
// public int lastModifiers;
|
* default constructor
|
||||||
//
|
*/
|
||||||
|
|
||||||
public ADWindowToolbar()
|
public ADWindowToolbar()
|
||||||
{
|
{
|
||||||
this(null, 0);
|
this(null, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param windowContent
|
||||||
|
* @param windowNo
|
||||||
|
*/
|
||||||
public ADWindowToolbar(AbstractADWindowContent windowContent, int windowNo) {
|
public ADWindowToolbar(AbstractADWindowContent windowContent, int windowNo) {
|
||||||
this.windowContent = windowContent;
|
this.windowContent = windowContent;
|
||||||
setWindowNo(windowNo);
|
setWindowNo(windowNo);
|
||||||
|
@ -200,6 +225,9 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init components
|
||||||
|
*/
|
||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
LayoutUtils.addSclass("adwindow-toolbar", this);
|
LayoutUtils.addSclass("adwindow-toolbar", this);
|
||||||
|
@ -292,6 +320,8 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
|
|
||||||
if (!ClientInfo.isMobile())
|
if (!ClientInfo.isMobile())
|
||||||
overflows = new ArrayList<ToolBarButton>();
|
overflows = new ArrayList<ToolBarButton>();
|
||||||
|
|
||||||
|
//Window toolbar buttons from AD_ToolBarButton
|
||||||
MToolBarButton[] officialButtons = MToolBarButton.getToolbarButtons("W", null);
|
MToolBarButton[] officialButtons = MToolBarButton.getToolbarButtons("W", null);
|
||||||
for (MToolBarButton button : officialButtons) {
|
for (MToolBarButton button : officialButtons) {
|
||||||
if (!button.isActive() || !hasAccess(BTNPREFIX+button.getComponentName())) {
|
if (!button.isActive() || !hasAccess(BTNPREFIX+button.getComponentName())) {
|
||||||
|
@ -374,7 +404,13 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
ZKUpdateUtil.setWidth(this, "100%");
|
ZKUpdateUtil.setWidth(this, "100%");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new toolbar button
|
||||||
|
* @param name button name (BTNPREFIX+name)
|
||||||
|
* @param image image name (images/image+suffix) or iconSclass name (z-icon-image)
|
||||||
|
* @param tooltip
|
||||||
|
* @return {@link ToolBarButton}
|
||||||
|
*/
|
||||||
private ToolBarButton createButton(String name, String image, String tooltip)
|
private ToolBarButton createButton(String name, String image, String tooltip)
|
||||||
{
|
{
|
||||||
ToolBarButton btn = new ToolBarButton("");
|
ToolBarButton btn = new ToolBarButton("");
|
||||||
|
@ -415,11 +451,21 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
return btn;
|
return btn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get ToolBarButton by name
|
||||||
|
* @param name
|
||||||
|
* @return {@link ToolBarButton} or null
|
||||||
|
*/
|
||||||
public ToolBarButton getButton(String name)
|
public ToolBarButton getButton(String name)
|
||||||
{
|
{
|
||||||
return buttons.get(name);
|
return buttons.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get ToolBarButton by name
|
||||||
|
* @param name
|
||||||
|
* @return {@link LabelImageElement} or null
|
||||||
|
*/
|
||||||
public LabelImageElement getToolbarItem(String name)
|
public LabelImageElement getToolbarItem(String name)
|
||||||
{
|
{
|
||||||
return buttons.get(name);
|
return buttons.get(name);
|
||||||
|
@ -453,6 +499,9 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
public static final int VK_Y = 0x59;
|
public static final int VK_Y = 0x59;
|
||||||
public static final int VK_Z = 0x5A;
|
public static final int VK_Z = 0x5A;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure shortcut key for each button
|
||||||
|
*/
|
||||||
private void configureKeyMap()
|
private void configureKeyMap()
|
||||||
{
|
{
|
||||||
altKeyMap.put(VK_H, btnHelp);
|
altKeyMap.put(VK_H, btnHelp);
|
||||||
|
@ -473,6 +522,9 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
altKeyMap.put(VK_L, btnCustomize);
|
altKeyMap.put(VK_L, btnCustomize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add separator/spacer between button
|
||||||
|
*/
|
||||||
protected void addSeparator()
|
protected void addSeparator()
|
||||||
{
|
{
|
||||||
Space s = new Space();
|
Space s = new Space();
|
||||||
|
@ -481,16 +533,25 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
this.appendChild(s);
|
this.appendChild(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add ToolbarListener
|
||||||
|
* @param toolbarListener
|
||||||
|
*/
|
||||||
public void addListener(ToolbarListener toolbarListener)
|
public void addListener(ToolbarListener toolbarListener)
|
||||||
{
|
{
|
||||||
listeners.add(toolbarListener);
|
listeners.add(toolbarListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove ToolbarListener
|
||||||
|
* @param toolbarListener
|
||||||
|
*/
|
||||||
public void removeListener(ToolbarListener toolbarListener)
|
public void removeListener(ToolbarListener toolbarListener)
|
||||||
{
|
{
|
||||||
listeners.remove(toolbarListener);
|
listeners.remove(toolbarListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onEvent(Event event)
|
public void onEvent(Event event)
|
||||||
{
|
{
|
||||||
String eventName = event.getName();
|
String eventName = event.getName();
|
||||||
|
@ -547,6 +608,11 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle ON_Click event for button.
|
||||||
|
* Call register {@link ToolbarListener}.
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
private void doOnClick(Event event) {
|
private void doOnClick(Event event) {
|
||||||
this.event = event;
|
this.event = event;
|
||||||
String compName;
|
String compName;
|
||||||
|
@ -590,127 +656,216 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
this.event = null;
|
this.event = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable buttons for navigation between parent and detail tab
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableTabNavigation(boolean enabled)
|
public void enableTabNavigation(boolean enabled)
|
||||||
{
|
{
|
||||||
enableTabNavigation(enabled, enabled);
|
enableTabNavigation(enabled, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable buttons for navigation between parent and detail tab
|
||||||
|
* @param enableParent
|
||||||
|
* @param enableDetail
|
||||||
|
*/
|
||||||
public void enableTabNavigation(boolean enableParent, boolean enableDetail)
|
public void enableTabNavigation(boolean enableParent, boolean enableDetail)
|
||||||
{
|
{
|
||||||
this.btnParentRecord.setDisabled(!enableParent);
|
this.btnParentRecord.setDisabled(!enableParent);
|
||||||
this.btnDetailRecord.setDisabled(!enableDetail);
|
this.btnDetailRecord.setDisabled(!enableDetail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Refresh button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableRefresh(boolean enabled)
|
public void enableRefresh(boolean enabled)
|
||||||
{
|
{
|
||||||
this.btnRefresh.setDisabled(!enabled);
|
this.btnRefresh.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Save button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableSave(boolean enabled)
|
public void enableSave(boolean enabled)
|
||||||
{
|
{
|
||||||
this.btnSave.setDisabled(!enabled);
|
this.btnSave.setDisabled(!enabled);
|
||||||
this.btnSaveAndCreate.setDisabled(!(isNewEnabled() || isSaveEnable()));
|
this.btnSaveAndCreate.setDisabled(!(isNewEnabled() || isSaveEnable()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if Save button is enable
|
||||||
|
*/
|
||||||
public boolean isSaveEnable() {
|
public boolean isSaveEnable() {
|
||||||
return !btnSave.isDisabled();
|
return !btnSave.isDisabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void enableExit(boolean enabled)
|
/**
|
||||||
// {
|
* Enable/disable Delete button
|
||||||
// this.btnExit.setDisabled(!enabled);
|
* @param enabled
|
||||||
// }
|
*/
|
||||||
|
|
||||||
public void enableDelete(boolean enabled)
|
public void enableDelete(boolean enabled)
|
||||||
{
|
{
|
||||||
this.btnDelete.setDisabled(!enabled);
|
this.btnDelete.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if Delete button is enable
|
||||||
|
*/
|
||||||
public boolean isDeleteEnable()
|
public boolean isDeleteEnable()
|
||||||
{
|
{
|
||||||
return !btnDelete.isDisabled();
|
return !btnDelete.isDisabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if New button is enable
|
||||||
|
*/
|
||||||
public boolean isNewEnabled() {
|
public boolean isNewEnabled() {
|
||||||
return !btnNew.isDisabled();
|
return !btnNew.isDisabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Ignore/Undo button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableIgnore(boolean enabled)
|
public void enableIgnore(boolean enabled)
|
||||||
{
|
{
|
||||||
this.btnIgnore.setDisabled(!enabled);
|
this.btnIgnore.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable New button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableNew(boolean enabled)
|
public void enableNew(boolean enabled)
|
||||||
{
|
{
|
||||||
this.btnNew.setDisabled(!enabled);
|
this.btnNew.setDisabled(!enabled);
|
||||||
this.btnSaveAndCreate.setDisabled(!(isNewEnabled() || isSaveEnable()));
|
this.btnSaveAndCreate.setDisabled(!(isNewEnabled() || isSaveEnable()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Copy/Duplicate button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableCopy(boolean enabled)
|
public void enableCopy(boolean enabled)
|
||||||
{
|
{
|
||||||
this.btnCopy.setDisabled(!enabled);
|
this.btnCopy.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Attachment button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableAttachment(boolean enabled)
|
public void enableAttachment(boolean enabled)
|
||||||
{
|
{
|
||||||
this.btnAttachment.setDisabled(!enabled);
|
this.btnAttachment.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Chat button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableChat(boolean enabled)
|
public void enableChat(boolean enabled)
|
||||||
{
|
{
|
||||||
this.btnChat.setDisabled(!enabled);
|
this.btnChat.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Print button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enablePrint(boolean enabled)
|
public void enablePrint(boolean enabled)
|
||||||
{
|
{
|
||||||
this.btnPrint.setDisabled(!enabled);
|
this.btnPrint.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Report button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableReport(boolean enabled)
|
public void enableReport(boolean enabled)
|
||||||
{
|
{
|
||||||
this.btnReport.setDisabled(!enabled);
|
this.btnReport.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Find/Query button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableFind(boolean enabled)
|
public void enableFind(boolean enabled)
|
||||||
{
|
{
|
||||||
this.btnFind.setDisabled(!enabled);
|
this.btnFind.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Toggle button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableGridToggle(boolean enabled)
|
public void enableGridToggle(boolean enabled)
|
||||||
{
|
{
|
||||||
btnGridToggle.setDisabled(!enabled);
|
btnGridToggle.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Customize Grid button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableCustomize(boolean enabled)
|
public void enableCustomize(boolean enabled)
|
||||||
{
|
{
|
||||||
btnCustomize.setDisabled(!enabled);
|
btnCustomize.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Archive button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableArchive(boolean enabled)
|
public void enableArchive(boolean enabled)
|
||||||
{
|
{
|
||||||
btnArchive.setDisabled(!enabled);
|
btnArchive.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Zoom Across button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableZoomAcross(boolean enabled)
|
public void enableZoomAcross(boolean enabled)
|
||||||
{
|
{
|
||||||
btnZoomAcross.setDisabled(!enabled);
|
btnZoomAcross.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Active Workflows button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableActiveWorkflows(boolean enabled)
|
public void enableActiveWorkflows(boolean enabled)
|
||||||
{
|
{
|
||||||
btnActiveWorkflows.setDisabled(!enabled);
|
btnActiveWorkflows.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Requests button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableRequests(boolean enabled)
|
public void enableRequests(boolean enabled)
|
||||||
{
|
{
|
||||||
btnRequests.setDisabled(!enabled);
|
btnRequests.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Quick Form button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableQuickForm(boolean enabled)
|
public void enableQuickForm(boolean enabled)
|
||||||
{
|
{
|
||||||
btnQuickForm.setDisabled(!enabled);
|
btnQuickForm.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn on/off Lock button (Pressed=On, Not Pressed=Off)
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void lock(boolean locked)
|
public void lock(boolean locked)
|
||||||
{
|
{
|
||||||
setPressed("Lock", locked);
|
setPressed("Lock", locked);
|
||||||
|
@ -735,13 +890,17 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Post It Note button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enablePostIt(boolean enabled)
|
public void enablePostIt(boolean enabled)
|
||||||
{
|
{
|
||||||
this.btnPostIt.setDisabled(!enabled);
|
this.btnPostIt.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable/disable the label button
|
* Enable/disable Label record button
|
||||||
* @param enabled
|
* @param enabled
|
||||||
*/
|
*/
|
||||||
public void enableLabel(boolean enabled)
|
public void enableLabel(boolean enabled)
|
||||||
|
@ -749,11 +908,18 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
this.btnLabel.setDisabled(!enabled);
|
this.btnLabel.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ON_Click event that's being handle
|
||||||
|
*/
|
||||||
public Event getEvent()
|
public Event getEvent()
|
||||||
{
|
{
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle shortcut key event
|
||||||
|
* @param keyEvent
|
||||||
|
*/
|
||||||
private void onCtrlKeyEvent(KeyEvent keyEvent) {
|
private void onCtrlKeyEvent(KeyEvent keyEvent) {
|
||||||
if (windowContent != null && windowContent.isBlock())
|
if (windowContent != null && windowContent.isBlock())
|
||||||
return;
|
return;
|
||||||
|
@ -810,6 +976,11 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
fireButtonClickEvent(keyEvent, btn);
|
fireButtonClickEvent(keyEvent, btn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fire ON_Click event for button, trigger by shortcut key event.
|
||||||
|
* @param keyEvent source shortcut key event
|
||||||
|
* @param btn
|
||||||
|
*/
|
||||||
private void fireButtonClickEvent(KeyEvent keyEvent, ToolBarButton btn)
|
private void fireButtonClickEvent(KeyEvent keyEvent, ToolBarButton btn)
|
||||||
{
|
{
|
||||||
if (btn != null) {
|
if (btn != null) {
|
||||||
|
@ -823,7 +994,7 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Make all toolbar buttons visible
|
||||||
* @param visible
|
* @param visible
|
||||||
*/
|
*/
|
||||||
public void setVisibleAll(boolean visible)
|
public void setVisibleAll(boolean visible)
|
||||||
|
@ -835,7 +1006,6 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param buttonName
|
* @param buttonName
|
||||||
* @param visible
|
* @param visible
|
||||||
*/
|
*/
|
||||||
|
@ -849,7 +1019,6 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param windowNo
|
* @param windowNo
|
||||||
*/
|
*/
|
||||||
public void setWindowNo(int windowNo) {
|
public void setWindowNo(int windowNo) {
|
||||||
|
@ -857,7 +1026,7 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable/disable export button
|
* Enable/disable Export button
|
||||||
* @param b
|
* @param b
|
||||||
*/
|
*/
|
||||||
public void enableExport(boolean b) {
|
public void enableExport(boolean b) {
|
||||||
|
@ -866,7 +1035,7 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable/disable file import button
|
* Enable/disable File Import button
|
||||||
* @param b
|
* @param b
|
||||||
*/
|
*/
|
||||||
public void enableFileImport(boolean b) {
|
public void enableFileImport(boolean b) {
|
||||||
|
@ -875,7 +1044,7 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable/disable CSV import button
|
* Enable/disable CSV Import button
|
||||||
* @param b
|
* @param b
|
||||||
*/
|
*/
|
||||||
public void enableCSVImport(boolean b) {
|
public void enableCSVImport(boolean b) {
|
||||||
|
@ -885,6 +1054,10 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
|
|
||||||
private boolean ToolBarMenuRestictionLoaded = false;
|
private boolean ToolBarMenuRestictionLoaded = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param buttonName
|
||||||
|
* @return true if current login user has access to buttonName
|
||||||
|
*/
|
||||||
private boolean hasAccess(String buttonName) {
|
private boolean hasAccess(String buttonName) {
|
||||||
ADWindow adwindow = ADWindow.get(windowNo);
|
ADWindow adwindow = ADWindow.get(windowNo);
|
||||||
if (restrictionList == null)
|
if (restrictionList == null)
|
||||||
|
@ -904,6 +1077,9 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the accessibility state of toolbar buttons
|
||||||
|
*/
|
||||||
public void updateToolbarAccess() {
|
public void updateToolbarAccess() {
|
||||||
if (ToolBarMenuRestictionLoaded)
|
if (ToolBarMenuRestictionLoaded)
|
||||||
return;
|
return;
|
||||||
|
@ -921,19 +1097,31 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
ToolBarMenuRestictionLoaded = true;
|
ToolBarMenuRestictionLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** btnActiveWorkflow should be disabled when table has not workflow defined */
|
/**
|
||||||
boolean hasWorkflow(GridTab gridTab)
|
* btnActiveWorkflow should be disabled when table has no workflow defined
|
||||||
|
* @param gridTab
|
||||||
|
* @return true if has workflow define for gridTab
|
||||||
|
*/
|
||||||
|
protected boolean hasWorkflow(GridTab gridTab)
|
||||||
{
|
{
|
||||||
String sql = "SELECT COUNT(*) FROM AD_Workflow WHERE IsActive='Y' AND AD_Table_ID=? AND AD_Client_ID IN (0,?)";
|
String sql = "SELECT COUNT(*) FROM AD_Workflow WHERE IsActive='Y' AND AD_Table_ID=? AND AD_Client_ID IN (0,?)";
|
||||||
return (DB.getSQLValueEx(null, sql, gridTab.getAD_Table_ID(), Env.getAD_Client_ID(Env.getCtx())) > 0);
|
return (DB.getSQLValueEx(null, sql, gridTab.getAD_Table_ID(), Env.getAD_Client_ID(Env.getCtx())) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable Process button
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
public void enableProcessButton(boolean b) {
|
public void enableProcessButton(boolean b) {
|
||||||
if (btnProcess != null) {
|
if (btnProcess != null) {
|
||||||
btnProcess.setDisabled(!b);
|
btnProcess.setDisabled(!b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamic update of each toolbar button state (Check restrictions).
|
||||||
|
* For custom button, call {@link ToolbarCustomButton#dynamicDisplay()}, process pressedLogic and readOnlyLogic.
|
||||||
|
*/
|
||||||
public void dynamicDisplay() {
|
public void dynamicDisplay() {
|
||||||
List<Toolbarbutton> customButtons = new ArrayList<Toolbarbutton>();
|
List<Toolbarbutton> customButtons = new ArrayList<Toolbarbutton>();
|
||||||
for(ToolbarCustomButton toolbarCustomBtn : toolbarCustomButtons) {
|
for(ToolbarCustomButton toolbarCustomBtn : toolbarCustomButtons) {
|
||||||
|
@ -995,6 +1183,9 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
readOnlyLogic();
|
readOnlyLogic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call {@link ToolbarCustomButton#pressedLogic()}
|
||||||
|
*/
|
||||||
private void pressedLogic()
|
private void pressedLogic()
|
||||||
{
|
{
|
||||||
for (ToolbarCustomButton toolbarCustomBtn : toolbarCustomButtons)
|
for (ToolbarCustomButton toolbarCustomBtn : toolbarCustomButtons)
|
||||||
|
@ -1003,6 +1194,9 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call {@link ToolbarCustomButton#readOnlyLogic()}
|
||||||
|
*/
|
||||||
private void readOnlyLogic()
|
private void readOnlyLogic()
|
||||||
{
|
{
|
||||||
for (ToolbarCustomButton toolbarCustomBtn : toolbarCustomButtons)
|
for (ToolbarCustomButton toolbarCustomBtn : toolbarCustomButtons)
|
||||||
|
@ -1027,6 +1221,9 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init for mobile client only.
|
||||||
|
*/
|
||||||
private void mobileInit() {
|
private void mobileInit() {
|
||||||
LayoutUtils.addSclass("mobile", this);
|
LayoutUtils.addSclass("mobile", this);
|
||||||
addEventListener("onOverflowButton", evt -> onOverflowButton(evt));
|
addEventListener("onOverflowButton", evt -> onOverflowButton(evt));
|
||||||
|
@ -1064,6 +1261,9 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
addCallback(AFTER_PAGE_ATTACHED, t -> afterPageAttached());
|
addCallback(AFTER_PAGE_ATTACHED, t -> afterPageAttached());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mobile specific handling for AFTER_PAGE_ATTACHED callback.
|
||||||
|
*/
|
||||||
private void afterPageAttached() {
|
private void afterPageAttached() {
|
||||||
Component p = getParent();
|
Component p = getParent();
|
||||||
while (p != null) {
|
while (p != null) {
|
||||||
|
@ -1075,12 +1275,16 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mobile specific event handling for ON_AFTER_SIZE event.
|
||||||
|
* @param evt
|
||||||
|
*/
|
||||||
private void onAfterSize(AfterSizeEvent evt) {
|
private void onAfterSize(AfterSizeEvent evt) {
|
||||||
int width = evt.getWidth();
|
int width = evt.getWidth();
|
||||||
if (width != prevWidth) {
|
if (width != prevWidth) {
|
||||||
prevWidth = width;
|
prevWidth = width;
|
||||||
if (overflowButton != null)
|
if (mobileOverflowButton != null)
|
||||||
overflowButton.detach();
|
mobileOverflowButton.detach();
|
||||||
if (overflowPopup != null)
|
if (overflowPopup != null)
|
||||||
overflowPopup.detach();
|
overflowPopup.detach();
|
||||||
if (overflows != null) {
|
if (overflows != null) {
|
||||||
|
@ -1093,6 +1297,10 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle onOverflowButton event from mobile client.
|
||||||
|
* @param evt
|
||||||
|
*/
|
||||||
private void onOverflowButton(Event evt) {
|
private void onOverflowButton(Event evt) {
|
||||||
overflows = new ArrayList<>();
|
overflows = new ArrayList<>();
|
||||||
String uuid = (String) evt.getData();
|
String uuid = (String) evt.getData();
|
||||||
|
@ -1113,11 +1321,15 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
for (ToolBarButton toolbarButton : mobileShowMoreButtons)
|
for (ToolBarButton toolbarButton : mobileShowMoreButtons)
|
||||||
overflows.add(toolbarButton);
|
overflows.add(toolbarButton);
|
||||||
if (overflows.size() > 0) {
|
if (overflows.size() > 0) {
|
||||||
createOverflowButton();
|
createOverflowButtonForMobile();
|
||||||
populateOverflowPopup();
|
populateOverflowPopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate overflow popup.
|
||||||
|
* Use for both desktop and mobile client.
|
||||||
|
*/
|
||||||
private void populateOverflowPopup() {
|
private void populateOverflowPopup() {
|
||||||
boolean vertical = !ClientInfo.isMobile() && MSysConfig.getBooleanValue(MSysConfig.ZK_TOOLBAR_SHOW_MORE_VERTICAL, true, Env.getAD_Client_ID(Env.getCtx()));
|
boolean vertical = !ClientInfo.isMobile() && MSysConfig.getBooleanValue(MSysConfig.ZK_TOOLBAR_SHOW_MORE_VERTICAL, true, Env.getAD_Client_ID(Env.getCtx()));
|
||||||
if (vertical) {
|
if (vertical) {
|
||||||
|
@ -1164,6 +1376,10 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable show more feature for desktop client.
|
||||||
|
* Overflow for mobile client is initialise differently in {@link #mobileInit()}.
|
||||||
|
*/
|
||||||
private void enableShowMore() {
|
private void enableShowMore() {
|
||||||
this.appendChild(btnShowMore);
|
this.appendChild(btnShowMore);
|
||||||
btnShowMore.setDisabled(false);
|
btnShowMore.setDisabled(false);
|
||||||
|
@ -1173,8 +1389,12 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
populateOverflowPopup();
|
populateOverflowPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show overflow popup after {@link #btnShowMore}.
|
||||||
|
* For desktop client only.
|
||||||
|
*/
|
||||||
private void onShowMore() {
|
private void onShowMore() {
|
||||||
Long ts = (Long) overflowPopup.removeAttribute("popup.close");
|
Long ts = (Long) overflowPopup.removeAttribute(POPUP_CLOSE_TIMESTAMP_ATTR);
|
||||||
if (ts != null) {
|
if (ts != null) {
|
||||||
if (System.currentTimeMillis() - ts.longValue() < 500) {
|
if (System.currentTimeMillis() - ts.longValue() < 500) {
|
||||||
return;
|
return;
|
||||||
|
@ -1183,30 +1403,37 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
overflowPopup.open(btnShowMore, "after_end");
|
overflowPopup.open(btnShowMore, "after_end");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createOverflowButton() {
|
/**
|
||||||
overflowButton = new A();
|
* Create show more button for mobile client
|
||||||
overflowButton.setTooltiptext(Msg.getMsg(Env.getCtx(), "ShowMore"));
|
*/
|
||||||
overflowButton.setIconSclass("z-icon-ShowMore");
|
private void createOverflowButtonForMobile() {
|
||||||
overflowButton.setSclass("font-icon-toolbar-button toolbar-button mobile-overflow-link");
|
mobileOverflowButton = new A();
|
||||||
appendChild(overflowButton);
|
mobileOverflowButton.setTooltiptext(Msg.getMsg(Env.getCtx(), "ShowMore"));
|
||||||
|
mobileOverflowButton.setIconSclass("z-icon-ShowMore");
|
||||||
|
mobileOverflowButton.setSclass("font-icon-toolbar-button toolbar-button mobile-overflow-link");
|
||||||
|
appendChild(mobileOverflowButton);
|
||||||
newOverflowPopup();
|
newOverflowPopup();
|
||||||
appendChild(overflowPopup);
|
appendChild(overflowPopup);
|
||||||
overflowButton.addEventListener(Events.ON_CLICK, e -> {
|
mobileOverflowButton.addEventListener(Events.ON_CLICK, e -> {
|
||||||
Long ts = (Long) overflowPopup.removeAttribute("popup.close");
|
Long ts = (Long) overflowPopup.removeAttribute(POPUP_CLOSE_TIMESTAMP_ATTR);
|
||||||
if (ts != null) {
|
if (ts != null) {
|
||||||
if (System.currentTimeMillis() - ts.longValue() < 500) {
|
if (System.currentTimeMillis() - ts.longValue() < 500) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
overflowPopup.open(overflowButton, "after_end");
|
overflowPopup.open(mobileOverflowButton, "after_end");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create overflow popup.
|
||||||
|
* For both desktop and mobile client.
|
||||||
|
*/
|
||||||
private void newOverflowPopup() {
|
private void newOverflowPopup() {
|
||||||
overflowPopup = new Popup();
|
overflowPopup = new Popup();
|
||||||
overflowPopup.addEventListener(Events.ON_OPEN, (OpenEvent oe) -> {
|
overflowPopup.addEventListener(Events.ON_OPEN, (OpenEvent oe) -> {
|
||||||
if (!oe.isOpen()) {
|
if (!oe.isOpen()) {
|
||||||
overflowPopup.setAttribute("popup.close", System.currentTimeMillis());
|
overflowPopup.setAttribute(POPUP_CLOSE_TIMESTAMP_ATTR, System.currentTimeMillis());
|
||||||
Component[] childrens = overflowPopup.getChildren().toArray(new Component[0]);
|
Component[] childrens = overflowPopup.getChildren().toArray(new Component[0]);
|
||||||
for (Component child : childrens) {
|
for (Component child : childrens) {
|
||||||
if (child instanceof Grid || child instanceof Toolbarbutton)
|
if (child instanceof Grid || child instanceof Toolbarbutton)
|
||||||
|
@ -1217,6 +1444,10 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post after size event handler for mobile client.
|
||||||
|
* Calculate which toolbar buttons should overflow to show more popup.
|
||||||
|
*/
|
||||||
public void onPostAfterSize() {
|
public void onPostAfterSize() {
|
||||||
if (this.getPage() != null) {
|
if (this.getPage() != null) {
|
||||||
String script = "(function(){let w = zk.Widget.$('#" + getUuid() + "'); w.toolbarScrollable(w);";
|
String script = "(function(){let w = zk.Widget.$('#" + getUuid() + "'); w.toolbarScrollable(w);";
|
||||||
|
@ -1225,13 +1456,18 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set button to pressed/not pressed state
|
||||||
|
* @param buttonName
|
||||||
|
* @param pressed
|
||||||
|
*/
|
||||||
public void setPressed(String buttonName, boolean pressed) {
|
public void setPressed(String buttonName, boolean pressed) {
|
||||||
if (getButton(buttonName) != null)
|
if (getButton(buttonName) != null)
|
||||||
getButton(buttonName).setPressed(pressed);
|
getButton(buttonName).setPressed(pressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return
|
* @return parent tab level for quick form
|
||||||
*/
|
*/
|
||||||
public int getQuickFormTabHrchyLevel()
|
public int getQuickFormTabHrchyLevel()
|
||||||
{
|
{
|
||||||
|
@ -1246,6 +1482,11 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
this.quickFormTabHrchyLevel = quickFormHrchyTabLevel;
|
this.quickFormTabHrchyLevel = quickFormHrchyTabLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reload user queries and set selected item to AD_UserQuery_ID
|
||||||
|
* @param AD_Tab_ID
|
||||||
|
* @param AD_UserQuery_ID
|
||||||
|
*/
|
||||||
public void refreshUserQuery(int AD_Tab_ID, int AD_UserQuery_ID) {
|
public void refreshUserQuery(int AD_Tab_ID, int AD_UserQuery_ID) {
|
||||||
if (AEnv.getOrSetExecutionAttribute(getClass().getName()+".refreshUserQuery")) {
|
if (AEnv.getOrSetExecutionAttribute(getClass().getName()+".refreshUserQuery")) {
|
||||||
return;
|
return;
|
||||||
|
@ -1269,6 +1510,10 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
fQueryName.setSelectedIndex(0);
|
fQueryName.setSelectedIndex(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set selected user query
|
||||||
|
* @param AD_UserQuery_ID
|
||||||
|
*/
|
||||||
public void setSelectedUserQuery(int AD_UserQuery_ID) {
|
public void setSelectedUserQuery(int AD_UserQuery_ID) {
|
||||||
for (MUserQuery userQuery : userQueries) {
|
for (MUserQuery userQuery : userQueries) {
|
||||||
if (AD_UserQuery_ID == userQuery.getAD_UserQuery_ID()) {
|
if (AD_UserQuery_ID == userQuery.getAD_UserQuery_ID()) {
|
||||||
|
@ -1278,12 +1523,19 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set selected user query
|
||||||
|
* @param selectedUserQuery
|
||||||
|
*/
|
||||||
public void setSelectedUserQuery(MUserQuery selectedUserQuery) {
|
public void setSelectedUserQuery(MUserQuery selectedUserQuery) {
|
||||||
this.selectedUserQuery = selectedUserQuery;
|
this.selectedUserQuery = selectedUserQuery;
|
||||||
if (selectedUserQuery != null)
|
if (selectedUserQuery != null)
|
||||||
fQueryName.setValue(selectedUserQuery.getName());
|
fQueryName.setValue(selectedUserQuery.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return AD_UserQuery_ID of selected user query
|
||||||
|
*/
|
||||||
public int getAD_UserQuery_ID() {
|
public int getAD_UserQuery_ID() {
|
||||||
if (selectedUserQuery == null)
|
if (selectedUserQuery == null)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1291,8 +1543,8 @@ public class ADWindowToolbar extends FToolbar implements EventListener<Event>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Init Default Query in Window Toolbar
|
* Set selected user query to first default user query (if any)
|
||||||
* @return true if initialized
|
* @return true if there's a default user query
|
||||||
*/
|
*/
|
||||||
public boolean initDefaultQuery() {
|
public boolean initDefaultQuery() {
|
||||||
if(userQueries != null) {
|
if(userQueries != null) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ import org.compiere.util.Evaluator;
|
||||||
import org.compiere.util.Util;
|
import org.compiere.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Abstract model and controller for AD_Tab+AD_Field. UI part is implemented in sub class.
|
||||||
* @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a>
|
* @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a>
|
||||||
* @author <a href="mailto:hengsin@gmail.com">Low Heng Sin</a>
|
* @author <a href="mailto:hengsin@gmail.com">Low Heng Sin</a>
|
||||||
* @date Feb 25, 2007
|
* @date Feb 25, 2007
|
||||||
|
@ -46,16 +46,21 @@ public abstract class AbstractADTabbox extends AbstractUIPart implements IADTabb
|
||||||
/** List of dependent Variables */
|
/** List of dependent Variables */
|
||||||
private ArrayList<String> m_dependents = new ArrayList<String>();
|
private ArrayList<String> m_dependents = new ArrayList<String>();
|
||||||
|
|
||||||
/** Tabs associated to this tab box */
|
/** AD tab panels associated to this tab box */
|
||||||
protected List<IADTabpanel> tabPanelList = new ArrayList<IADTabpanel>();
|
protected List<IADTabpanel> tabPanelList = new ArrayList<IADTabpanel>();
|
||||||
|
/** Parent part, the content part of AD Window **/
|
||||||
protected AbstractADWindowContent adWindowPanel;
|
protected AbstractADWindowContent adWindowPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default constructor
|
||||||
|
*/
|
||||||
public AbstractADTabbox()
|
public AbstractADTabbox()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add Tab
|
* Add new tab(AD_Tab).
|
||||||
|
* Delegate to {@link #doAddTab(GridTab, IADTabpanel)}
|
||||||
* @param gTab grid tab model
|
* @param gTab grid tab model
|
||||||
* @param tabPanel
|
* @param tabPanel
|
||||||
*/
|
*/
|
||||||
|
@ -76,7 +81,8 @@ public abstract class AbstractADTabbox extends AbstractUIPart implements IADTabb
|
||||||
}// addTab
|
}// addTab
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* handle add tab to tabbox
|
* Handle add new tab to UI.
|
||||||
|
* Override to implement add new tab to UI.
|
||||||
* @param tab
|
* @param tab
|
||||||
* @param tabPanel
|
* @param tabPanel
|
||||||
*/
|
*/
|
||||||
|
@ -84,19 +90,24 @@ public abstract class AbstractADTabbox extends AbstractUIPart implements IADTabb
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param index of tab panel
|
* @param index of tab panel
|
||||||
* @return true if enable
|
* @return true if enable, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean isEnabledAt(int index)
|
public boolean isEnabledAt(int index)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}// isEnabledAt
|
}// isEnabledAt
|
||||||
|
|
||||||
private boolean isDisplay(IADTabpanel newTab)
|
/**
|
||||||
|
* Evaluate display logic
|
||||||
|
* @param tabPanel
|
||||||
|
* @return true if visible, false otherwise
|
||||||
|
*/
|
||||||
|
private boolean isDisplay(IADTabpanel tabPanel)
|
||||||
{
|
{
|
||||||
String logic = newTab.getDisplayLogic();
|
String logic = tabPanel.getDisplayLogic();
|
||||||
if (logic != null && logic.length() > 0)
|
if (logic != null && logic.length() > 0)
|
||||||
{
|
{
|
||||||
boolean display = Evaluator.evaluateLogic(newTab, logic);
|
boolean display = Evaluator.evaluateLogic(tabPanel, logic);
|
||||||
if (!display)
|
if (!display)
|
||||||
{
|
{
|
||||||
log.info("Not displayed - " + logic);
|
log.info("Not displayed - " + logic);
|
||||||
|
@ -107,11 +118,13 @@ public abstract class AbstractADTabbox extends AbstractUIPart implements IADTabb
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updated selected tab index
|
* Change selected tab index from oldIndex to newIndex.
|
||||||
|
* Delegate to {@link #doTabSelectionChanged(int, int)}.
|
||||||
* @param oldIndex
|
* @param oldIndex
|
||||||
* @param newIndex
|
* @param newIndex
|
||||||
* @return true if successfully switch to newIndex
|
* @return true if successfully switch to newIndex
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean updateSelectedIndex(int oldIndex, int newIndex)
|
public boolean updateSelectedIndex(int oldIndex, int newIndex)
|
||||||
{
|
{
|
||||||
IADTabpanel newTab = tabPanelList.get(newIndex);
|
IADTabpanel newTab = tabPanelList.get(newIndex);
|
||||||
|
@ -136,6 +149,11 @@ public abstract class AbstractADTabbox extends AbstractUIPart implements IADTabb
|
||||||
return canJump;
|
return canJump;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare environment context for newTab.
|
||||||
|
* @param newIndex
|
||||||
|
* @param newTab
|
||||||
|
*/
|
||||||
private void prepareContext(int newIndex, IADTabpanel newTab) {
|
private void prepareContext(int newIndex, IADTabpanel newTab) {
|
||||||
//update context
|
//update context
|
||||||
if (newTab != null)
|
if (newTab != null)
|
||||||
|
@ -192,15 +210,17 @@ public abstract class AbstractADTabbox extends AbstractUIPart implements IADTabb
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* handle tab selection changed event
|
* Handle tab selection change event.
|
||||||
|
* Override to update UI for tab selection change.
|
||||||
* @param oldIndex
|
* @param oldIndex
|
||||||
* @param newIndex
|
* @param newIndex
|
||||||
*/
|
*/
|
||||||
protected abstract void doTabSelectionChanged(int oldIndex, int newIndex);
|
protected abstract void doTabSelectionChanged(int oldIndex, int newIndex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param index tab index
|
* Evaluate display logic
|
||||||
* @return true if tab is visible
|
* @param index
|
||||||
|
* @return true if visible, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean isDisplay(int index) {
|
public boolean isDisplay(int index) {
|
||||||
if (index >= tabPanelList.size())
|
if (index >= tabPanelList.size())
|
||||||
|
@ -218,21 +238,23 @@ public abstract class AbstractADTabbox extends AbstractUIPart implements IADTabb
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Delegate to {@link #canNavigateTo(int, int, boolean)}
|
||||||
* @param fromIndex
|
* @param fromIndex
|
||||||
* @param toIndex
|
* @param toIndex
|
||||||
* @return true if can navigate to toIndex
|
* @return true if can change selected tab from fromIndex to toIndex
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean canNavigateTo(int fromIndex, int toIndex) {
|
public boolean canNavigateTo(int fromIndex, int toIndex) {
|
||||||
return canNavigateTo(fromIndex, toIndex, false);
|
return canNavigateTo(fromIndex, toIndex, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param fromIndex
|
* @param fromIndex
|
||||||
* @param toIndex
|
* @param toIndex
|
||||||
* @param checkRecordID true to validate record id of fromIndex tab
|
* @param checkRecordID true to validate fromIndex has a valid record id
|
||||||
* @return true if can navigate to toIndex tab
|
* @return true if can change selected tab from fromIndex to toIndex
|
||||||
*/
|
*/
|
||||||
public boolean canNavigateTo(int fromIndex, int toIndex, boolean checkRecordID) {
|
public boolean canNavigateTo(int fromIndex, int toIndex, boolean checkRecordID) {
|
||||||
IADTabpanel newTab = tabPanelList.get(toIndex);
|
IADTabpanel newTab = tabPanelList.get(toIndex);
|
||||||
if (newTab instanceof ADTabpanel)
|
if (newTab instanceof ADTabpanel)
|
||||||
|
@ -281,7 +303,7 @@ public abstract class AbstractADTabbox extends AbstractUIPart implements IADTabb
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Get break crumb path
|
||||||
* @return full path
|
* @return full path
|
||||||
*/
|
*/
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
|
@ -310,7 +332,8 @@ public abstract class AbstractADTabbox extends AbstractUIPart implements IADTabb
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluate Tab Logic
|
* Handle DataStatusEvent.
|
||||||
|
* Delegate to {@link #updateTabState()}.
|
||||||
* @param e event
|
* @param e event
|
||||||
*/
|
*/
|
||||||
public void evaluate (DataStatusEvent e)
|
public void evaluate (DataStatusEvent e)
|
||||||
|
@ -335,7 +358,7 @@ public abstract class AbstractADTabbox extends AbstractUIPart implements IADTabb
|
||||||
} // evaluate
|
} // evaluate
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update display state of tab (visibility, activation and if need invalidate)
|
* Update UI state of tab (visibility, activation and if need invalidate)
|
||||||
*/
|
*/
|
||||||
protected abstract void updateTabState();
|
protected abstract void updateTabState();
|
||||||
|
|
||||||
|
@ -366,8 +389,10 @@ public abstract class AbstractADTabbox extends AbstractUIPart implements IADTabb
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set newIndex as selected tab
|
* Set newIndex as selected tab
|
||||||
|
* Delegate to {@link #updateSelectedIndex(int, int)}
|
||||||
* @param newIndex
|
* @param newIndex
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void setSelectedIndex(int newIndex) {
|
public void setSelectedIndex(int newIndex) {
|
||||||
int oldIndex = getSelectedIndex();
|
int oldIndex = getSelectedIndex();
|
||||||
updateSelectedIndex(oldIndex, newIndex);
|
updateSelectedIndex(oldIndex, newIndex);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -52,13 +52,20 @@ import org.zkoss.zul.Menuitem;
|
||||||
import org.zkoss.zul.Window;
|
import org.zkoss.zul.Window;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Bread crumb component for AD Window
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class BreadCrumb extends Div implements EventListener<Event> {
|
public class BreadCrumb extends Div implements EventListener<Event> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event echo after ON_MOUSE_OVER event.
|
||||||
|
*/
|
||||||
private static final String ON_MOUSE_OVER_ECHO_EVENT = "onMouseOverEcho";
|
private static final String ON_MOUSE_OVER_ECHO_EVENT = "onMouseOverEcho";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is echo after some delay after ON_MOUSE_OUT event (to close linkPopup).
|
||||||
|
* Also use as attribute to allow a rapid ON_MOUSE_OVER event to cancel the delay ON_MOUSE_OUT_ECHO_EVENT, thus keeping linkPopup open.
|
||||||
|
**/
|
||||||
private static final String ON_MOUSE_OUT_ECHO_EVENT = "onMouseOutEcho";
|
private static final String ON_MOUSE_OUT_ECHO_EVENT = "onMouseOutEcho";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,29 +75,39 @@ public class BreadCrumb extends Div implements EventListener<Event> {
|
||||||
|
|
||||||
private static final String BTNPREFIX = "Btn";
|
private static final String BTNPREFIX = "Btn";
|
||||||
|
|
||||||
|
/** west layout for paths to a tab (for e.g "Business Partner > Location") **/
|
||||||
private Hlayout layout;
|
private Hlayout layout;
|
||||||
|
|
||||||
|
/** record navigation buttons **/
|
||||||
private ToolBarButton btnFirst, btnPrevious, btnNext, btnLast, btnRecordInfo;
|
private ToolBarButton btnFirst, btnPrevious, btnNext, btnLast, btnRecordInfo;
|
||||||
|
|
||||||
|
/** Label:TabIndex. Link to other tabs at same level (i.e other child tabs of the same parent tab). **/
|
||||||
private LinkedHashMap<String, String> links;
|
private LinkedHashMap<String, String> links;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private int windowNo;
|
private int windowNo;
|
||||||
|
|
||||||
|
/** BtnName:ToolBarButton. Map of all toolbar buttons. **/
|
||||||
private HashMap<String, ToolBarButton> buttons = new HashMap<String, ToolBarButton>();
|
private HashMap<String, ToolBarButton> buttons = new HashMap<String, ToolBarButton>();
|
||||||
|
|
||||||
|
/** Last DataStatusEvent from {@link AbstractADWindowContent#dataStatusChanged(DataStatusEvent)} **/
|
||||||
private DataStatusEvent m_dse;
|
private DataStatusEvent m_dse;
|
||||||
|
|
||||||
|
/** Last data status text from {@link AbstractADWindowContent#dataStatusChanged(DataStatusEvent)} **/
|
||||||
private String m_text;
|
private String m_text;
|
||||||
|
|
||||||
|
/** register ToolbarListener **/
|
||||||
private ToolbarListener toolbarListener;
|
private ToolbarListener toolbarListener;
|
||||||
|
|
||||||
|
/** east layout for record navigation buttons **/
|
||||||
private Hlayout toolbarContainer;
|
private Hlayout toolbarContainer;
|
||||||
|
|
||||||
|
/** popup for link to other tabs at same level **/
|
||||||
protected Menupopup linkPopup;
|
protected Menupopup linkPopup;
|
||||||
|
|
||||||
private GridTab m_gridTab;
|
private GridTab m_gridTab;
|
||||||
|
|
||||||
|
/** AD Window content part that own this bread crumb **/
|
||||||
private AbstractADWindowContent windowContent;
|
private AbstractADWindowContent windowContent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -140,7 +157,6 @@ public class BreadCrumb extends Div implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param listener
|
* @param listener
|
||||||
*/
|
*/
|
||||||
public void setToolbarListener(ToolbarListener listener) {
|
public void setToolbarListener(ToolbarListener listener) {
|
||||||
|
@ -148,10 +164,10 @@ public class BreadCrumb extends Div implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Add path to tab
|
||||||
* @param label
|
* @param label path label
|
||||||
* @param id
|
* @param id path id
|
||||||
* @param clickable
|
* @param clickable true to add clickable {@link BreadCrumbLink} false to add text label
|
||||||
*/
|
*/
|
||||||
public void addPath(String label, String id, boolean clickable) {
|
public void addPath(String label, String id, boolean clickable) {
|
||||||
if (clickable) {
|
if (clickable) {
|
||||||
|
@ -181,7 +197,7 @@ public class BreadCrumb extends Div implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Get parent BreadCrumbLinks
|
||||||
* @return list of parent links
|
* @return list of parent links
|
||||||
*/
|
*/
|
||||||
public List<BreadCrumbLink> getParentLinks() {
|
public List<BreadCrumbLink> getParentLinks() {
|
||||||
|
@ -195,7 +211,7 @@ public class BreadCrumb extends Div implements EventListener<Event> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add links to other tabs at the same level
|
* add links to other tabs at the same level
|
||||||
* @param links
|
* @param links Label:TabIndex map
|
||||||
*/
|
*/
|
||||||
public void addLinks(LinkedHashMap<String, String> links) {
|
public void addLinks(LinkedHashMap<String, String> links) {
|
||||||
this.links = links;
|
this.links = links;
|
||||||
|
@ -368,7 +384,7 @@ public class BreadCrumb extends Div implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove all links
|
* remove all path and links
|
||||||
*/
|
*/
|
||||||
public void reset() {
|
public void reset() {
|
||||||
layout.getChildren().clear();
|
layout.getChildren().clear();
|
||||||
|
@ -395,6 +411,13 @@ public class BreadCrumb extends Div implements EventListener<Event> {
|
||||||
this.btnNext.setDisabled(!enabled);
|
this.btnNext.setDisabled(!enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create toolbar button.
|
||||||
|
* @param name
|
||||||
|
* @param image
|
||||||
|
* @param tooltip
|
||||||
|
* @return {@link ToolBarButton}
|
||||||
|
*/
|
||||||
private ToolBarButton createButton(String name, String image, String tooltip)
|
private ToolBarButton createButton(String name, String image, String tooltip)
|
||||||
{
|
{
|
||||||
ToolBarButton btn = new ToolBarButton("");
|
ToolBarButton btn = new ToolBarButton("");
|
||||||
|
@ -425,6 +448,7 @@ public class BreadCrumb extends Div implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Set record info text
|
||||||
* @param text
|
* @param text
|
||||||
*/
|
*/
|
||||||
public void setStatusDB (String text)
|
public void setStatusDB (String text)
|
||||||
|
@ -433,7 +457,8 @@ public class BreadCrumb extends Div implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param text
|
* Data status from {@link AbstractADWindowContent#dataStatusChanged(DataStatusEvent)}
|
||||||
|
* @param text record info text (for e.g 1/1)
|
||||||
* @param dse
|
* @param dse
|
||||||
* @param gridTab
|
* @param gridTab
|
||||||
*/
|
*/
|
||||||
|
@ -471,7 +496,7 @@ public class BreadCrumb extends Div implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Set visibility of record navigation toolbar
|
||||||
* @param visible
|
* @param visible
|
||||||
*/
|
*/
|
||||||
public void setNavigationToolbarVisibility(boolean visible) {
|
public void setNavigationToolbarVisibility(boolean visible) {
|
||||||
|
@ -498,22 +523,37 @@ public class BreadCrumb extends Div implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if previous button is enable
|
||||||
|
*/
|
||||||
public boolean isPreviousEnabled() {
|
public boolean isPreviousEnabled() {
|
||||||
return !btnPrevious.isDisabled();
|
return !btnPrevious.isDisabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if next button is enable
|
||||||
|
*/
|
||||||
public boolean isNextEnabled() {
|
public boolean isNextEnabled() {
|
||||||
return !btnNext.isDisabled();
|
return !btnNext.isDisabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return next ToolBarButton
|
||||||
|
*/
|
||||||
public ToolBarButton getNextButton() {
|
public ToolBarButton getNextButton() {
|
||||||
return btnNext;
|
return btnNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return previous ToolBarButton
|
||||||
|
*/
|
||||||
public ToolBarButton getPreviousButton() {
|
public ToolBarButton getPreviousButton() {
|
||||||
return btnPrevious;
|
return btnPrevious;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if path/link is empty
|
||||||
|
*/
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return layout == null || layout.getChildren().isEmpty();
|
return layout == null || layout.getChildren().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,8 @@ package org.adempiere.webui.adwindow;
|
||||||
import org.zkoss.zul.A;
|
import org.zkoss.zul.A;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Link component for {@link BreadCrumb}
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class BreadCrumbLink extends A {
|
public class BreadCrumbLink extends A {
|
||||||
|
|
||||||
|
@ -26,12 +26,19 @@ public class BreadCrumbLink extends A {
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 170361731431877695L;
|
private static final long serialVersionUID = 170361731431877695L;
|
||||||
|
|
||||||
|
/** id for path (tab index) **/
|
||||||
private String pathId;
|
private String pathId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return path id
|
||||||
|
*/
|
||||||
public String getPathId() {
|
public String getPathId() {
|
||||||
return pathId;
|
return pathId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param pathId
|
||||||
|
*/
|
||||||
public void setPathId(String pathId) {
|
public void setPathId(String pathId) {
|
||||||
this.pathId = pathId;
|
this.pathId = pathId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,10 @@ import org.zkoss.zul.RowRenderer;
|
||||||
import org.zkoss.zul.Vlayout;
|
import org.zkoss.zul.Vlayout;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Header and detail UI for AD_Tabs.
|
||||||
|
* This class manage a list of tabs with the current selected tab as the attached and visible {@link ADTabpanel} instance.
|
||||||
|
* Child tabs of selected tab is shown in {@link DetailPane} inside {@link ADTabpanel}.
|
||||||
|
*
|
||||||
* @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a>
|
* @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a>
|
||||||
* @author <a href="mailto:hengsin@gmail.com">Low Heng Sin</a>
|
* @author <a href="mailto:hengsin@gmail.com">Low Heng Sin</a>
|
||||||
* @date Feb 25, 2007
|
* @date Feb 25, 2007
|
||||||
|
@ -63,27 +66,45 @@ import org.zkoss.zul.Vlayout;
|
||||||
*/
|
*/
|
||||||
public class CompositeADTabbox extends AbstractADTabbox
|
public class CompositeADTabbox extends AbstractADTabbox
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* DetailPane attribute to hold list of child tabs.
|
||||||
|
* List of Object[] of tabIndex, tabPanel, tabLabel, enable.
|
||||||
|
*/
|
||||||
|
private static final String DETAILPANE_TABLIST_ATTR = "detailpane.tablist";
|
||||||
|
|
||||||
|
/** Execution attribute to hold reference to detail ADTabpanel that's handling onEditDetail event **/
|
||||||
public static final String AD_TABBOX_ON_EDIT_DETAIL_ATTRIBUTE = "ADTabbox.onEditDetail";
|
public static final String AD_TABBOX_ON_EDIT_DETAIL_ATTRIBUTE = "ADTabbox.onEditDetail";
|
||||||
|
|
||||||
|
/** after tab selection change event **/
|
||||||
private static final String ON_POST_TAB_SELECTION_CHANGED_EVENT = "onPostTabSelectionChanged";
|
private static final String ON_POST_TAB_SELECTION_CHANGED_EVENT = "onPostTabSelectionChanged";
|
||||||
|
|
||||||
|
/** event echo from ON_POST_TAB_SELECTION_CHANGED_EVENT handler **/
|
||||||
private static final String ON_TAB_SELECTION_CHANGED_ECHO_EVENT = "onTabSelectionChangedEcho";
|
private static final String ON_TAB_SELECTION_CHANGED_ECHO_EVENT = "onTabSelectionChangedEcho";
|
||||||
|
|
||||||
|
/** tab selection change event **/
|
||||||
public static final String ON_SELECTION_CHANGED_EVENT = "onSelectionChanged";
|
public static final String ON_SELECTION_CHANGED_EVENT = "onSelectionChanged";
|
||||||
|
|
||||||
|
/** List of all tab **/
|
||||||
private List<ADTabListModel.ADTabLabel> tabLabelList = new ArrayList<ADTabListModel.ADTabLabel>();
|
private List<ADTabListModel.ADTabLabel> tabLabelList = new ArrayList<ADTabListModel.ADTabLabel>();
|
||||||
|
|
||||||
|
/** List of all tab panel **/
|
||||||
private List<IADTabpanel> tabPanelList = new ArrayList<IADTabpanel>();
|
private List<IADTabpanel> tabPanelList = new ArrayList<IADTabpanel>();
|
||||||
|
|
||||||
|
/** main layout component **/
|
||||||
private Vlayout layout;
|
private Vlayout layout;
|
||||||
|
|
||||||
|
/** tab selection change listener **/
|
||||||
private EventListener<Event> selectionListener;
|
private EventListener<Event> selectionListener;
|
||||||
|
|
||||||
|
/** {@link IADTabpanel} instance for selected tab **/
|
||||||
private IADTabpanel headerTab;
|
private IADTabpanel headerTab;
|
||||||
|
|
||||||
|
/** Index of selected tab **/
|
||||||
private int selectedIndex = 0;
|
private int selectedIndex = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default constructor
|
||||||
|
*/
|
||||||
public CompositeADTabbox(){
|
public CompositeADTabbox(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,6 +242,9 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete current row of selected detail tab
|
||||||
|
*/
|
||||||
private void onDelete() {
|
private void onDelete() {
|
||||||
if (headerTab.getGridTab().isNew()) return;
|
if (headerTab.getGridTab().isNew()) return;
|
||||||
|
|
||||||
|
@ -245,6 +269,10 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete selected rows of selected detail tab
|
||||||
|
* @param tabPanel
|
||||||
|
*/
|
||||||
private void onDeleteSelected(final IADTabpanel tabPanel) {
|
private void onDeleteSelected(final IADTabpanel tabPanel) {
|
||||||
if (tabPanel == null || tabPanel.getGridTab() == null) return;
|
if (tabPanel == null || tabPanel.getGridTab() == null) return;
|
||||||
|
|
||||||
|
@ -283,6 +311,10 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
return detailPane;
|
return detailPane;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* defer execution of adTabPanel.focus()
|
||||||
|
* @param adTabPanel
|
||||||
|
*/
|
||||||
private void focusToTabpanel(IADTabpanel adTabPanel ) {
|
private void focusToTabpanel(IADTabpanel adTabPanel ) {
|
||||||
if (adTabPanel != null && adTabPanel instanceof HtmlBasedComponent) {
|
if (adTabPanel != null && adTabPanel instanceof HtmlBasedComponent) {
|
||||||
final HtmlBasedComponent comp = (HtmlBasedComponent) adTabPanel;
|
final HtmlBasedComponent comp = (HtmlBasedComponent) adTabPanel;
|
||||||
|
@ -291,7 +323,8 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edit selected detail tab
|
* Edit current row of selected detail tab.
|
||||||
|
* Make selected detail tab the new header tab.
|
||||||
* @param row
|
* @param row
|
||||||
* @param formView
|
* @param formView
|
||||||
*/
|
*/
|
||||||
|
@ -328,6 +361,10 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create layout and setup listeners for bread crumb.
|
||||||
|
* Vertical layout with {@link ADTabpanel} as the only child component.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Component doCreatePart(Component parent)
|
protected Component doCreatePart(Component parent)
|
||||||
{
|
{
|
||||||
|
@ -359,8 +396,9 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
breadCrumb.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
|
breadCrumb.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(Event event) throws Exception {
|
public void onEvent(Event event) throws Exception {
|
||||||
|
//send tab selection change event
|
||||||
int oldIndex = selectedIndex;
|
int oldIndex = selectedIndex;
|
||||||
if (event.getTarget() instanceof BreadCrumbLink) {
|
if (event.getTarget() instanceof BreadCrumbLink) {
|
||||||
BreadCrumbLink link = (BreadCrumbLink) event.getTarget();
|
BreadCrumbLink link = (BreadCrumbLink) event.getTarget();
|
||||||
int newIndex = Integer.parseInt(link.getPathId());
|
int newIndex = Integer.parseInt(link.getPathId());
|
||||||
|
|
||||||
|
@ -381,8 +419,8 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doAddTab(GridTab gTab, IADTabpanel tabPanel) {
|
protected void doAddTab(GridTab gTab, IADTabpanel tabPanel) {
|
||||||
ADTabListModel.ADTabLabel tabLabel = new ADTabListModel.ADTabLabel(gTab.getName(), gTab.getTabLevel(),gTab.getDescription(),
|
ADTabListModel.ADTabLabel tabLabel = new ADTabListModel.ADTabLabel(gTab.getName(), gTab.getTabLevel(), gTab.getDescription(),
|
||||||
gTab.getWindowNo(),gTab.getAD_Tab_ID());
|
gTab.getWindowNo(), gTab.getAD_Tab_ID());
|
||||||
tabLabelList.add(tabLabel);
|
tabLabelList.add(tabLabel);
|
||||||
tabPanelList.add(tabPanel);
|
tabPanelList.add(tabPanel);
|
||||||
|
|
||||||
|
@ -480,6 +518,7 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//add to header or detail pane
|
||||||
if (layout.getChildren().isEmpty()) {
|
if (layout.getChildren().isEmpty()) {
|
||||||
layout.appendChild(tabPanel);
|
layout.appendChild(tabPanel);
|
||||||
headerTab = tabPanel;
|
headerTab = tabPanel;
|
||||||
|
@ -516,6 +555,9 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call {@link ADTabpanel#activateDetailIfVisible()}
|
||||||
|
*/
|
||||||
private void activateDetailIfVisible() {
|
private void activateDetailIfVisible() {
|
||||||
if (headerTab instanceof ADTabpanel) {
|
if (headerTab instanceof ADTabpanel) {
|
||||||
((ADTabpanel)headerTab).activateDetailIfVisible();
|
((ADTabpanel)headerTab).activateDetailIfVisible();
|
||||||
|
@ -595,7 +637,7 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
|
|
||||||
//set state
|
//set state
|
||||||
headerTab.setDetailPaneMode(false);
|
headerTab.setDetailPaneMode(false);
|
||||||
//show empty path, update later with actual path in onTabSelectionChangedEcho
|
//show empty path, update later with actual path in onPostTabSelectionChanged
|
||||||
getBreadCrumb().getFirstChild().getChildren().clear();
|
getBreadCrumb().getFirstChild().getChildren().clear();
|
||||||
getBreadCrumb().getFirstChild().appendChild(new Label(""));
|
getBreadCrumb().getFirstChild().appendChild(new Label(""));
|
||||||
|
|
||||||
|
@ -603,11 +645,13 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* first after tab selection change event, follow by onTabSelectionChangedEcho event
|
* Handle after tab selection change event, echo onTabSelectionChangedEcho event.
|
||||||
* @param back
|
* @param back
|
||||||
*/
|
*/
|
||||||
private void onPostTabSelectionChanged(Boolean back) {
|
private void onPostTabSelectionChanged(Boolean back) {
|
||||||
if (headerTab instanceof ADTabpanel && !headerTab.getGridTab().isSortTab()) {
|
if (headerTab instanceof ADTabpanel && !headerTab.getGridTab().isSortTab()) {
|
||||||
|
//gather all child tabs (both immediate and not immediate)
|
||||||
|
//Object[]: tabIndex, tabPanel, tabLabel, enable
|
||||||
List<Object[]> list = new ArrayList<Object[]>();
|
List<Object[]> list = new ArrayList<Object[]>();
|
||||||
int tabIndex = -1;
|
int tabIndex = -1;
|
||||||
int currentLevel = headerTab.getTabLevel();
|
int currentLevel = headerTab.getTabLevel();
|
||||||
|
@ -633,7 +677,7 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
if (detailPane == null) {
|
if (detailPane == null) {
|
||||||
detailPane = createDetailPane();
|
detailPane = createDetailPane();
|
||||||
}
|
}
|
||||||
detailPane.setAttribute("detailpane.tablist", list);
|
detailPane.setAttribute(DETAILPANE_TABLIST_ATTR, list);
|
||||||
|
|
||||||
ZKUpdateUtil.setVflex(detailPane, "true");
|
ZKUpdateUtil.setVflex(detailPane, "true");
|
||||||
if (headerTab.getDetailPane() == null) {
|
if (headerTab.getDetailPane() == null) {
|
||||||
|
@ -658,7 +702,8 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
//setup tabs of detail pane
|
//setup tabs of detail pane
|
||||||
if (detailPane != null) {
|
if (detailPane != null) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
List<Object[]> list = (List<Object[]>) detailPane.removeAttribute("detailpane.tablist");
|
//tabIndex, tabPanel, tabLabel, enable
|
||||||
|
List<Object[]> list = (List<Object[]>) detailPane.removeAttribute(DETAILPANE_TABLIST_ATTR);
|
||||||
if (list != null && !list.isEmpty()) {
|
if (list != null && !list.isEmpty()) {
|
||||||
int currentLevel = headerTab.getTabLevel();
|
int currentLevel = headerTab.getTabLevel();
|
||||||
for (Object[] value : list) {
|
for (Object[] value : list) {
|
||||||
|
@ -747,6 +792,7 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
private void updateBreadCrumb() {
|
private void updateBreadCrumb() {
|
||||||
BreadCrumb breadCrumb = getBreadCrumb();
|
BreadCrumb breadCrumb = getBreadCrumb();
|
||||||
breadCrumb.reset();
|
breadCrumb.reset();
|
||||||
|
//add parent path
|
||||||
if (selectedIndex > 0) {
|
if (selectedIndex > 0) {
|
||||||
List<ADTabLabel> parents = new ArrayList<ADTabListModel.ADTabLabel>();
|
List<ADTabLabel> parents = new ArrayList<ADTabListModel.ADTabLabel>();
|
||||||
List<Integer> parentIndex = new ArrayList<Integer>();
|
List<Integer> parentIndex = new ArrayList<Integer>();
|
||||||
|
@ -771,6 +817,8 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
if (!breadCrumb.isVisible())
|
if (!breadCrumb.isVisible())
|
||||||
breadCrumb.setVisible(true);
|
breadCrumb.setVisible(true);
|
||||||
|
|
||||||
|
//Links for other child tabs at same level
|
||||||
|
//Tab Index:Tab Label
|
||||||
LinkedHashMap<String, String> links = new LinkedHashMap<String, String>();
|
LinkedHashMap<String, String> links = new LinkedHashMap<String, String>();
|
||||||
int parentIndex = 0;
|
int parentIndex = 0;
|
||||||
if (headerTab.getTabLevel() > 1) {
|
if (headerTab.getTabLevel() > 1) {
|
||||||
|
@ -823,6 +871,9 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link BreadCrumb}
|
||||||
|
*/
|
||||||
private BreadCrumb getBreadCrumb() {
|
private BreadCrumb getBreadCrumb() {
|
||||||
ADWindowContent window = (ADWindowContent) adWindowPanel;
|
ADWindowContent window = (ADWindowContent) adWindowPanel;
|
||||||
BreadCrumb breadCrumb = window.getBreadCrumb();
|
BreadCrumb breadCrumb = window.getBreadCrumb();
|
||||||
|
@ -844,6 +895,9 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify selected detail tab after data status change of header tab
|
||||||
|
*/
|
||||||
class SyncDataStatusListener implements DataStatusListener {
|
class SyncDataStatusListener implements DataStatusListener {
|
||||||
|
|
||||||
private IADTabpanel tabPanel;
|
private IADTabpanel tabPanel;
|
||||||
|
@ -867,7 +921,7 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
|
|
||||||
IADTabpanel detailTab = getSelectedDetailADTabpanel();
|
IADTabpanel detailTab = getSelectedDetailADTabpanel();
|
||||||
if (detailTab != null) {
|
if (detailTab != null) {
|
||||||
//check data action
|
//check is data action from detail tab
|
||||||
String uuid = (String) execution.getAttribute(CompositeADTabbox.class.getName()+".dataAction");
|
String uuid = (String) execution.getAttribute(CompositeADTabbox.class.getName()+".dataAction");
|
||||||
if (uuid != null && uuid.equals(detailTab.getUuid()) && detailTab.getGridTab().isCurrent()) {
|
if (uuid != null && uuid.equals(detailTab.getUuid()) && detailTab.getGridTab().isCurrent()) {
|
||||||
//refresh current row
|
//refresh current row
|
||||||
|
@ -909,7 +963,6 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @return true if selected detail tab have been activated
|
* @return true if selected detail tab have been activated
|
||||||
*/
|
*/
|
||||||
public boolean isDetailActivated() {
|
public boolean isDetailActivated() {
|
||||||
|
@ -1074,6 +1127,10 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* force invalidate of tabPanel
|
||||||
|
* @param tabPanel
|
||||||
|
*/
|
||||||
private void invalidateTabPanel(IADTabpanel tabPanel) {
|
private void invalidateTabPanel(IADTabpanel tabPanel) {
|
||||||
Center center = findCenter(tabPanel.getGridView());
|
Center center = findCenter(tabPanel.getGridView());
|
||||||
if (center != null)
|
if (center != null)
|
||||||
|
@ -1082,6 +1139,11 @@ public class CompositeADTabbox extends AbstractADTabbox
|
||||||
tabPanel.invalidate();
|
tabPanel.invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find {@link Center} that own gridView
|
||||||
|
* @param gridView
|
||||||
|
* @return {@link Center}
|
||||||
|
*/
|
||||||
private Center findCenter(GridView gridView) {
|
private Center findCenter(GridView gridView) {
|
||||||
if (gridView == null)
|
if (gridView == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -81,8 +81,10 @@ import org.zkoss.zul.Tabs;
|
||||||
import org.zkoss.zul.Toolbar;
|
import org.zkoss.zul.Toolbar;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Detail panel that display the child tabs of a parent {@link ADTabpanel} tab.
|
||||||
|
* Implemented as a panel with {@link Tabbox}.
|
||||||
|
*
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
|
|
||||||
|
@ -107,12 +109,16 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
|
|
||||||
private static final String BTN_TOGGLE_ID = "BtnToggle";
|
private static final String BTN_TOGGLE_ID = "BtnToggle";
|
||||||
|
|
||||||
|
/** Boolean execution attribute to indicate tabbox is handling ON_SELECT event **/
|
||||||
private static final String TABBOX_ONSELECT_ATTRIBUTE = "detailpane.tabbox.onselect";
|
private static final String TABBOX_ONSELECT_ATTRIBUTE = "detailpane.tabbox.onselect";
|
||||||
|
|
||||||
|
/** event after handling of ON_SElECT event of a detail tab */
|
||||||
private static final String ON_POST_SELECT_TAB_EVENT = "onPostSelectTab";
|
private static final String ON_POST_SELECT_TAB_EVENT = "onPostSelectTab";
|
||||||
|
|
||||||
|
/** Attribute use by {@link #messageContainers} to hold status text **/
|
||||||
private static final String STATUS_TEXT_ATTRIBUTE = "status.text";
|
private static final String STATUS_TEXT_ATTRIBUTE = "status.text";
|
||||||
|
|
||||||
|
/** Attribute use by {@link #messageContainers} to hold error text **/
|
||||||
private static final String STATUS_ERROR_ATTRIBUTE = "status.error";
|
private static final String STATUS_ERROR_ATTRIBUTE = "status.error";
|
||||||
|
|
||||||
private static final String CUSTOMIZE_IMAGE = "images/Customize16.png";
|
private static final String CUSTOMIZE_IMAGE = "images/Customize16.png";
|
||||||
|
@ -124,34 +130,57 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
private static final String QUICK_FORM_IMAGE = "images/QuickForm16.png";
|
private static final String QUICK_FORM_IMAGE = "images/QuickForm16.png";
|
||||||
private static final String TOGGLE_IMAGE = "images/Multi16.png";
|
private static final String TOGGLE_IMAGE = "images/Multi16.png";
|
||||||
|
|
||||||
|
/** Timestamp for previous key event **/
|
||||||
private long prevKeyEventTime = 0;
|
private long prevKeyEventTime = 0;
|
||||||
|
/**
|
||||||
|
* Previous KeyEvent reference.
|
||||||
|
* Use together with {@link #prevKeyEventTime} to detect double firing of key event by browser.
|
||||||
|
*/
|
||||||
private KeyEvent prevKeyEvent;
|
private KeyEvent prevKeyEvent;
|
||||||
|
|
||||||
|
/** tabbox for AD_Tabs **/
|
||||||
private Tabbox tabbox;
|
private Tabbox tabbox;
|
||||||
|
|
||||||
|
/** Registered event listener for DetailPane events **/
|
||||||
private EventListener<Event> eventListener;
|
private EventListener<Event> eventListener;
|
||||||
|
|
||||||
|
/** AD_Tab_ID:Hbox. Message (status, error) container for each tab. **/
|
||||||
private Map<Integer, Hbox> messageContainers = new HashMap<Integer, Hbox>();
|
private Map<Integer, Hbox> messageContainers = new HashMap<Integer, Hbox>();
|
||||||
|
|
||||||
|
/** content for message popup **/
|
||||||
private Div msgPopupCnt;
|
private Div msgPopupCnt;
|
||||||
|
|
||||||
|
/** message popup window **/
|
||||||
private Window msgPopup;
|
private Window msgPopup;
|
||||||
|
|
||||||
|
/** last selected tab index **/
|
||||||
private int prevSelectedIndex = 0;
|
private int prevSelectedIndex = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On activate event for detail tab.
|
||||||
|
* Use to activate detail tab or notify detail tab after header tab change.
|
||||||
|
*/
|
||||||
public static final String ON_ACTIVATE_DETAIL_EVENT = "onActivateDetail";
|
public static final String ON_ACTIVATE_DETAIL_EVENT = "onActivateDetail";
|
||||||
|
|
||||||
|
/** on delete event for selected tab **/
|
||||||
public static final String ON_DELETE_EVENT = "onDelete";
|
public static final String ON_DELETE_EVENT = "onDelete";
|
||||||
|
|
||||||
|
/** on new event for selected tab **/
|
||||||
public static final String ON_NEW_EVENT = "onNew";
|
public static final String ON_NEW_EVENT = "onNew";
|
||||||
|
|
||||||
|
/** event to edit current row of selected tab **/
|
||||||
public static final String ON_EDIT_EVENT = "onEdit";
|
public static final String ON_EDIT_EVENT = "onEdit";
|
||||||
|
|
||||||
|
/** on save event for selected tab **/
|
||||||
public static final String ON_SAVE_EVENT = "onSave";
|
public static final String ON_SAVE_EVENT = "onSave";
|
||||||
|
|
||||||
|
/** on quick form event for selected tab **/
|
||||||
public static final String ON_QUICK_FORM_EVENT = "onQuickForm";
|
public static final String ON_QUICK_FORM_EVENT = "onQuickForm";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record navigation event for selected tab.
|
||||||
|
* Event data is the navigation action (previous, next, first and last).
|
||||||
|
*/
|
||||||
public static final String ON_RECORD_NAVIGATE_EVENT = "onRecordNavigate";
|
public static final String ON_RECORD_NAVIGATE_EVENT = "onRecordNavigate";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -224,7 +253,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* replace of add
|
* Replace or add IADTabpanel to tabbox.
|
||||||
* @param index
|
* @param index
|
||||||
* @param tabPanel
|
* @param tabPanel
|
||||||
* @param tabLabel
|
* @param tabLabel
|
||||||
|
@ -238,7 +267,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* replace or add
|
* Replace or add IADTabpanel to tabbox.
|
||||||
* @param index
|
* @param index
|
||||||
* @param tabPanel
|
* @param tabPanel
|
||||||
* @param tabLabel
|
* @param tabLabel
|
||||||
|
@ -253,7 +282,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Add IADTabpanel to tabbox
|
||||||
* @param tabPanel
|
* @param tabPanel
|
||||||
* @param tabLabel
|
* @param tabLabel
|
||||||
*/
|
*/
|
||||||
|
@ -262,7 +291,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Add IADTabpanel to tabbox
|
||||||
* @param tabPanel
|
* @param tabPanel
|
||||||
* @param tabLabel
|
* @param tabLabel
|
||||||
* @param enabled
|
* @param enabled
|
||||||
|
@ -284,6 +313,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
tab.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
|
tab.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(Event event) throws Exception {
|
public void onEvent(Event event) throws Exception {
|
||||||
|
//click on tab title trigger edit of current row
|
||||||
Tab tab = (Tab) event.getTarget();
|
Tab tab = (Tab) event.getTarget();
|
||||||
if (!tab.isSelected())
|
if (!tab.isSelected())
|
||||||
return;
|
return;
|
||||||
|
@ -313,8 +343,9 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
Tabpanel tp = new Tabpanel();
|
Tabpanel tp = new Tabpanel();
|
||||||
tabpanels.appendChild(tp);
|
tabpanels.appendChild(tp);
|
||||||
ToolBar toolbar = tp.getToolbar();
|
|
||||||
|
|
||||||
|
//setup toolbar
|
||||||
|
ToolBar toolbar = tp.getToolbar();
|
||||||
HashMap<String, ToolBarButton> buttons = new HashMap<String, ToolBarButton>();
|
HashMap<String, ToolBarButton> buttons = new HashMap<String, ToolBarButton>();
|
||||||
ToolBarButton button = new ToolBarButton();
|
ToolBarButton button = new ToolBarButton();
|
||||||
if (ThemeManager.isUseFontIconForImage())
|
if (ThemeManager.isUseFontIconForImage())
|
||||||
|
@ -444,6 +475,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
button.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Toggle")) + " Shift+Alt+T");
|
button.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Toggle")) + " Shift+Alt+T");
|
||||||
buttons.put(BTN_TOGGLE_ID.substring(3, BTN_TOGGLE_ID.length()), button);
|
buttons.put(BTN_TOGGLE_ID.substring(3, BTN_TOGGLE_ID.length()), button);
|
||||||
|
|
||||||
|
//Detail toolbar button configure at AD_ToolBarButton
|
||||||
MToolBarButton[] officialButtons = MToolBarButton.getToolbarButtons("D", null);
|
MToolBarButton[] officialButtons = MToolBarButton.getToolbarButtons("D", null);
|
||||||
for (MToolBarButton toolbarButton : officialButtons) {
|
for (MToolBarButton toolbarButton : officialButtons) {
|
||||||
if ( !toolbarButton.isActive() ) {
|
if ( !toolbarButton.isActive() ) {
|
||||||
|
@ -505,6 +537,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//container for status and error text
|
||||||
Hbox messageContainer = new Hbox();
|
Hbox messageContainer = new Hbox();
|
||||||
messageContainer.setPack("end");
|
messageContainer.setPack("end");
|
||||||
messageContainer.setAlign("center");
|
messageContainer.setAlign("center");
|
||||||
|
@ -564,7 +597,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* open customize grid dialog
|
* Open customize grid view dialog.
|
||||||
* @param e
|
* @param e
|
||||||
*/
|
*/
|
||||||
protected void onCustomize(Event e) {
|
protected void onCustomize(Event e) {
|
||||||
|
@ -579,7 +612,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* open process dropdown
|
* open process list popup
|
||||||
* @param button
|
* @param button
|
||||||
*/
|
*/
|
||||||
protected void onProcess(Component button) {
|
protected void onProcess(Component button) {
|
||||||
|
@ -594,7 +627,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Set event listener for DetailPane events
|
||||||
* @param listener
|
* @param listener
|
||||||
*/
|
*/
|
||||||
public void setEventListener(EventListener<Event> listener) {
|
public void setEventListener(EventListener<Event> listener) {
|
||||||
|
@ -616,7 +649,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param index
|
* @param index
|
||||||
* @return adtabpanel at index
|
* @return IADTabpanel at index
|
||||||
*/
|
*/
|
||||||
public IADTabpanel getADTabpanel(int index) {
|
public IADTabpanel getADTabpanel(int index) {
|
||||||
if (index < 0 || index >= tabbox.getTabpanels().getChildren().size())
|
if (index < 0 || index >= tabbox.getTabpanels().getChildren().size())
|
||||||
|
@ -631,8 +664,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return selected IADTabpanel
|
||||||
* @return selected adtabpanel
|
|
||||||
*/
|
*/
|
||||||
public IADTabpanel getSelectedADTabpanel() {
|
public IADTabpanel getSelectedADTabpanel() {
|
||||||
org.zkoss.zul.Tabpanel selectedPanel = tabbox.getSelectedPanel();
|
org.zkoss.zul.Tabpanel selectedPanel = tabbox.getSelectedPanel();
|
||||||
|
@ -646,15 +678,14 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return selected {@link Tabpanel}
|
||||||
* @return {@link Tabpanel}
|
|
||||||
*/
|
*/
|
||||||
public Tabpanel getSelectedPanel() {
|
public Tabpanel getSelectedPanel() {
|
||||||
return (Tabpanel) tabbox.getSelectedPanel();
|
return (Tabpanel) tabbox.getSelectedPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Set status and error text for selected tab.
|
||||||
* @param status
|
* @param status
|
||||||
* @param error
|
* @param error
|
||||||
*/
|
*/
|
||||||
|
@ -676,6 +707,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
messageContainer.getChildren().clear();
|
messageContainer.getChildren().clear();
|
||||||
|
//store in attribute for retrieval in ON_CLICK event
|
||||||
messageContainer.setAttribute(STATUS_ERROR_ATTRIBUTE, error);
|
messageContainer.setAttribute(STATUS_ERROR_ATTRIBUTE, error);
|
||||||
messageContainer.setAttribute(STATUS_TEXT_ATTRIBUTE, status);
|
messageContainer.setAttribute(STATUS_TEXT_ATTRIBUTE, status);
|
||||||
messageContainer.setSclass(error ? "docstatus-error" : "docstatus-normal");
|
messageContainer.setSclass(error ? "docstatus-error" : "docstatus-normal");
|
||||||
|
@ -712,6 +744,11 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shorten status text to a more presentable length.
|
||||||
|
* @param statusText
|
||||||
|
* @return shorten status text
|
||||||
|
*/
|
||||||
private String buildLabelText(String statusText) {
|
private String buildLabelText(String statusText) {
|
||||||
if (statusText == null)
|
if (statusText == null)
|
||||||
return "";
|
return "";
|
||||||
|
@ -724,6 +761,11 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
return statusText.substring(0, 80);
|
return statusText.substring(0, 80);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shorten notification text to a more presentable length.
|
||||||
|
* @param statusText
|
||||||
|
* @return shorten notification text
|
||||||
|
*/
|
||||||
private String buildNotificationText(String statusText) {
|
private String buildNotificationText(String statusText) {
|
||||||
if (statusText == null)
|
if (statusText == null)
|
||||||
return "";
|
return "";
|
||||||
|
@ -777,20 +819,31 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create popup content for message popup window
|
||||||
|
* @param status
|
||||||
|
*/
|
||||||
protected void createPopupContent(String status) {
|
protected void createPopupContent(String status) {
|
||||||
Text t = new Text(status);
|
Text t = new Text(status);
|
||||||
msgPopupCnt.getChildren().clear();
|
msgPopupCnt.getChildren().clear();
|
||||||
msgPopupCnt.appendChild(t);
|
msgPopupCnt.appendChild(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show notification popup using Clients.showNotification
|
||||||
|
* @param error
|
||||||
|
* @param msg
|
||||||
|
*/
|
||||||
private void showPopup(boolean error, String msg) {
|
private void showPopup(boolean error, String msg) {
|
||||||
Clients.showNotification(buildNotificationText(msg), "error", findTabpanel(this), "at_pointer", 3500, true);
|
Clients.showNotification(buildNotificationText(msg), "error", findTabpanel(this), "at_pointer", 3500, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create message popup window
|
||||||
|
*/
|
||||||
private void createPopup() {
|
private void createPopup() {
|
||||||
msgPopupCnt = new Div();
|
msgPopupCnt = new Div();
|
||||||
ZKUpdateUtil.setVflex(msgPopupCnt, "1");
|
ZKUpdateUtil.setVflex(msgPopupCnt, "1");
|
||||||
|
|
||||||
|
|
||||||
msgPopup = new Window();
|
msgPopup = new Window();
|
||||||
msgPopup.setVisible(false);
|
msgPopup.setVisible(false);
|
||||||
|
@ -903,10 +956,13 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update from customized implementation
|
//Not use by ADTabpanel, for custom IADTabpanel implementation.
|
||||||
adtab.updateDetailToolbar(toolbar);
|
adtab.updateDetailToolbar(toolbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update state of Process toolbar button.
|
||||||
|
*/
|
||||||
private void updateProcessToolbar() {
|
private void updateProcessToolbar() {
|
||||||
int index = getSelectedIndex();
|
int index = getSelectedIndex();
|
||||||
if (index < 0 || index >= getTabcount()) return;
|
if (index < 0 || index >= getTabcount()) return;
|
||||||
|
@ -934,8 +990,9 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edit current record
|
* Edit current record of selected tab.
|
||||||
* @param formView
|
* This event will make the selected tab becomes the new header tab, i.e become the selected tab of {@link CompositeADTabbox}.
|
||||||
|
* @param formView true to force form view.
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void onEdit(boolean formView) throws Exception {
|
public void onEdit(boolean formView) throws Exception {
|
||||||
|
@ -944,7 +1001,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fire the on activate detail event
|
* Fire ON_ACTIVATE_DETAIL_EVENT for selected tab.
|
||||||
*/
|
*/
|
||||||
public void fireActivateDetailEvent() {
|
public void fireActivateDetailEvent() {
|
||||||
int index = tabbox.getSelectedIndex();
|
int index = tabbox.getSelectedIndex();
|
||||||
|
@ -972,7 +1029,6 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param tabIndex
|
* @param tabIndex
|
||||||
* @return true if tab at tabIndex is visible
|
* @return true if tab at tabIndex is visible
|
||||||
*/
|
*/
|
||||||
|
@ -996,7 +1052,6 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param tabIndex
|
* @param tabIndex
|
||||||
* @param enabled
|
* @param enabled
|
||||||
*/
|
*/
|
||||||
|
@ -1009,7 +1064,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* disable toolbar
|
* Disable all toolbar buttons
|
||||||
*/
|
*/
|
||||||
public void disableToolbar() {
|
public void disableToolbar() {
|
||||||
int index = getSelectedIndex();
|
int index = getSelectedIndex();
|
||||||
|
@ -1025,6 +1080,11 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find first {@link Tabpanel} that own comp.
|
||||||
|
* @param comp
|
||||||
|
* @return {@link Component}
|
||||||
|
*/
|
||||||
private Component findTabpanel(Component comp) {
|
private Component findTabpanel(Component comp) {
|
||||||
Component parent = comp.getParent();
|
Component parent = comp.getParent();
|
||||||
while (parent != null) {
|
while (parent != null) {
|
||||||
|
@ -1037,7 +1097,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add new record
|
* add new row
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void onNew() throws Exception {
|
public void onNew() throws Exception {
|
||||||
|
@ -1052,6 +1112,11 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
private static final int VK_D = 0x44;
|
private static final int VK_D = 0x44;
|
||||||
private static final int VK_O = 0x4F;
|
private static final int VK_O = 0x4F;
|
||||||
private static final int VK_Q = 0x51;
|
private static final int VK_Q = 0x51;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle shortcut key event
|
||||||
|
* @param keyEvent
|
||||||
|
*/
|
||||||
private void onCtrlKeyEvent(KeyEvent keyEvent) {
|
private void onCtrlKeyEvent(KeyEvent keyEvent) {
|
||||||
ToolBarButton btn = null;
|
ToolBarButton btn = null;
|
||||||
if (keyEvent.isAltKey() && !keyEvent.isCtrlKey() && keyEvent.isShiftKey()) { // Shift+Alt key
|
if (keyEvent.isAltKey() && !keyEvent.isCtrlKey() && keyEvent.isShiftKey()) { // Shift+Alt key
|
||||||
|
@ -1096,14 +1161,12 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tabpanel for adtabpanel
|
* Custom {@link org.adempiere.webui.component.Tabpanel} implementation for DetailPane.
|
||||||
* @author hengsin
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static class Tabpanel extends org.adempiere.webui.component.Tabpanel {
|
public static class Tabpanel extends org.adempiere.webui.component.Tabpanel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 8248794614430375822L;
|
private static final long serialVersionUID = 8248794614430375822L;
|
||||||
|
|
||||||
|
@ -1156,7 +1219,6 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @return true if tab have been toggle to form view
|
* @return true if tab have been toggle to form view
|
||||||
*/
|
*/
|
||||||
public boolean isToggleToFormView() {
|
public boolean isToggleToFormView() {
|
||||||
|
@ -1209,7 +1271,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set paging control container
|
* Set paging control
|
||||||
* @param pagingControl
|
* @param pagingControl
|
||||||
*/
|
*/
|
||||||
public void setPagingControl(Div pagingControl) {
|
public void setPagingControl(Div pagingControl) {
|
||||||
|
@ -1225,7 +1287,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return paging control container
|
* @return paging control
|
||||||
*/
|
*/
|
||||||
public Div getPagingControl() {
|
public Div getPagingControl() {
|
||||||
return pagingControl;
|
return pagingControl;
|
||||||
|
@ -1243,7 +1305,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return buttons from the detail toolbar
|
* @return toolbar buttons from the detail toolbar
|
||||||
*/
|
*/
|
||||||
private List<ToolBarButton> getToolbarButtons() {
|
private List<ToolBarButton> getToolbarButtons() {
|
||||||
|
|
||||||
|
@ -1257,6 +1319,9 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create overflow button (show more) for mobile client.
|
||||||
|
*/
|
||||||
private void createOverflowButton() {
|
private void createOverflowButton() {
|
||||||
overflowButton = new A();
|
overflowButton = new A();
|
||||||
overflowButton.setTooltiptext(Msg.getMsg(Env.getCtx(), "ShowMore"));
|
overflowButton.setTooltiptext(Msg.getMsg(Env.getCtx(), "ShowMore"));
|
||||||
|
@ -1276,6 +1341,9 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new overflow popup
|
||||||
|
*/
|
||||||
private void newOverflowPopup() {
|
private void newOverflowPopup() {
|
||||||
overflowPopup = new Popup();
|
overflowPopup = new Popup();
|
||||||
overflowPopup.setHflex("min");
|
overflowPopup.setHflex("min");
|
||||||
|
@ -1291,7 +1359,7 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
private static class RecordToolbar extends Hlayout {
|
private static class RecordToolbar extends Hlayout {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 5024630043211194429L;
|
private static final long serialVersionUID = 5024630043211194429L;
|
||||||
private ToolBarButton btnFirst;
|
private ToolBarButton btnFirst;
|
||||||
|
@ -1301,6 +1369,9 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
private ToolBarButton btnLast;
|
private ToolBarButton btnLast;
|
||||||
private GridTab gridTab;
|
private GridTab gridTab;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param gridTab
|
||||||
|
*/
|
||||||
private RecordToolbar(GridTab gridTab) {
|
private RecordToolbar(GridTab gridTab) {
|
||||||
this.gridTab = gridTab;
|
this.gridTab = gridTab;
|
||||||
btnFirst = createButton("First", "First", "First");
|
btnFirst = createButton("First", "First", "First");
|
||||||
|
@ -1350,6 +1421,13 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
this.setValign("middle");
|
this.setValign("middle");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create toolbar button
|
||||||
|
* @param name
|
||||||
|
* @param image
|
||||||
|
* @param tooltip
|
||||||
|
* @return {@link ToolBarButton}
|
||||||
|
*/
|
||||||
private ToolBarButton createButton(String name, String image, String tooltip)
|
private ToolBarButton createButton(String name, String image, String tooltip)
|
||||||
{
|
{
|
||||||
ToolBarButton btn = new ToolBarButton("");
|
ToolBarButton btn = new ToolBarButton("");
|
||||||
|
@ -1372,6 +1450,9 @@ public class DetailPane extends Panel implements EventListener<Event>, IdSpace {
|
||||||
return btn;
|
return btn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamic update state of toolbar buttons
|
||||||
|
*/
|
||||||
private void dynamicDisplay() {
|
private void dynamicDisplay() {
|
||||||
int rowCount = gridTab.getRowCount();
|
int rowCount = gridTab.getRowCount();
|
||||||
int currentRow = gridTab.getCurrentRow()+1;
|
int currentRow = gridTab.getCurrentRow()+1;
|
||||||
|
|
|
@ -81,28 +81,53 @@ import org.zkoss.zul.impl.XulElement;
|
||||||
*/
|
*/
|
||||||
public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt, RendererCtrl, EventListener<Event> {
|
public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt, RendererCtrl, EventListener<Event> {
|
||||||
|
|
||||||
|
/** Cell div component attribute to hold field column name value **/
|
||||||
|
protected static final String COLUMN_NAME_ATTR = "columnName";
|
||||||
|
|
||||||
|
/** Cell div component attribute to hold reference to editor component use to create display text for field **/
|
||||||
|
private static final String DISPLAY_COMPONENT_ATTR = "display.component";
|
||||||
|
|
||||||
|
/** Boolean execution attribute to indicate execution is handling the "Select" checkbox's ON_CHECK event **/
|
||||||
|
private static final String GRID_VIEW_ON_SELECT_ROW_ATTR = "gridView.onSelectRow";
|
||||||
|
|
||||||
|
/** Editor component attribute to store row index (absolute) **/
|
||||||
public static final String GRID_ROW_INDEX_ATTR = "grid.row.index";
|
public static final String GRID_ROW_INDEX_ATTR = "grid.row.index";
|
||||||
|
|
||||||
|
//styles for grid cell
|
||||||
private static final String CELL_DIV_STYLE = "height: 100%; cursor: pointer; ";
|
private static final String CELL_DIV_STYLE = "height: 100%; cursor: pointer; ";
|
||||||
private static final String CELL_DIV_STYLE_ALIGN_CENTER = CELL_DIV_STYLE + "text-align:center; ";
|
private static final String CELL_DIV_STYLE_ALIGN_CENTER = CELL_DIV_STYLE + "text-align:center; ";
|
||||||
private static final String CELL_DIV_STYLE_ALIGN_RIGHT = CELL_DIV_STYLE + "text-align:right; ";
|
private static final String CELL_DIV_STYLE_ALIGN_RIGHT = CELL_DIV_STYLE + "text-align:right; ";
|
||||||
|
|
||||||
|
/** default max length for display text for field **/
|
||||||
private static final int MAX_TEXT_LENGTH_DEFAULT = 60;
|
private static final int MAX_TEXT_LENGTH_DEFAULT = 60;
|
||||||
private GridTab gridTab;
|
private GridTab gridTab;
|
||||||
private int windowNo;
|
private int windowNo;
|
||||||
|
/** Sync field editor changes to GridField **/
|
||||||
private GridTabDataBinder dataBinder;
|
private GridTabDataBinder dataBinder;
|
||||||
|
/** field editors **/
|
||||||
private Map<GridField, WEditor> editors = new LinkedHashMap<GridField, WEditor>();
|
private Map<GridField, WEditor> editors = new LinkedHashMap<GridField, WEditor>();
|
||||||
|
/** readonly field editors to get display text for field value **/
|
||||||
private Map<GridField, WEditor> readOnlyEditors = new LinkedHashMap<GridField, WEditor>();
|
private Map<GridField, WEditor> readOnlyEditors = new LinkedHashMap<GridField, WEditor>();
|
||||||
private Paging paging;
|
private Paging paging;
|
||||||
|
|
||||||
|
/** internal listener for row event **/
|
||||||
private RowListener rowListener;
|
private RowListener rowListener;
|
||||||
|
|
||||||
|
/** Grid that own this renderer **/
|
||||||
private Grid grid = null;
|
private Grid grid = null;
|
||||||
|
/** GridView that uses this renderer **/
|
||||||
private GridView gridPanel = null;
|
private GridView gridPanel = null;
|
||||||
|
/** current focus row **/
|
||||||
private Row currentRow;
|
private Row currentRow;
|
||||||
|
/** values of current row. updated in {@link #render(Row, Object[], int)}. **/
|
||||||
private Object[] currentValues;
|
private Object[] currentValues;
|
||||||
|
/** true if currrent row is in edit mode **/
|
||||||
private boolean editing = false;
|
private boolean editing = false;
|
||||||
|
/** index of current row **/
|
||||||
private int currentRowIndex = -1;
|
private int currentRowIndex = -1;
|
||||||
|
/** AD window content part that own this renderer **/
|
||||||
private AbstractADWindowContent m_windowPanel;
|
private AbstractADWindowContent m_windowPanel;
|
||||||
|
/** internal listener for button ActionEvent **/
|
||||||
private ActionListener buttonListener;
|
private ActionListener buttonListener;
|
||||||
/**
|
/**
|
||||||
* Flag detect this view has customized column or not
|
* Flag detect this view has customized column or not
|
||||||
|
@ -112,6 +137,7 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
/** DefaultFocusField */
|
/** DefaultFocusField */
|
||||||
private WEditor defaultFocusField = null;
|
private WEditor defaultFocusField = null;
|
||||||
|
|
||||||
|
/** editor configuration for readonly field editor **/
|
||||||
private final static IEditorConfiguration readOnlyEditorConfiguration = new IEditorConfiguration() {
|
private final static IEditorConfiguration readOnlyEditorConfiguration = new IEditorConfiguration() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean getReadonly() {
|
public Boolean getReadonly() {
|
||||||
|
@ -135,6 +161,11 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
this.dataBinder = new GridTabDataBinder(gridTab);
|
this.dataBinder = new GridTabDataBinder(gridTab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get editor for GridField.
|
||||||
|
* @param gridField
|
||||||
|
* @return {@link WEditor}
|
||||||
|
*/
|
||||||
private WEditor getEditorCell(GridField gridField) {
|
private WEditor getEditorCell(GridField gridField) {
|
||||||
WEditor editor = editors.get(gridField);
|
WEditor editor = editors.get(gridField);
|
||||||
if (editor != null) {
|
if (editor != null) {
|
||||||
|
@ -147,6 +178,11 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup field editor
|
||||||
|
* @param gridField
|
||||||
|
* @param editor
|
||||||
|
*/
|
||||||
private void prepareFieldEditor(GridField gridField, WEditor editor) {
|
private void prepareFieldEditor(GridField gridField, WEditor editor) {
|
||||||
if (editor instanceof WButtonEditor)
|
if (editor instanceof WButtonEditor)
|
||||||
{
|
{
|
||||||
|
@ -172,9 +208,8 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param field
|
* @param field
|
||||||
* @return column index, -1 if not found
|
* @return column index for field, -1 if not found
|
||||||
*/
|
*/
|
||||||
public int getColumnIndex(GridField field) {
|
public int getColumnIndex(GridField field) {
|
||||||
GridField[] fields = gridPanel.getFields();
|
GridField[] fields = gridPanel.getFields();
|
||||||
|
@ -185,6 +220,10 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param value
|
||||||
|
* @return readonly checkbox component
|
||||||
|
*/
|
||||||
private Component createReadonlyCheckbox(Object value) {
|
private Component createReadonlyCheckbox(Object value) {
|
||||||
Checkbox checkBox = new Checkbox();
|
Checkbox checkBox = new Checkbox();
|
||||||
if (value != null && "true".equalsIgnoreCase(value.toString()))
|
if (value != null && "true".equalsIgnoreCase(value.toString()))
|
||||||
|
@ -195,6 +234,11 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
return checkBox;
|
return checkBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create invisible component for GridField with IsHeading=Y.
|
||||||
|
* To fill up space allocated for field component.
|
||||||
|
* @return invisible text box component
|
||||||
|
*/
|
||||||
private Component createInvisibleComponent() {
|
private Component createInvisibleComponent() {
|
||||||
Textbox textBox = new Textbox();
|
Textbox textBox = new Textbox();
|
||||||
textBox.setDisabled(true);
|
textBox.setDisabled(true);
|
||||||
|
@ -236,7 +280,8 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
* @param value
|
* @param value
|
||||||
* @param gridField
|
* @param gridField
|
||||||
* @param rowIndex
|
* @param rowIndex
|
||||||
* @param isForceGetValue
|
* @param isForceGetValue true to return text for field value even if IsDisplay return false. This is to allow Grid customization
|
||||||
|
* to override IsDisplay result.
|
||||||
* @return display text
|
* @return display text
|
||||||
*/
|
*/
|
||||||
private String getDisplayText(Object value, GridField gridField, int rowIndex, boolean isForceGetValue)
|
private String getDisplayText(Object value, GridField gridField, int rowIndex, boolean isForceGetValue)
|
||||||
|
@ -271,8 +316,9 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
* @param rowIndex
|
* @param rowIndex
|
||||||
* @param value
|
* @param value
|
||||||
* @param gridField
|
* @param gridField
|
||||||
* @param isForceGetValue
|
* @param isForceGetValue true to return Component with value even if IsDisplay return false. This is to allow Grid customization
|
||||||
* @return
|
* preference to override IsDisplay result.
|
||||||
|
* @return {@link Component}
|
||||||
*/
|
*/
|
||||||
private Component getDisplayComponent(int rowIndex, Object value, GridField gridField, boolean isForceGetValue) {
|
private Component getDisplayComponent(int rowIndex, Object value, GridField gridField, boolean isForceGetValue) {
|
||||||
Component component;
|
Component component;
|
||||||
|
@ -308,6 +354,12 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply AD_Style to field.
|
||||||
|
* @param gridField
|
||||||
|
* @param rowIndex
|
||||||
|
* @param component
|
||||||
|
*/
|
||||||
private void applyFieldStyle(GridField gridField, int rowIndex,
|
private void applyFieldStyle(GridField gridField, int rowIndex,
|
||||||
HtmlBasedComponent component) {
|
HtmlBasedComponent component) {
|
||||||
int AD_Style_ID = gridField.getAD_FieldStyle_ID();
|
int AD_Style_ID = gridField.getAD_FieldStyle_ID();
|
||||||
|
@ -319,6 +371,11 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
setComponentStyle(component, style.buildStyle(ThemeManager.getTheme(), gridRowCtx));
|
setComponentStyle(component, style.buildStyle(ThemeManager.getTheme(), gridRowCtx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set component's style, sclass or zclass property
|
||||||
|
* @param component
|
||||||
|
* @param style "@sclass=" for sclass for "@zclass=" for zclass. default to style if there's no prefix.
|
||||||
|
*/
|
||||||
protected void setComponentStyle(HtmlBasedComponent component, String style) {
|
protected void setComponentStyle(HtmlBasedComponent component, String style) {
|
||||||
if (style != null && style.startsWith(MStyle.SCLASS_PREFIX)) {
|
if (style != null && style.startsWith(MStyle.SCLASS_PREFIX)) {
|
||||||
String sclass = style.substring(MStyle.SCLASS_PREFIX.length());
|
String sclass = style.substring(MStyle.SCLASS_PREFIX.length());
|
||||||
|
@ -341,6 +398,7 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* set label text, shorten text if length exceed define max length.
|
||||||
* @param text
|
* @param text
|
||||||
* @param label
|
* @param label
|
||||||
*/
|
*/
|
||||||
|
@ -355,8 +413,7 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return field editor list
|
||||||
* @return active editor list
|
|
||||||
*/
|
*/
|
||||||
public List<WEditor> getEditors() {
|
public List<WEditor> getEditors() {
|
||||||
List<WEditor> editorList = new ArrayList<WEditor>();
|
List<WEditor> editorList = new ArrayList<WEditor>();
|
||||||
|
@ -395,7 +452,7 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
else
|
else
|
||||||
child = parent;
|
child = parent;
|
||||||
}
|
}
|
||||||
Component component = div!=null ? (Component) div.getAttribute("display.component") : null;
|
Component component = div!=null ? (Component) div.getAttribute(DISPLAY_COMPONENT_ATTR) : null;
|
||||||
if (updateCellLabel) {
|
if (updateCellLabel) {
|
||||||
if (component instanceof Label) {
|
if (component instanceof Label) {
|
||||||
Label label = (Label)component;
|
Label label = (Label)component;
|
||||||
|
@ -433,9 +490,10 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Render data for row.
|
||||||
* @param row
|
* @param row
|
||||||
* @param data
|
* @param data Object[] values for row
|
||||||
* @param index
|
* @param index row index within current page (i.e if page size is 25, index is one of 0 to 24).
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void render(Row row, Object[] data, int index) throws Exception {
|
public void render(Row row, Object[] data, int index) throws Exception {
|
||||||
|
@ -579,7 +637,7 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
if (column.isVisible()) {
|
if (column.isVisible()) {
|
||||||
Component component = getDisplayComponent(rowIndex, currentValues[i], gridPanelFields[i], isGridViewCustomized);
|
Component component = getDisplayComponent(rowIndex, currentValues[i], gridPanelFields[i], isGridViewCustomized);
|
||||||
div.appendChild(component);
|
div.appendChild(component);
|
||||||
div.setAttribute("display.component", component);
|
div.setAttribute(DISPLAY_COMPONENT_ATTR, component);
|
||||||
if (gridPanelFields[i].isHeading()) {
|
if (gridPanelFields[i].isHeading()) {
|
||||||
component.setVisible(false);
|
component.setVisible(false);
|
||||||
}
|
}
|
||||||
|
@ -599,7 +657,7 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
}
|
}
|
||||||
div.setStyle(divStyle);
|
div.setStyle(divStyle);
|
||||||
ZKUpdateUtil.setWidth(div, "100%");
|
ZKUpdateUtil.setWidth(div, "100%");
|
||||||
div.setAttribute("columnName", gridPanelFields[i].getColumnName());
|
div.setAttribute(COLUMN_NAME_ATTR, gridPanelFields[i].getColumnName());
|
||||||
div.addEventListener(Events.ON_CLICK, rowListener);
|
div.addEventListener(Events.ON_CLICK, rowListener);
|
||||||
div.addEventListener(Events.ON_DOUBLE_CLICK, rowListener);
|
div.addEventListener(Events.ON_DOUBLE_CLICK, rowListener);
|
||||||
row.appendChild(div);
|
row.appendChild(div);
|
||||||
|
@ -693,7 +751,7 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Row
|
* @return current {@link Row}
|
||||||
*/
|
*/
|
||||||
public Row getCurrentRow() {
|
public Row getCurrentRow() {
|
||||||
return currentRow;
|
return currentRow;
|
||||||
|
@ -707,7 +765,7 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enter edit mode
|
* Enter edit mode for current focus row.
|
||||||
*/
|
*/
|
||||||
public void editCurrentRow() {
|
public void editCurrentRow() {
|
||||||
if (ClientInfo.isMobile()) {
|
if (ClientInfo.isMobile()) {
|
||||||
|
@ -771,6 +829,9 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if it is own by {@link DetailPane}.
|
||||||
|
*/
|
||||||
private boolean isDetailPane() {
|
private boolean isDetailPane() {
|
||||||
Component parent = grid.getParent();
|
Component parent = grid.getParent();
|
||||||
while (parent != null) {
|
while (parent != null) {
|
||||||
|
@ -828,7 +889,8 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set focus to first active editor
|
* Set focus to first writable field editor (or default focus field editor if it is writable).
|
||||||
|
* If no field editor is writable, set focus to first visible field editor.
|
||||||
*/
|
*/
|
||||||
public void focusToFirstEditor() {
|
public void focusToFirstEditor() {
|
||||||
if (currentRow != null && currentRow.getParent() != null) {
|
if (currentRow != null && currentRow.getParent() != null) {
|
||||||
|
@ -861,7 +923,6 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param toFocus
|
* @param toFocus
|
||||||
*/
|
*/
|
||||||
protected void focusToEditor(WEditor toFocus) {
|
protected void focusToEditor(WEditor toFocus) {
|
||||||
|
@ -877,7 +938,7 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set focus to next readwrite editor from ref
|
* set focus to next writable editor from ref
|
||||||
* @param ref
|
* @param ref
|
||||||
*/
|
*/
|
||||||
public void focusToNextEditor(WEditor ref) {
|
public void focusToNextEditor(WEditor ref) {
|
||||||
|
@ -897,13 +958,16 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Set {@link GridView} that own this renderer.
|
||||||
* @param gridPanel
|
* @param gridPanel
|
||||||
*/
|
*/
|
||||||
public void setGridPanel(GridView gridPanel) {
|
public void setGridPanel(GridView gridPanel) {
|
||||||
this.gridPanel = gridPanel;
|
this.gridPanel = gridPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal listener for row event (ON_CLICK, ON_DOUBLE_CLICK and ON_OK).
|
||||||
|
*/
|
||||||
static class RowListener implements EventListener<Event> {
|
static class RowListener implements EventListener<Event> {
|
||||||
|
|
||||||
private Grid _grid;
|
private Grid _grid;
|
||||||
|
@ -914,7 +978,7 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
|
|
||||||
public void onEvent(Event event) throws Exception {
|
public void onEvent(Event event) throws Exception {
|
||||||
if (Events.ON_CLICK.equals(event.getName())) {
|
if (Events.ON_CLICK.equals(event.getName())) {
|
||||||
if (Executions.getCurrent().getAttribute("gridView.onSelectRow") != null)
|
if (Executions.getCurrent().getAttribute(GRID_VIEW_ON_SELECT_ROW_ATTR) != null)
|
||||||
return;
|
return;
|
||||||
Event evt = new Event(Events.ON_CLICK, _grid, event.getTarget());
|
Event evt = new Event(Events.ON_CLICK, _grid, event.getTarget());
|
||||||
Events.sendEvent(_grid, evt);
|
Events.sendEvent(_grid, evt);
|
||||||
|
@ -932,13 +996,15 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if it is in edit mode, false otherwise
|
* @return true if current row is in edit mode, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean isEditing() {
|
public boolean isEditing() {
|
||||||
return editing;
|
return editing;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Set AD window content part that own this renderer.
|
||||||
|
* {@link #buttonListener} need this to call {@link AbstractADWindowContent#actionPerformed(ActionEvent)}.
|
||||||
* @param windowPanel
|
* @param windowPanel
|
||||||
*/
|
*/
|
||||||
public void setADWindowPanel(AbstractADWindowContent windowPanel) {
|
public void setADWindowPanel(AbstractADWindowContent windowPanel) {
|
||||||
|
@ -974,12 +1040,15 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
|
||||||
else
|
else
|
||||||
Events.sendEvent(event.getTarget().getParent(), event);
|
Events.sendEvent(event.getTarget().getParent(), event);
|
||||||
} else if (event.getTarget() instanceof Checkbox) {
|
} else if (event.getTarget() instanceof Checkbox) {
|
||||||
Executions.getCurrent().setAttribute("gridView.onSelectRow", Boolean.TRUE);
|
Executions.getCurrent().setAttribute(GRID_VIEW_ON_SELECT_ROW_ATTR, Boolean.TRUE);
|
||||||
Checkbox checkBox = (Checkbox) event.getTarget();
|
Checkbox checkBox = (Checkbox) event.getTarget();
|
||||||
Events.sendEvent(gridPanel, new Event("onSelectRow", gridPanel, checkBox));
|
Events.sendEvent(gridPanel, new Event("onSelectRow", gridPanel, checkBox));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link GridView#isShowCurrentRowIndicatorColumn}
|
||||||
|
*/
|
||||||
private boolean isShowCurrentRowIndicatorColumn() {
|
private boolean isShowCurrentRowIndicatorColumn() {
|
||||||
return gridPanel != null && gridPanel.isShowCurrentRowIndicatorColumn();
|
return gridPanel != null && gridPanel.isShowCurrentRowIndicatorColumn();
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,14 +28,14 @@ import org.zkoss.zul.event.ListDataEvent;
|
||||||
import org.zkoss.zul.ext.Sortable;
|
import org.zkoss.zul.ext.Sortable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* List model for {@link GridTable}
|
||||||
* @author Low Heng Sin
|
* @author Low Heng Sin
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class GridTableListModel extends AbstractListModel<Object> implements TableModelListener, Sortable<Object> {
|
public class GridTableListModel extends AbstractListModel<Object> implements TableModelListener, Sortable<Object> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 698185856751242764L;
|
private static final long serialVersionUID = 698185856751242764L;
|
||||||
private GridTable tableModel;
|
private GridTable tableModel;
|
||||||
|
@ -47,10 +47,10 @@ public class GridTableListModel extends AbstractListModel<Object> implements Tab
|
||||||
private int pageSize = -1;
|
private int pageSize = -1;
|
||||||
private int pageNo = 0;
|
private int pageNo = 0;
|
||||||
|
|
||||||
|
/** Edit mode flag. When editing is true, do not fire ListDataEvent.CONTENTS_CHANGED event. **/
|
||||||
private boolean editing = false;
|
private boolean editing = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param tableModel
|
* @param tableModel
|
||||||
* @param windowNo
|
* @param windowNo
|
||||||
*/
|
*/
|
||||||
|
@ -142,7 +142,7 @@ public class GridTableListModel extends AbstractListModel<Object> implements Tab
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request components that attached to this model to re-render a row.
|
* Delegate to {@link #updateComponent(int, int)}.
|
||||||
* @param row
|
* @param row
|
||||||
*/
|
*/
|
||||||
public void updateComponent(int row) {
|
public void updateComponent(int row) {
|
||||||
|
@ -151,6 +151,7 @@ public class GridTableListModel extends AbstractListModel<Object> implements Tab
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request components that attached to this model to re-render a range of row.
|
* Request components that attached to this model to re-render a range of row.
|
||||||
|
* Fire ListDataEvent.CONTENTS_CHANGED event for fromRow to toRow.
|
||||||
* @param fromRow
|
* @param fromRow
|
||||||
* @param toRow
|
* @param toRow
|
||||||
*/
|
*/
|
||||||
|
@ -162,6 +163,7 @@ public class GridTableListModel extends AbstractListModel<Object> implements Tab
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Sort and fire ListDataEvent.CONTENTS_CHANGED event to notify UI component.
|
||||||
* @param cmpr
|
* @param cmpr
|
||||||
* @param ascending
|
* @param ascending
|
||||||
*/
|
*/
|
||||||
|
@ -178,6 +180,7 @@ public class GridTableListModel extends AbstractListModel<Object> implements Tab
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Handle TableModelEvent from GridTable.
|
||||||
* @param e
|
* @param e
|
||||||
* @see TableModelListener#tableChanged(TableModelEvent)
|
* @see TableModelListener#tableChanged(TableModelEvent)
|
||||||
*/
|
*/
|
||||||
|
@ -216,6 +219,8 @@ public class GridTableListModel extends AbstractListModel<Object> implements Tab
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Set editing to true/false.
|
||||||
|
* When editing is true, do not fire ListDataEvent.CONTENTS_CHANGED event.
|
||||||
* @param b
|
* @param b
|
||||||
*/
|
*/
|
||||||
public void setEditing(boolean b) {
|
public void setEditing(boolean b) {
|
||||||
|
|
|
@ -70,95 +70,132 @@ import org.zkoss.zul.event.ZulEvents;
|
||||||
import org.zkoss.zul.impl.CustomGridDataLoader;
|
import org.zkoss.zul.impl.CustomGridDataLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Grid view implemented using the Grid component.
|
* Grid/List view implemented using the Grid component.
|
||||||
* @author Low Heng Sin
|
* @author Low Heng Sin
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class GridView extends Vlayout implements EventListener<Event>, IdSpace, IFieldEditorContainer, StateChangeListener
|
public class GridView extends Vlayout implements EventListener<Event>, IdSpace, IFieldEditorContainer, StateChangeListener
|
||||||
{
|
{
|
||||||
|
/** Event after the current row index has changed. **/
|
||||||
|
private static final String ON_POST_SELECTED_ROW_CHANGED_EVENT = "onPostSelectedRowChanged";
|
||||||
|
|
||||||
public static final String ZERO_PX_WIDTH = "0px";
|
public static final String ZERO_PX_WIDTH = "0px";
|
||||||
|
|
||||||
|
/** {@link Column} attribute to store grid field index **/
|
||||||
private static final String GRID_VIEW_GRID_FIELD_INDEX = "gridView.gridField.index";
|
private static final String GRID_VIEW_GRID_FIELD_INDEX = "gridView.gridField.index";
|
||||||
|
|
||||||
|
/** {@link Column} attribute to store initial/original column width value **/
|
||||||
public static final String COLUMN_WIDTH_ORIGINAL = "column.width.original";
|
public static final String COLUMN_WIDTH_ORIGINAL = "column.width.original";
|
||||||
|
|
||||||
|
/** {@link Column} attribute to store initial/original column hflex value **/
|
||||||
private static final String COLUMN_HFLEX_ORIGINAL = "column.hflex.original";
|
private static final String COLUMN_HFLEX_ORIGINAL = "column.hflex.original";
|
||||||
|
|
||||||
|
/** minimum column width for mobile client **/
|
||||||
private static final int MIN_COLUMN_MOBILE_WIDTH = 100;
|
private static final int MIN_COLUMN_MOBILE_WIDTH = 100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 3995829393137424527L;
|
private static final long serialVersionUID = 3995829393137424527L;
|
||||||
|
|
||||||
|
/** Style for Grid and Grid Footer **/
|
||||||
private static final String HEADER_GRID_STYLE = "border: none; margin:0; padding: 0;";
|
private static final String HEADER_GRID_STYLE = "border: none; margin:0; padding: 0;";
|
||||||
|
|
||||||
|
/** default paging size when GridView is in DetailPane **/
|
||||||
private static final int DEFAULT_DETAIL_PAGE_SIZE = 10;
|
private static final int DEFAULT_DETAIL_PAGE_SIZE = 10;
|
||||||
|
|
||||||
|
/** default paging size for mobile client when GridView is in header panel **/
|
||||||
private static final int DEFAULT_MOBILE_PAGE_SIZE = 20;
|
private static final int DEFAULT_MOBILE_PAGE_SIZE = 20;
|
||||||
|
|
||||||
|
/** default paging size when GridView is in header panel **/
|
||||||
private static final int DEFAULT_PAGE_SIZE = 20;
|
private static final int DEFAULT_PAGE_SIZE = 20;
|
||||||
|
|
||||||
|
/** minimum column width **/
|
||||||
private static final int MIN_COLUMN_WIDTH = 100;
|
private static final int MIN_COLUMN_WIDTH = 100;
|
||||||
|
|
||||||
|
/** maximum column width **/
|
||||||
private static final int MAX_COLUMN_WIDTH = 300;
|
private static final int MAX_COLUMN_WIDTH = 300;
|
||||||
|
|
||||||
|
/** minimum column width for combobox field **/
|
||||||
private static final int MIN_COMBOBOX_WIDTH = 160;
|
private static final int MIN_COMBOBOX_WIDTH = 160;
|
||||||
|
|
||||||
|
/** minimum column width for numeric field **/
|
||||||
private static final int MIN_NUMERIC_COL_WIDTH = 120;
|
private static final int MIN_NUMERIC_COL_WIDTH = 120;
|
||||||
|
|
||||||
|
/** GridView boolean attribute to indicate ON_POST_SELECTED_ROW_CHANGED_EVENT have been posted in current execution cycle **/
|
||||||
private static final String ATTR_ON_POST_SELECTED_ROW_CHANGED = "org.adempiere.webui.adwindow.GridView.onPostSelectedRowChanged";
|
private static final String ATTR_ON_POST_SELECTED_ROW_CHANGED = "org.adempiere.webui.adwindow.GridView.onPostSelectedRowChanged";
|
||||||
|
|
||||||
/** Static Logger */
|
/** Static Logger */
|
||||||
private static CLogger s_log = CLogger.getCLogger (GridView.class);
|
private static CLogger s_log = CLogger.getCLogger (GridView.class);
|
||||||
|
|
||||||
|
/** data grid instance **/
|
||||||
private Grid listbox = null;
|
private Grid listbox = null;
|
||||||
|
|
||||||
private int pageSize = DEFAULT_PAGE_SIZE;
|
private int pageSize = DEFAULT_PAGE_SIZE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list field display in grid mode, in case user customize grid
|
* list field display in grid mode, in case user customize grid
|
||||||
* this list container only customize list.
|
* this list container only display list.
|
||||||
*/
|
*/
|
||||||
private GridField[] gridField;
|
private GridField[] gridFields;
|
||||||
|
|
||||||
|
/** GridTable model for GridTab **/
|
||||||
private AbstractTableModel tableModel;
|
private AbstractTableModel tableModel;
|
||||||
|
|
||||||
private int numColumns = 5;
|
private int numColumns = 5;
|
||||||
|
|
||||||
private int windowNo;
|
private int windowNo;
|
||||||
|
|
||||||
|
/** GridTab that back this GridView **/
|
||||||
private GridTab gridTab;
|
private GridTab gridTab;
|
||||||
|
|
||||||
|
/** true if this GridView instance have been init with GridTab **/
|
||||||
private boolean init;
|
private boolean init;
|
||||||
|
|
||||||
|
/** Zk List model for {@link #tableModel} **/
|
||||||
private GridTableListModel listModel;
|
private GridTableListModel listModel;
|
||||||
|
|
||||||
private Paging paging;
|
private Paging paging;
|
||||||
|
|
||||||
|
/** Row renderer for this GridView instance **/
|
||||||
private GridTabRowRenderer renderer;
|
private GridTabRowRenderer renderer;
|
||||||
|
|
||||||
|
/** Footer for paging **/
|
||||||
private Div gridFooter;
|
private Div gridFooter;
|
||||||
|
|
||||||
|
/** true if current row is always in edit mode **/
|
||||||
private boolean modeless = true;
|
private boolean modeless = true;
|
||||||
|
|
||||||
|
/** column click by user **/
|
||||||
private String columnOnClick;
|
private String columnOnClick;
|
||||||
|
|
||||||
|
/** AD window content part that own this GridView instance **/
|
||||||
private AbstractADWindowContent windowPanel;
|
private AbstractADWindowContent windowPanel;
|
||||||
|
|
||||||
|
/** true when grid is refreshing its data **/
|
||||||
private boolean refreshing;
|
private boolean refreshing;
|
||||||
|
|
||||||
|
/** AD_Field_ID:Column Width **/
|
||||||
private Map<Integer, String> columnWidthMap;
|
private Map<Integer, String> columnWidthMap;
|
||||||
|
|
||||||
|
/** true if it is in DetailPane **/
|
||||||
private boolean detailPaneMode;
|
private boolean detailPaneMode;
|
||||||
|
|
||||||
|
/** checkbox to select all row of current page **/
|
||||||
protected Checkbox selectAll;
|
protected Checkbox selectAll;
|
||||||
|
|
||||||
boolean isHasCustomizeData = false;
|
/** true if there are AD_Tab_Customization for GridTab **/
|
||||||
|
protected boolean isHasCustomizeData = false;
|
||||||
|
|
||||||
|
/** true to add row indicator column after selection column (i.e second column) **/
|
||||||
private boolean showCurrentRowIndicatorColumn = true;
|
private boolean showCurrentRowIndicatorColumn = true;
|
||||||
|
|
||||||
|
/** true if auto hide empty column feature is enable **/
|
||||||
private String m_isAutoHideEmptyColumn;
|
private String m_isAutoHideEmptyColumn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default constructor
|
||||||
|
*/
|
||||||
public GridView()
|
public GridView()
|
||||||
{
|
{
|
||||||
this(0);
|
this(0);
|
||||||
|
@ -214,6 +251,9 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
addEventListener("onCustomizeGrid", this);
|
addEventListener("onCustomizeGrid", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create data grid instances
|
||||||
|
*/
|
||||||
protected void createListbox() {
|
protected void createListbox() {
|
||||||
listbox = new Grid();
|
listbox = new Grid();
|
||||||
listbox.setSizedByContent(false);
|
listbox.setSizedByContent(false);
|
||||||
|
@ -223,6 +263,11 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
listbox.setEmptyMessage(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Processing")));
|
listbox.setEmptyMessage(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Processing")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* turn on/off detail pane mode
|
||||||
|
* @param detailPaneMode
|
||||||
|
* @param gridTab
|
||||||
|
*/
|
||||||
public void setDetailPaneMode(boolean detailPaneMode, GridTab gridTab) {
|
public void setDetailPaneMode(boolean detailPaneMode, GridTab gridTab) {
|
||||||
if (this.detailPaneMode != detailPaneMode) {
|
if (this.detailPaneMode != detailPaneMode) {
|
||||||
this.detailPaneMode = detailPaneMode;
|
this.detailPaneMode = detailPaneMode;
|
||||||
|
@ -231,7 +276,10 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the number of records to be displayed in detail grid */
|
/**
|
||||||
|
* @param gridTab
|
||||||
|
* @return the number of records to be displayed in detail grid
|
||||||
|
*/
|
||||||
private int getDetailPageSize(GridTab gridTab) {
|
private int getDetailPageSize(GridTab gridTab) {
|
||||||
int size = DEFAULT_DETAIL_PAGE_SIZE;
|
int size = DEFAULT_DETAIL_PAGE_SIZE;
|
||||||
String pageDetailSizes = MSysConfig.getValue(MSysConfig.ZK_PAGING_DETAIL_SIZE, Env.getAD_Client_ID(Env.getCtx()));
|
String pageDetailSizes = MSysConfig.getValue(MSysConfig.ZK_PAGING_DETAIL_SIZE, Env.getAD_Client_ID(Env.getCtx()));
|
||||||
|
@ -279,10 +327,16 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if it is in detail pane mode
|
||||||
|
*/
|
||||||
public boolean isDetailPaneMode() {
|
public boolean isDetailPaneMode() {
|
||||||
return this.detailPaneMode;
|
return this.detailPaneMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update paging component with new paging size and notify model if paging size has change.
|
||||||
|
*/
|
||||||
private void updatePaging() {
|
private void updatePaging() {
|
||||||
if (paging != null && paging.getPageSize() != pageSize) {
|
if (paging != null && paging.getPageSize() != pageSize) {
|
||||||
paging.setPageSize(pageSize);
|
paging.setPageSize(pageSize);
|
||||||
|
@ -296,7 +350,7 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Init data grid
|
||||||
* @param gridTab
|
* @param gridTab
|
||||||
*/
|
*/
|
||||||
public void init(GridTab gridTab)
|
public void init(GridTab gridTab)
|
||||||
|
@ -324,6 +378,9 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
showRecordsCount();
|
showRecordsCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update {@link DetailPane} status with record count
|
||||||
|
*/
|
||||||
private void showRecordsCount() {
|
private void showRecordsCount() {
|
||||||
Component parent = this.getParent();
|
Component parent = this.getParent();
|
||||||
while (parent != null) {
|
while (parent != null) {
|
||||||
|
@ -337,6 +394,10 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup {@link #gridFields} from gridTab.
|
||||||
|
* @param gridTab
|
||||||
|
*/
|
||||||
private void setupFields(GridTab gridTab) {
|
private void setupFields(GridTab gridTab) {
|
||||||
this.gridTab = gridTab;
|
this.gridTab = gridTab;
|
||||||
gridTab.addStateChangeListener(this);
|
gridTab.addStateChangeListener(this);
|
||||||
|
@ -366,11 +427,11 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gridField = fieldList.toArray(new GridField[0]);
|
gridFields = fieldList.toArray(new GridField[0]);
|
||||||
if (customComponent.length == 2) {
|
if (customComponent.length == 2) {
|
||||||
String[] widths = customComponent[1].split("[,]");
|
String[] widths = customComponent[1].split("[,]");
|
||||||
for(int i = 0; i< gridField.length && i<widths.length; i++) {
|
for(int i = 0; i< gridFields.length && i<widths.length; i++) {
|
||||||
columnWidthMap.put(gridField[i].getAD_Field_ID(), widths[i]);
|
columnWidthMap.put(gridFields[i].getAD_Field_ID(), widths[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_isAutoHideEmptyColumn = tabCustomization.getIsAutoHideEmptyColumn();
|
m_isAutoHideEmptyColumn = tabCustomization.getIsAutoHideEmptyColumn();
|
||||||
|
@ -396,22 +457,22 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
gridField = new GridField[gridFieldList.size()];
|
gridFields = new GridField[gridFieldList.size()];
|
||||||
gridFieldList.toArray(gridField);
|
gridFieldList.toArray(gridFields);
|
||||||
}
|
}
|
||||||
numColumns = gridField.length;
|
numColumns = gridFields.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return true if data grid have been init with GridTab
|
||||||
*/
|
*/
|
||||||
public boolean isInit() {
|
public boolean isInit() {
|
||||||
return init;
|
return init;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* call when tab is activated
|
* Activate GridView (make visible or GridTab have been refreshed)
|
||||||
* @param gridTab
|
* @param gridTab
|
||||||
*/
|
*/
|
||||||
public void activate(GridTab gridTab) {
|
public void activate(GridTab gridTab) {
|
||||||
|
@ -425,7 +486,7 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* refresh after switching from form view
|
* Refresh data grid (after switching from form view or column setup has change)
|
||||||
* @param gridTab
|
* @param gridTab
|
||||||
*/
|
*/
|
||||||
public void refresh(GridTab gridTab) {
|
public void refresh(GridTab gridTab) {
|
||||||
|
@ -445,12 +506,15 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if data grid is refreshing data from GridTab
|
||||||
|
*/
|
||||||
public boolean isRefreshing() {
|
public boolean isRefreshing() {
|
||||||
return refreshing;
|
return refreshing;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update current row from model
|
* Update current row index from model
|
||||||
*/
|
*/
|
||||||
public void updateListIndex() {
|
public void updateListIndex() {
|
||||||
if (gridTab == null || !gridTab.isOpen()) return;
|
if (gridTab == null || !gridTab.isOpen()) return;
|
||||||
|
@ -506,23 +570,29 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hide paging component
|
||||||
|
*/
|
||||||
private void hidePagingControl() {
|
private void hidePagingControl() {
|
||||||
if (gridFooter.isVisible())
|
if (gridFooter.isVisible())
|
||||||
gridFooter.setVisible(false);
|
gridFooter.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* show paging component
|
||||||
|
*/
|
||||||
private void showPagingControl() {
|
private void showPagingControl() {
|
||||||
if (!gridFooter.isVisible())
|
if (!gridFooter.isVisible())
|
||||||
gridFooter.setVisible(true);
|
gridFooter.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* echo ON_POST_SELECTED_ROW_CHANGED_EVENT after current row index has changed
|
||||||
*/
|
*/
|
||||||
protected void echoOnPostSelectedRowChanged() {
|
protected void echoOnPostSelectedRowChanged() {
|
||||||
if (getAttribute(ATTR_ON_POST_SELECTED_ROW_CHANGED) == null) {
|
if (getAttribute(ATTR_ON_POST_SELECTED_ROW_CHANGED) == null) {
|
||||||
setAttribute(ATTR_ON_POST_SELECTED_ROW_CHANGED, Boolean.TRUE);
|
setAttribute(ATTR_ON_POST_SELECTED_ROW_CHANGED, Boolean.TRUE);
|
||||||
Events.echoEvent("onPostSelectedRowChanged", this, null);
|
Events.echoEvent(ON_POST_SELECTED_ROW_CHANGED_EVENT, this, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,11 +605,17 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
this.pageSize = pageSize;
|
this.pageSize = pageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove all components
|
||||||
|
*/
|
||||||
public void clear()
|
public void clear()
|
||||||
{
|
{
|
||||||
this.getChildren().clear();
|
this.getChildren().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup {@link Columns} of data grid
|
||||||
|
*/
|
||||||
private void setupColumns()
|
private void setupColumns()
|
||||||
{
|
{
|
||||||
if (init) return;
|
if (init) return;
|
||||||
|
@ -595,36 +671,36 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
for (int i = 0; i < numColumns; i++)
|
for (int i = 0; i < numColumns; i++)
|
||||||
{
|
{
|
||||||
// IDEMPIERE-2148: when has tab customize, ignore check properties isDisplayedGrid
|
// IDEMPIERE-2148: when has tab customize, ignore check properties isDisplayedGrid
|
||||||
if ((isHasCustomizeData || gridField[i].isDisplayedGrid()) && !gridField[i].isToolbarOnlyButton())
|
if ((isHasCustomizeData || gridFields[i].isDisplayedGrid()) && !gridFields[i].isToolbarOnlyButton())
|
||||||
{
|
{
|
||||||
colnames.put(index, gridField[i].getHeader());
|
colnames.put(index, gridFields[i].getHeader());
|
||||||
index++;
|
index++;
|
||||||
org.zkoss.zul.Column column = new Column();
|
org.zkoss.zul.Column column = new Column();
|
||||||
column.setAttribute(GRID_VIEW_GRID_FIELD_INDEX, i);
|
column.setAttribute(GRID_VIEW_GRID_FIELD_INDEX, i);
|
||||||
column.setHeight("2em");
|
column.setHeight("2em");
|
||||||
int colindex =tableModel.findColumn(gridField[i].getColumnName());
|
int colindex =tableModel.findColumn(gridFields[i].getColumnName());
|
||||||
column.setSortAscending(new SortComparator(colindex, true, Env.getLanguage(Env.getCtx())));
|
column.setSortAscending(new SortComparator(colindex, true, Env.getLanguage(Env.getCtx())));
|
||||||
column.setSortDescending(new SortComparator(colindex, false, Env.getLanguage(Env.getCtx())));
|
column.setSortDescending(new SortComparator(colindex, false, Env.getLanguage(Env.getCtx())));
|
||||||
//IDEMPIERE-2898 - UX: Field only showing title at header on grid
|
//IDEMPIERE-2898 - UX: Field only showing title at header on grid
|
||||||
if( gridField[i].isFieldOnly() )
|
if( gridFields[i].isFieldOnly() )
|
||||||
column.setLabel("");
|
column.setLabel("");
|
||||||
else
|
else
|
||||||
column.setLabel(gridField[i].getHeader());
|
column.setLabel(gridFields[i].getHeader());
|
||||||
|
|
||||||
if (columnWidthMap != null && columnWidthMap.get(gridField[i].getAD_Field_ID()) != null && !columnWidthMap.get(gridField[i].getAD_Field_ID()).equals("")) {
|
if (columnWidthMap != null && columnWidthMap.get(gridFields[i].getAD_Field_ID()) != null && !columnWidthMap.get(gridFields[i].getAD_Field_ID()).equals("")) {
|
||||||
ZKUpdateUtil.setWidth(column, columnWidthMap.get(gridField[i].getAD_Field_ID()));
|
ZKUpdateUtil.setWidth(column, columnWidthMap.get(gridFields[i].getAD_Field_ID()));
|
||||||
} else {
|
} else {
|
||||||
if (gridField[i].getDisplayType()==DisplayType.YesNo) {
|
if (gridFields[i].getDisplayType()==DisplayType.YesNo) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
ZKUpdateUtil.setHflex(column, "min");
|
ZKUpdateUtil.setHflex(column, "min");
|
||||||
} else {
|
} else {
|
||||||
int estimatedWidth=60;
|
int estimatedWidth=60;
|
||||||
int headerWidth = (gridField[i].getHeader().length()+2) * 8;
|
int headerWidth = (gridFields[i].getHeader().length()+2) * 8;
|
||||||
if (headerWidth > estimatedWidth)
|
if (headerWidth > estimatedWidth)
|
||||||
estimatedWidth = headerWidth;
|
estimatedWidth = headerWidth;
|
||||||
ZKUpdateUtil.setWidth(column, estimatedWidth+"px");
|
ZKUpdateUtil.setWidth(column, estimatedWidth+"px");
|
||||||
}
|
}
|
||||||
} else if (DisplayType.isNumeric(gridField[i].getDisplayType()) && "Line".equals(gridField[i].getColumnName())) {
|
} else if (DisplayType.isNumeric(gridFields[i].getDisplayType()) && "Line".equals(gridFields[i].getColumnName())) {
|
||||||
//special treatment for line
|
//special treatment for line
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
ZKUpdateUtil.setHflex(column, "min");
|
ZKUpdateUtil.setHflex(column, "min");
|
||||||
|
@ -632,33 +708,33 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
ZKUpdateUtil.setWidth(column, "60px");
|
ZKUpdateUtil.setWidth(column, "60px");
|
||||||
} else {
|
} else {
|
||||||
int estimatedWidth = 0;
|
int estimatedWidth = 0;
|
||||||
if (DisplayType.isNumeric(gridField[i].getDisplayType()))
|
if (DisplayType.isNumeric(gridFields[i].getDisplayType()))
|
||||||
estimatedWidth = MIN_NUMERIC_COL_WIDTH;
|
estimatedWidth = MIN_NUMERIC_COL_WIDTH;
|
||||||
else if (DisplayType.isLookup(gridField[i].getDisplayType()))
|
else if (DisplayType.isLookup(gridFields[i].getDisplayType()))
|
||||||
estimatedWidth = MIN_COMBOBOX_WIDTH;
|
estimatedWidth = MIN_COMBOBOX_WIDTH;
|
||||||
else if (DisplayType.isText(gridField[i].getDisplayType()))
|
else if (DisplayType.isText(gridFields[i].getDisplayType()))
|
||||||
estimatedWidth = gridField[i].getDisplayLength() * 8;
|
estimatedWidth = gridFields[i].getDisplayLength() * 8;
|
||||||
else
|
else
|
||||||
estimatedWidth = MIN_COLUMN_WIDTH;
|
estimatedWidth = MIN_COLUMN_WIDTH;
|
||||||
|
|
||||||
int headerWidth = (gridField[i].getHeader().length()+2) * 8;
|
int headerWidth = (gridFields[i].getHeader().length()+2) * 8;
|
||||||
if (headerWidth > estimatedWidth)
|
if (headerWidth > estimatedWidth)
|
||||||
estimatedWidth = headerWidth;
|
estimatedWidth = headerWidth;
|
||||||
|
|
||||||
//hflex=min for first column not working well
|
//hflex=min for first column not working well
|
||||||
if (i > 0 && !ClientInfo.isMobile())
|
if (i > 0 && !ClientInfo.isMobile())
|
||||||
{
|
{
|
||||||
if (DisplayType.isLookup(gridField[i].getDisplayType()))
|
if (DisplayType.isLookup(gridFields[i].getDisplayType()))
|
||||||
{
|
{
|
||||||
if (headerWidth > MIN_COMBOBOX_WIDTH)
|
if (headerWidth > MIN_COMBOBOX_WIDTH)
|
||||||
ZKUpdateUtil.setHflex(column, "min");
|
ZKUpdateUtil.setHflex(column, "min");
|
||||||
}
|
}
|
||||||
else if (DisplayType.isNumeric(gridField[i].getDisplayType()))
|
else if (DisplayType.isNumeric(gridFields[i].getDisplayType()))
|
||||||
{
|
{
|
||||||
if (headerWidth > MIN_NUMERIC_COL_WIDTH)
|
if (headerWidth > MIN_NUMERIC_COL_WIDTH)
|
||||||
ZKUpdateUtil.setHflex(column, "min");
|
ZKUpdateUtil.setHflex(column, "min");
|
||||||
}
|
}
|
||||||
else if (!DisplayType.isText(gridField[i].getDisplayType()))
|
else if (!DisplayType.isText(gridFields[i].getDisplayType()))
|
||||||
{
|
{
|
||||||
if (headerWidth > MIN_COLUMN_WIDTH)
|
if (headerWidth > MIN_COLUMN_WIDTH)
|
||||||
ZKUpdateUtil.setHflex(column, "min");
|
ZKUpdateUtil.setHflex(column, "min");
|
||||||
|
@ -689,6 +765,9 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render data grid
|
||||||
|
*/
|
||||||
private void render()
|
private void render()
|
||||||
{
|
{
|
||||||
updateEmptyMessage();
|
updateEmptyMessage();
|
||||||
|
@ -722,7 +801,7 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* auto hide empty columns
|
* Auto hide empty columns (if auto hide empty column feature have been turned on)
|
||||||
*/
|
*/
|
||||||
protected void autoHideEmptyColumns() {
|
protected void autoHideEmptyColumns() {
|
||||||
if (!isAutoHideEmptyColumns()) {
|
if (!isAutoHideEmptyColumns()) {
|
||||||
|
@ -748,7 +827,7 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
continue;
|
continue;
|
||||||
int index = (Integer)value;
|
int index = (Integer)value;
|
||||||
for(int i = 0; i < gridTabFields.length; i++) {
|
for(int i = 0; i < gridTabFields.length; i++) {
|
||||||
if (gridField[index].getAD_Field_ID() == gridTabFields[i].getAD_Field_ID()) {
|
if (gridFields[index].getAD_Field_ID() == gridTabFields[i].getAD_Field_ID()) {
|
||||||
indexMap.put(index, i);
|
indexMap.put(index, i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -771,14 +850,14 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
if (paging != null && paging.getPageSize() > 0) {
|
if (paging != null && paging.getPageSize() > 0) {
|
||||||
rowIndex = (paging.getActivePage() * paging.getPageSize()) + rowIndex;
|
rowIndex = (paging.getActivePage() * paging.getPageSize()) + rowIndex;
|
||||||
}
|
}
|
||||||
String display = renderer.getDisplayTextWithEditorCheck(values[valueIndex], gridField[index], rowIndex);
|
String display = renderer.getDisplayTextWithEditorCheck(values[valueIndex], gridFields[index], rowIndex);
|
||||||
if (!Util.isEmpty(display, true)) {
|
if (!Util.isEmpty(display, true)) {
|
||||||
hideColumn = false;
|
hideColumn = false;
|
||||||
break;
|
break;
|
||||||
} else if (gridTab.getCurrentRow() == rowIndex && gridTab.isNew()) {
|
} else if (gridTab.getCurrentRow() == rowIndex && gridTab.isNew()) {
|
||||||
if (gridField[index].isEditable(false) && (gridField[index].isMandatory(false) || !Util.isEmpty(gridField[index].getVO().MandatoryLogic)
|
if (gridFields[index].isEditable(false) && (gridFields[index].isMandatory(false) || !Util.isEmpty(gridFields[index].getVO().MandatoryLogic)
|
||||||
|| !Util.isEmpty(gridField[index].getVO().DisplayLogic)
|
|| !Util.isEmpty(gridFields[index].getVO().DisplayLogic)
|
||||||
|| !Util.isEmpty(gridField[index].getVO().ReadOnlyLogic))) {
|
|| !Util.isEmpty(gridFields[index].getVO().ReadOnlyLogic))) {
|
||||||
hideColumn = false;
|
hideColumn = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -808,6 +887,9 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return if auto hide empty columns feature have been turned on
|
||||||
|
*/
|
||||||
private boolean isAutoHideEmptyColumns() {
|
private boolean isAutoHideEmptyColumns() {
|
||||||
if (!Util.isEmpty(m_isAutoHideEmptyColumn, true))
|
if (!Util.isEmpty(m_isAutoHideEmptyColumn, true))
|
||||||
return "Y".equalsIgnoreCase(m_isAutoHideEmptyColumn);
|
return "Y".equalsIgnoreCase(m_isAutoHideEmptyColumn);
|
||||||
|
@ -815,6 +897,9 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
return MSysConfig.getBooleanValue(MSysConfig.ZK_GRID_AUTO_HIDE_EMPTY_COLUMNS, false, Env.getAD_Client_ID(Env.getCtx()));
|
return MSysConfig.getBooleanValue(MSysConfig.ZK_GRID_AUTO_HIDE_EMPTY_COLUMNS, false, Env.getAD_Client_ID(Env.getCtx()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show zero records for processing message
|
||||||
|
*/
|
||||||
private void updateEmptyMessage() {
|
private void updateEmptyMessage() {
|
||||||
if (gridTab.getRowCount() == 0)
|
if (gridTab.getRowCount() == 0)
|
||||||
{
|
{
|
||||||
|
@ -826,6 +911,10 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update {@link #listModel} with {@link #tableModel} changes.
|
||||||
|
* Re-create {@link #renderer}.
|
||||||
|
*/
|
||||||
private void updateModel() {
|
private void updateModel() {
|
||||||
if (listModel != null)
|
if (listModel != null)
|
||||||
((GridTable)tableModel).removeTableModelListener(listModel);
|
((GridTable)tableModel).removeTableModelListener(listModel);
|
||||||
|
@ -846,13 +935,14 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* deactivate panel
|
* Deactivate Grid View. Stop editing if current row is in edit mode.
|
||||||
*/
|
*/
|
||||||
public void deactivate() {
|
public void deactivate() {
|
||||||
if (renderer != null && renderer.isEditing())
|
if (renderer != null && renderer.isEditing())
|
||||||
renderer.stopEditing(true);
|
renderer.stopEditing(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onEvent(Event event) throws Exception
|
public void onEvent(Event event) throws Exception
|
||||||
{
|
{
|
||||||
if (event == null)
|
if (event == null)
|
||||||
|
@ -872,15 +962,15 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
if (cmp.getParent() instanceof org.zkoss.zul.Row)
|
if (cmp.getParent() instanceof org.zkoss.zul.Row)
|
||||||
{
|
{
|
||||||
row = (Row) cmp.getParent();
|
row = (Row) cmp.getParent();
|
||||||
columnName = (String) cmp.getAttribute("columnName");
|
columnName = (String) cmp.getAttribute(GridTabRowRenderer.COLUMN_NAME_ATTR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (row != null)
|
if (row != null)
|
||||||
{
|
{
|
||||||
//click on selected row to enter edit mode
|
|
||||||
if (row == renderer.getCurrentRow())
|
if (row == renderer.getCurrentRow())
|
||||||
{
|
{
|
||||||
|
//click on selected row to enter edit mode
|
||||||
if (!renderer.isEditing())
|
if (!renderer.isEditing())
|
||||||
{
|
{
|
||||||
renderer.editCurrentRow();
|
renderer.editCurrentRow();
|
||||||
|
@ -892,6 +982,7 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//change selection of current row
|
||||||
int index = listbox.getRows().getChildren().indexOf(row);
|
int index = listbox.getRows().getChildren().indexOf(row);
|
||||||
if (index >= 0 ) {
|
if (index >= 0 ) {
|
||||||
columnOnClick = columnName;
|
columnOnClick = columnName;
|
||||||
|
@ -941,6 +1032,10 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param gridView
|
||||||
|
* @return {@link Center} that own this GridView instance
|
||||||
|
*/
|
||||||
private Center findCenter(GridView gridView) {
|
private Center findCenter(GridView gridView) {
|
||||||
if (gridView == null)
|
if (gridView == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -953,6 +1048,9 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if all row of current page is selected
|
||||||
|
*/
|
||||||
private boolean isAllSelected() {
|
private boolean isAllSelected() {
|
||||||
org.zkoss.zul.Rows rows = listbox.getRows();
|
org.zkoss.zul.Rows rows = listbox.getRows();
|
||||||
List<Component> childs = rows.getChildren();
|
List<Component> childs = rows.getChildren();
|
||||||
|
@ -974,6 +1072,10 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
return all;
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* turn on/off select all rows for current page
|
||||||
|
* @param b
|
||||||
|
*/
|
||||||
private void toggleSelectionForAll(boolean b) {
|
private void toggleSelectionForAll(boolean b) {
|
||||||
org.zkoss.zul.Rows rows = listbox.getRows();
|
org.zkoss.zul.Rows rows = listbox.getRows();
|
||||||
List<Component> childs = rows.getChildren();
|
List<Component> childs = rows.getChildren();
|
||||||
|
@ -995,6 +1097,10 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update list model and data grid with new current row index
|
||||||
|
* @param index
|
||||||
|
*/
|
||||||
private void onSelectedRowChange(int index) {
|
private void onSelectedRowChange(int index) {
|
||||||
if (updateModelIndex(index)) {
|
if (updateModelIndex(index)) {
|
||||||
updateListIndex();
|
updateListIndex();
|
||||||
|
@ -1002,7 +1108,7 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event after the current selected row change
|
* Event after the current row index has changed.
|
||||||
*/
|
*/
|
||||||
public void onPostSelectedRowChanged() {
|
public void onPostSelectedRowChanged() {
|
||||||
removeAttribute(ATTR_ON_POST_SELECTED_ROW_CHANGED);
|
removeAttribute(ATTR_ON_POST_SELECTED_ROW_CHANGED);
|
||||||
|
@ -1060,6 +1166,9 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Focus to first editor field if GridView instance is not own by the selected detail tab panel.
|
||||||
|
*/
|
||||||
private void focusToFirstEditorIfNotDetailTab() {
|
private void focusToFirstEditorIfNotDetailTab() {
|
||||||
ADTabpanel adtabpanel = null;
|
ADTabpanel adtabpanel = null;
|
||||||
boolean setFocus = true;
|
boolean setFocus = true;
|
||||||
|
@ -1095,6 +1204,11 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
onPostSelectedRowChanged();
|
onPostSelectedRowChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Focus to row.
|
||||||
|
* If it is in edit mode, assume row is the current editing row.
|
||||||
|
* @param row
|
||||||
|
*/
|
||||||
private void focusToRow(org.zkoss.zul.Row row) {
|
private void focusToRow(org.zkoss.zul.Row row) {
|
||||||
if (renderer.isEditing()) {
|
if (renderer.isEditing()) {
|
||||||
if (columnOnClick != null && columnOnClick.trim().length() > 0) {
|
if (columnOnClick != null && columnOnClick.trim().length() > 0) {
|
||||||
|
@ -1123,7 +1237,7 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
for(Object element : list) {
|
for(Object element : list) {
|
||||||
if (element instanceof Div) {
|
if (element instanceof Div) {
|
||||||
Div div = (Div) element;
|
Div div = (Div) element;
|
||||||
if (columnOnClick.equals(div.getAttribute("columnName"))) {
|
if (columnOnClick.equals(div.getAttribute(GridTabRowRenderer.COLUMN_NAME_ATTR))) {
|
||||||
cmp = div.getFirstChild();
|
cmp = div.getFirstChild();
|
||||||
Clients.response(new AuScript(null, "idempiere.scrollToRow('" + cmp.getUuid() + "');"));
|
Clients.response(new AuScript(null, "idempiere.scrollToRow('" + cmp.getUuid() + "');"));
|
||||||
break;
|
break;
|
||||||
|
@ -1135,6 +1249,11 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param row
|
||||||
|
* @param index
|
||||||
|
* @return true if row have been rendered by row renderer
|
||||||
|
*/
|
||||||
private boolean isRowRendered(org.zkoss.zul.Row row, int index) {
|
private boolean isRowRendered(org.zkoss.zul.Row row, int index) {
|
||||||
if (row.getChildren().size() == 0) {
|
if (row.getChildren().size() == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1146,6 +1265,11 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update gridTab current row index.
|
||||||
|
* @param rowIndex row index of current page
|
||||||
|
* @return true if gridTab current row index has change
|
||||||
|
*/
|
||||||
private boolean updateModelIndex(int rowIndex) {
|
private boolean updateModelIndex(int rowIndex) {
|
||||||
if (pageSize > 0) {
|
if (pageSize > 0) {
|
||||||
int start = listModel.getPage() * listModel.getPageSize();
|
int start = listModel.getPage() * listModel.getPageSize();
|
||||||
|
@ -1214,6 +1338,11 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
selectAll.setChecked(false);
|
selectAll.setChecked(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform dynamic display for editors in list
|
||||||
|
* @param noData true if data grid is empty
|
||||||
|
* @param list
|
||||||
|
*/
|
||||||
private void dynamicDisplayEditors(boolean noData, List<WEditor> list) {
|
private void dynamicDisplayEditors(boolean noData, List<WEditor> list) {
|
||||||
for (WEditor comp : list)
|
for (WEditor comp : list)
|
||||||
{
|
{
|
||||||
|
@ -1242,6 +1371,9 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this GridView instance is own by DetailPane
|
||||||
|
*/
|
||||||
private boolean isDetailPane() {
|
private boolean isDetailPane() {
|
||||||
Component parent = this.getParent();
|
Component parent = this.getParent();
|
||||||
while (parent != null) {
|
while (parent != null) {
|
||||||
|
@ -1261,6 +1393,9 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
this.windowNo = windowNo;
|
this.windowNo = windowNo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If current row is in edit mode, set focus to first field editor
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void focus() {
|
public void focus() {
|
||||||
if (renderer != null && renderer.isEditing()) {
|
if (renderer != null && renderer.isEditing()) {
|
||||||
|
@ -1299,6 +1434,7 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Set AD window content part that own this GridView instance
|
||||||
* @param winPanel
|
* @param winPanel
|
||||||
*/
|
*/
|
||||||
public void setADWindowPanel(AbstractADWindowContent winPanel) {
|
public void setADWindowPanel(AbstractADWindowContent winPanel) {
|
||||||
|
@ -1307,6 +1443,9 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
renderer.setADWindowPanel(windowPanel);
|
renderer.setADWindowPanel(windowPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-Init GridView with cache gridTab.
|
||||||
|
*/
|
||||||
public void reInit() {
|
public void reInit() {
|
||||||
listbox.getChildren().clear();
|
listbox.getChildren().clear();
|
||||||
listbox.detach();
|
listbox.detach();
|
||||||
|
@ -1343,15 +1482,23 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
/**
|
/**
|
||||||
* list field display in grid mode, in case user customize grid
|
* list field display in grid mode, in case user customize grid
|
||||||
* this list container only customize list.
|
* this list container only customize list.
|
||||||
|
* @return GridField[]
|
||||||
*/
|
*/
|
||||||
public GridField[] getFields() {
|
public GridField[] getFields() {
|
||||||
return gridField;
|
return gridFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* call {@link #onEditCurrentRow(Event)}
|
||||||
|
*/
|
||||||
public void onEditCurrentRow() {
|
public void onEditCurrentRow() {
|
||||||
onEditCurrentRow(null);
|
onEditCurrentRow(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit current row
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
public void onEditCurrentRow(Event event) {
|
public void onEditCurrentRow(Event event) {
|
||||||
if (!renderer.isEditing()) {
|
if (!renderer.isEditing()) {
|
||||||
Row currentRow = renderer.getCurrentRow();
|
Row currentRow = renderer.getCurrentRow();
|
||||||
|
@ -1366,6 +1513,9 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If current row is in edit mode, set focus to first writable field editor.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void focusToFirstEditor() {
|
public void focusToFirstEditor() {
|
||||||
if (renderer.isEditing()) {
|
if (renderer.isEditing()) {
|
||||||
|
@ -1397,10 +1547,18 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parent component change notification from ADTabpanel that own this GridView instance (Usually
|
||||||
|
* after movement between Header and DetailPane panel).
|
||||||
|
* Re-position paging component.
|
||||||
|
*/
|
||||||
protected void onADTabPanelParentChanged() {
|
protected void onADTabPanelParentChanged() {
|
||||||
positionPagingControl();
|
positionPagingControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set position of paging component depends on whether GridView is in header or DetailPane panel.
|
||||||
|
*/
|
||||||
private void positionPagingControl() {
|
private void positionPagingControl() {
|
||||||
if (isDetailPane()) {
|
if (isDetailPane()) {
|
||||||
Component parent = this.getParent();
|
Component parent = this.getParent();
|
||||||
|
@ -1411,6 +1569,7 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
parent = parent.getParent();
|
parent = parent.getParent();
|
||||||
}
|
}
|
||||||
|
//use simplify paging presentation for DetailPane
|
||||||
if (paging != null)
|
if (paging != null)
|
||||||
paging.setDetailed(false);
|
paging.setDetailed(false);
|
||||||
}
|
}
|
||||||
|
@ -1426,12 +1585,18 @@ public class GridView extends Vlayout implements EventListener<Event>, IdSpace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* call editorTaverseCallback for all field editors.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void editorTraverse(Callback<WEditor> editorTaverseCallback) {
|
public void editorTraverse(Callback<WEditor> editorTaverseCallback) {
|
||||||
editorTraverse(editorTaverseCallback, renderer.getEditors());
|
editorTraverse(editorTaverseCallback, renderer.getEditors());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if current row indicator column is visible.
|
||||||
|
*/
|
||||||
public boolean isShowCurrentRowIndicatorColumn() {
|
public boolean isShowCurrentRowIndicatorColumn() {
|
||||||
return showCurrentRowIndicatorColumn;
|
return showCurrentRowIndicatorColumn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,54 +19,53 @@ import org.zkoss.zk.ui.event.Event;
|
||||||
import org.zkoss.zk.ui.event.EventListener;
|
import org.zkoss.zk.ui.event.EventListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Interface for header+details AD_Tabs UI for AD_Window.
|
||||||
* @author <a href="mailto:hengsin@gmail.com">Low Heng Sin</a>
|
* @author <a href="mailto:hengsin@gmail.com">Low Heng Sin</a>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface IADTabbox extends UIPart {
|
public interface IADTabbox extends UIPart {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return selected header tab index
|
||||||
* @return selected tab index
|
|
||||||
*/
|
*/
|
||||||
public int getSelectedIndex();
|
public int getSelectedIndex();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* set selected header tab
|
||||||
* @param i tab index
|
* @param i tab index
|
||||||
*/
|
*/
|
||||||
public void setSelectedIndex(int i);
|
public void setSelectedIndex(int i);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Change selected header tab index from oldTabIndex to newTabIndex
|
||||||
* @param oldTabIndex
|
* @param oldTabIndex
|
||||||
* @param newTabIndex
|
* @param newTabIndex
|
||||||
* @return
|
* @return true if selected tab successfully change to newTabIndex
|
||||||
*/
|
*/
|
||||||
public boolean updateSelectedIndex(int oldTabIndex, int newTabIndex);
|
public boolean updateSelectedIndex(int oldTabIndex, int newTabIndex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return selected tab panel reference
|
* @return selected header {@link IADTabpanel} instance
|
||||||
*/
|
*/
|
||||||
public IADTabpanel getSelectedTabpanel();
|
public IADTabpanel getSelectedTabpanel();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param fromIndex
|
* @param fromIndex
|
||||||
* @param toIndex
|
* @param toIndex
|
||||||
* @return boolean
|
* @return true if user can change selected tab from fromIndex to toIndex, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean canNavigateTo(int fromIndex, int toIndex);
|
public boolean canNavigateTo(int fromIndex, int toIndex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param index
|
* @param index
|
||||||
* @return boolean
|
* @return true if tab at index visible, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean isDisplay(int index);
|
public boolean isDisplay(int index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* add new tab (AD_Tab)
|
||||||
* @param tab
|
* @param tab {@link GridTab} for AD_Tab
|
||||||
* @param tabPanel
|
* @param tabPanel {@link IADTabpanel} instance for AD_Tab
|
||||||
*/
|
*/
|
||||||
public void addTab(GridTab tab, IADTabpanel tabPanel);
|
public void addTab(GridTab tab, IADTabpanel tabPanel);
|
||||||
|
|
||||||
|
@ -76,41 +75,43 @@ public interface IADTabbox extends UIPart {
|
||||||
public int getTabCount();
|
public int getTabCount();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Evaluate state of each tab after DataStatusEvent
|
||||||
* @param e
|
* @param e
|
||||||
*/
|
*/
|
||||||
public void evaluate(DataStatusEvent e);
|
public void evaluate(DataStatusEvent e);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return path to the active tab
|
* @return folder like parent/child path to the selected tab (for e.g Business Partner > Location)
|
||||||
*/
|
*/
|
||||||
public String getPath();
|
public String getPath();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Set event listener for tab selection change event
|
||||||
* @param listener
|
* @param listener
|
||||||
*/
|
*/
|
||||||
public void setSelectionEventListener(EventListener<Event> listener);
|
public void setSelectionEventListener(EventListener<Event> listener);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param index
|
* @param index tab index
|
||||||
* @return IADTabpanel
|
* @return {@link IADTabpanel} instance at index
|
||||||
*/
|
*/
|
||||||
public IADTabpanel getADTabpanel(int index);
|
public IADTabpanel getADTabpanel(int index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param gTab
|
* @param gTab
|
||||||
* @return IADTabpanel or null if not found
|
* @return {@link IADTabpanel} instance for gTab or null if not found
|
||||||
*/
|
*/
|
||||||
public IADTabpanel findADTabpanel(GridTab gTab);
|
public IADTabpanel findADTabpanel(GridTab gTab);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Set AD Window content part that own this IADTabbox instance.
|
||||||
* @param abstractADWindowPanel
|
* @param abstractADWindowPanel
|
||||||
*/
|
*/
|
||||||
public void setADWindowPanel(AbstractADWindowContent abstractADWindowPanel);
|
public void setADWindowPanel(AbstractADWindowContent abstractADWindowPanel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drill down to the current selected adtabpanel
|
* Edit current row of selected detail tab.
|
||||||
|
* The selected detail tab will become the new header tab.
|
||||||
*/
|
*/
|
||||||
public void onDetailRecord();
|
public void onDetailRecord();
|
||||||
|
|
||||||
|
@ -120,6 +121,7 @@ public interface IADTabbox extends UIPart {
|
||||||
public boolean isSortTab();
|
public boolean isSortTab();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Call {@link IADTabpanel#needSave(boolean, boolean)}
|
||||||
* @param rowChange
|
* @param rowChange
|
||||||
* @param onlyRealChange
|
* @param onlyRealChange
|
||||||
* @return true if there are changes pending to be save
|
* @return true if there are changes pending to be save
|
||||||
|
@ -127,54 +129,55 @@ public interface IADTabbox extends UIPart {
|
||||||
public boolean needSave(boolean rowChange, boolean onlyRealChange);
|
public boolean needSave(boolean rowChange, boolean onlyRealChange);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ignore all pending changes
|
* ignore/undo all pending changes
|
||||||
*/
|
*/
|
||||||
public void dataIgnore();
|
public void dataIgnore();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return selected header grid tab
|
* @return {@link GridTab} instance of header tab
|
||||||
*/
|
*/
|
||||||
public GridTab getSelectedGridTab();
|
public GridTab getSelectedGridTab();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Save changes
|
||||||
* @param onSaveEvent
|
* @param onSaveEvent
|
||||||
* @return true if save is successfull
|
* @return true if save is successful
|
||||||
*/
|
*/
|
||||||
public boolean dataSave(boolean onSaveEvent);
|
public boolean dataSave(boolean onSaveEvent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Update status text of {@link DetailPane}
|
||||||
* @param status
|
* @param status
|
||||||
* @param error
|
* @param error
|
||||||
*/
|
*/
|
||||||
public void setDetailPaneStatusMessage(String status, boolean error);
|
public void setDetailPaneStatusMessage(String status, boolean error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the currently selected detail adtabpanel
|
* @return the selected detail {@link IADTabpanel} instance
|
||||||
*/
|
*/
|
||||||
IADTabpanel getSelectedDetailADTabpanel();
|
IADTabpanel getSelectedDetailADTabpanel();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return dirty adtabpanel that need save ( if any )
|
* @return dirty {@link IADTabpanel} that need save ( if any )
|
||||||
*/
|
*/
|
||||||
IADTabpanel getDirtyADTabpanel();
|
IADTabpanel getDirtyADTabpanel();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Call {@link DetailPane#updateToolbar(boolean, boolean)}
|
||||||
* @param changed
|
* @param changed true if header tab has changed
|
||||||
* @param readOnly
|
* @param readOnly true if header tab is readonly
|
||||||
*/
|
*/
|
||||||
public void updateDetailPaneToolbar(boolean changed, boolean readOnly);
|
public void updateDetailPaneToolbar(boolean changed, boolean readOnly);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Set selected tab of {@link DetailPane} to tabIndex.
|
||||||
* @param tabIndex
|
* @param tabIndex
|
||||||
* @param currentRow
|
* @param currentRow set current row of tab at tabIndex to currentRow
|
||||||
*/
|
*/
|
||||||
public void setDetailPaneSelectedTab(int tabIndex, int currentRow);
|
public void setDetailPaneSelectedTab(int tabIndex, int currentRow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if all the tabs of detail pane have been linked up with adtabpanel
|
* @return true if all the tabs of detail pane have been linked up with header tab
|
||||||
*/
|
*/
|
||||||
public boolean isDetailPaneLoaded();
|
public boolean isDetailPaneLoaded();
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,16 @@ import org.zkoss.zul.Button;
|
||||||
import org.zkoss.zul.Toolbar;
|
import org.zkoss.zul.Toolbar;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for UI component that edit/display record using ad_tab definitions
|
* Interface for AD_Tab UI (with all the AD_Fields definition)
|
||||||
* @author Low Heng Sin
|
* @author Low Heng Sin
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface IADTabpanel extends Component, Evaluatee {
|
public interface IADTabpanel extends Component, Evaluatee {
|
||||||
|
|
||||||
|
/** Activate/Deactivate event for IADTabpanel. Fire for init or after tab selection changed. **/
|
||||||
public static final String ON_ACTIVATE_EVENT = "onActivate";
|
public static final String ON_ACTIVATE_EVENT = "onActivate";
|
||||||
|
|
||||||
|
/** Component boolean attribute to indicate ON_ACTIVATE_EVENT have been posted for the current execution cycle **/
|
||||||
public static final String ATTR_ON_ACTIVATE_POSTED = "org.adempiere.webui.adwindow.IADTabpanel.onActivatePosted";
|
public static final String ATTR_ON_ACTIVATE_POSTED = "org.adempiere.webui.adwindow.IADTabpanel.onActivatePosted";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,12 +50,12 @@ public interface IADTabpanel extends Component, Evaluatee {
|
||||||
public int getTabLevel();
|
public int getTabLevel();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return tablename
|
* @return table name from GridTab
|
||||||
*/
|
*/
|
||||||
public String getTableName();
|
public String getTableName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return record ID
|
* @return record ID of current row
|
||||||
*/
|
*/
|
||||||
public int getRecord_ID();
|
public int getRecord_ID();
|
||||||
|
|
||||||
|
@ -62,40 +65,39 @@ public interface IADTabpanel extends Component, Evaluatee {
|
||||||
public boolean isCurrent();
|
public boolean isCurrent();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return title of tab
|
||||||
* @return title
|
|
||||||
*/
|
*/
|
||||||
public String getTitle();
|
public String getTitle();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the panel
|
* Layout fields of the tab panel
|
||||||
*/
|
*/
|
||||||
public void createUI();
|
public void createUI();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return {@link GridTab} instance that back this IADTabpanel instance
|
||||||
* @return GridTab
|
|
||||||
*/
|
*/
|
||||||
public GridTab getGridTab();
|
public GridTab getGridTab();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* activate/deactivate the panel
|
* Activate/deactivate this IADTabpanel instance.
|
||||||
|
* Call by init or after tab selection changed.
|
||||||
* @param b
|
* @param b
|
||||||
*/
|
*/
|
||||||
public void activate(boolean b);
|
public void activate(boolean b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* retrieve data from db
|
* Execute query through the backed {@link GridTab} instance.
|
||||||
*/
|
*/
|
||||||
public void query();
|
public void query();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refresh from db
|
* Refresh data through the backed {@link GridTab} instance.
|
||||||
*/
|
*/
|
||||||
public void refresh();
|
public void refresh();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* retrieve data from db
|
* Call {@link GridTab#query(boolean, int, int)}
|
||||||
* @param currentRows
|
* @param currentRows
|
||||||
* @param currentDays
|
* @param currentDays
|
||||||
* @param maxRows
|
* @param maxRows
|
||||||
|
@ -103,58 +105,56 @@ public interface IADTabpanel extends Component, Evaluatee {
|
||||||
public void query(boolean currentRows, int currentDays, int maxRows);
|
public void query(boolean currentRows, int currentDays, int maxRows);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle between grid and form view
|
* Switch between grid/list and form view
|
||||||
*/
|
*/
|
||||||
public void switchRowPresentation();
|
public void switchRowPresentation();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dynamic update of field properties ( visibility, filter and mandatory )
|
* Dynamic update of every field's UI properties ( visibility, filter and mandatory ).
|
||||||
* @param i
|
* @param col optional column name
|
||||||
*/
|
*/
|
||||||
public void dynamicDisplay(int i);
|
public void dynamicDisplay(int col);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* After save event
|
* Handle after save event
|
||||||
* @param onSaveEvent
|
* @param onSaveEvent
|
||||||
*/
|
*/
|
||||||
public void afterSave(boolean onSaveEvent);
|
public void afterSave(boolean onSaveEvent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enter key event
|
* Handle enter key event
|
||||||
* @return true if the event is process
|
* @return true if the event is process
|
||||||
*/
|
*/
|
||||||
public boolean onEnterKey();
|
public boolean onEnterKey();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return boolean
|
* @return true if current presentation of the tab panel is grid/list view
|
||||||
*/
|
*/
|
||||||
public boolean isGridView();
|
public boolean isGridView();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the panel have been activated
|
* @return true if the tab panel have been activated
|
||||||
*/
|
*/
|
||||||
public boolean isActivated();
|
public boolean isActivated();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Turn on/off detail mode, i.e either tab panel is currently a header or detail tab of the UI.
|
||||||
* @param detailMode
|
* @param detailMode
|
||||||
*/
|
*/
|
||||||
public void setDetailPaneMode(boolean detailMode);
|
public void setDetailPaneMode(boolean detailMode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return true if the panel is in detail mode (i.e a detail tab in DetailPane)
|
||||||
* @return true if the panel is in detailpane node
|
|
||||||
*/
|
*/
|
||||||
public boolean isDetailPaneMode();
|
public boolean isDetailPaneMode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return {@link GridView} instance
|
||||||
* @return gridview instance
|
|
||||||
*/
|
*/
|
||||||
public GridView getGridView();
|
public GridView getGridView();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Call {@link GridTab#needSave(boolean, boolean)}
|
||||||
* @param rowChange
|
* @param rowChange
|
||||||
* @param onlyRealChange
|
* @param onlyRealChange
|
||||||
* @return true if there are pending changes
|
* @return true if there are pending changes
|
||||||
|
@ -162,70 +162,71 @@ public interface IADTabpanel extends Component, Evaluatee {
|
||||||
public boolean needSave(boolean rowChange, boolean onlyRealChange);
|
public boolean needSave(boolean rowChange, boolean onlyRealChange);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Save changes.
|
||||||
|
* Call {@link GridTab#dataSave(boolean)}
|
||||||
* @param onSaveEvent
|
* @param onSaveEvent
|
||||||
* @return true if the save operation completed successfully
|
* @return true if the save operation completed successfully
|
||||||
*/
|
*/
|
||||||
public boolean dataSave(boolean onSaveEvent);
|
public boolean dataSave(boolean onSaveEvent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Set tab number/sequence within an AD_Window
|
||||||
* @param tabNo
|
* @param tabNo
|
||||||
*/
|
*/
|
||||||
public void setTabNo(int tabNo);
|
public void setTabNo(int tabNo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @return tab no ( ad_tab.tabno )
|
* @return tab no ( ad_tab.tabno )
|
||||||
*/
|
*/
|
||||||
public int getTabNo();
|
public int getTabNo();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Set the {@link DetailPane} part that own this IADTabpanel instance
|
||||||
* @param detailPane
|
* @param detailPane
|
||||||
*/
|
*/
|
||||||
public void setDetailPane(DetailPane detailPane);
|
public void setDetailPane(DetailPane detailPane);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return the {@link DetailPane} part that own this IADTabpanel instance
|
||||||
* @return detailpane
|
|
||||||
*/
|
*/
|
||||||
public DetailPane getDetailPane();
|
public DetailPane getDetailPane();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reset detail data grid when parent tab current record is new and not saved yet
|
* Reset detail data grid when parent tab current record is new and not saved yet.
|
||||||
|
* Call {@link GridTab#resetDetailForNewParentRecord()}
|
||||||
*/
|
*/
|
||||||
public void resetDetailForNewParentRecord();
|
public void resetDetailForNewParentRecord();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return treepanel instance
|
* @return {@link ADTreePanel} instance
|
||||||
*/
|
*/
|
||||||
public ADTreePanel getTreePanel();
|
public ADTreePanel getTreePanel();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Quick Form Button Enabled/Disabled
|
* @return true if Quick Form Button is Enabled
|
||||||
*/
|
*/
|
||||||
public boolean isEnableQuickFormButton();
|
public boolean isEnableQuickFormButton();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get is detail pane visible
|
* Get is detail pane visible
|
||||||
* @return boolean
|
* @return true if the containing {@link DetailPane} instance is visible
|
||||||
*/
|
*/
|
||||||
public default boolean isDetailVisible() {
|
public default boolean isDetailVisible() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return List of toolbar buttons
|
* @return List of toolbar buttons
|
||||||
*/
|
*/
|
||||||
public List<Button> getToolbarButtons();
|
public List<Button> getToolbarButtons();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return customization enabled/disabled for tab
|
* @return true if customize grid button is enabled
|
||||||
*/
|
*/
|
||||||
public boolean isEnableCustomizeButton();
|
public boolean isEnableCustomizeButton();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return process Button Enabled/Disabled
|
* @return true if process Button is Enabled
|
||||||
*/
|
*/
|
||||||
default public boolean isEnableProcessButton() {
|
default public boolean isEnableProcessButton() {
|
||||||
boolean isNewRow = getGridTab().getRowCount() == 0 || getGridTab().isNew();
|
boolean isNewRow = getGridTab().getRowCount() == 0 || getGridTab().isNew();
|
||||||
|
@ -233,14 +234,14 @@ public interface IADTabpanel extends Component, Evaluatee {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enabled/Disabled tab toolbar button
|
* Enabled/Disabled ADWindowToolbar buttons
|
||||||
*
|
*
|
||||||
* @param toolbar - {@link ADWindowToolbar}
|
* @param toolbar - {@link ADWindowToolbar}
|
||||||
*/
|
*/
|
||||||
public void updateToolbar(ADWindowToolbar toolbar);
|
public void updateToolbar(ADWindowToolbar toolbar);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enabled/Disabled detail panel toolbar button
|
* Enabled/Disabled {@link DetailPane} toolbar buttons
|
||||||
*
|
*
|
||||||
* @param toolbar - {@link Toolbar}
|
* @param toolbar - {@link Toolbar}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,31 +19,30 @@ import org.adempiere.util.Callback;
|
||||||
import org.adempiere.webui.editor.WEditor;
|
import org.adempiere.webui.editor.WEditor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Interface for container that host one or more field editors
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface IFieldEditorContainer {
|
public interface IFieldEditorContainer {
|
||||||
/**
|
/**
|
||||||
* focus to first field editor
|
* set focus to first field editor
|
||||||
*/
|
*/
|
||||||
public void focusToFirstEditor();
|
public void focusToFirstEditor();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* focus to next field editor from ref
|
* set focus to next field editor from ref
|
||||||
* @param ref
|
* @param ref
|
||||||
*/
|
*/
|
||||||
public void focusToNextEditor(WEditor ref);
|
public void focusToNextEditor(WEditor ref);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* helper method to loop thru editor collection of panel <br/>
|
* Call editorTaverseCallback for all editors hosted by this container
|
||||||
* can use on callout to check relative editor
|
|
||||||
* @param editorTaverseCallback
|
* @param editorTaverseCallback
|
||||||
*/
|
*/
|
||||||
public void editorTraverse (Callback<WEditor> editorTaverseCallback);
|
public void editorTraverse (Callback<WEditor> editorTaverseCallback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* default implement for {@link #editorTraverse(Callback)}
|
* Default implementation for {@link #editorTraverse(Callback)}
|
||||||
* @param editorTaverseCallback
|
* @param editorTaverseCallback
|
||||||
* @param editors
|
* @param editors
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,27 @@
|
||||||
/**
|
/***********************************************************************
|
||||||
*
|
* This file is part of iDempiere ERP Open Source *
|
||||||
*/
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* 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., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - hengsin *
|
||||||
|
**********************************************************************/
|
||||||
package org.adempiere.webui.adwindow;
|
package org.adempiere.webui.adwindow;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -25,13 +46,16 @@ import org.zkoss.zul.Menuseparator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class ProcessButtonPopup extends Menupopup implements EventListener<Event> {
|
public class ProcessButtonPopup extends Menupopup implements EventListener<Event> {
|
||||||
|
|
||||||
private static final String DOCUMENT_ACTION_MENUITEM_ATTRIBUTE = "document-action-menuitem";
|
/** sclass for document action menu items **/
|
||||||
|
private static final String DOCUMENT_ACTION_MENUITEM_SCLASS = "document-action-menuitem";
|
||||||
|
/** Menupopup attribute to store reference to WDocActionPanel **/
|
||||||
private static final String DOC_ACTION_PANEL_ATTRIBUTE = "doc-action-panel";
|
private static final String DOC_ACTION_PANEL_ATTRIBUTE = "doc-action-panel";
|
||||||
|
/** Menupopup/Menuitem attribute to store reference to Button **/
|
||||||
private static final String BUTTON_ATTRIBUTE = "button";
|
private static final String BUTTON_ATTRIBUTE = "button";
|
||||||
|
/** Button yes/no attribute (Y/N) to store whether button is pressed **/
|
||||||
public static final String BUTTON_ATTRIBUTE_PRESSED = "buttonPressed";
|
public static final String BUTTON_ATTRIBUTE_PRESSED = "buttonPressed";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,6 +63,11 @@ public class ProcessButtonPopup extends Menupopup implements EventListener<Event
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 304878472233552113L;
|
private static final long serialVersionUID = 304878472233552113L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render buttons as menu items.
|
||||||
|
* Special treatment for DocAction - render each available document action as a sub menu item.
|
||||||
|
* @param buttons
|
||||||
|
*/
|
||||||
public void render(List<Button> buttons) {
|
public void render(List<Button> buttons) {
|
||||||
this.setSclass("z-menu-noimage");
|
this.setSclass("z-menu-noimage");
|
||||||
|
|
||||||
|
@ -88,7 +117,7 @@ public class ProcessButtonPopup extends Menupopup implements EventListener<Event
|
||||||
for(Listitem action : actions) {
|
for(Listitem action : actions) {
|
||||||
Menuitem mi = new Menuitem(action.getLabel());
|
Menuitem mi = new Menuitem(action.getLabel());
|
||||||
mi.setValue((String)action.getValue());
|
mi.setValue((String)action.getValue());
|
||||||
mi.setSclass(DOCUMENT_ACTION_MENUITEM_ATTRIBUTE);
|
mi.setSclass(DOCUMENT_ACTION_MENUITEM_SCLASS);
|
||||||
mi.addEventListener(Events.ON_CLICK, this);
|
mi.addEventListener(Events.ON_CLICK, this);
|
||||||
popup.appendChild(mi);
|
popup.appendChild(mi);
|
||||||
}
|
}
|
||||||
|
@ -99,7 +128,7 @@ public class ProcessButtonPopup extends Menupopup implements EventListener<Event
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(Event event) throws Exception {
|
public void onEvent(Event event) throws Exception {
|
||||||
Menuitem mi = (Menuitem) event.getTarget();
|
Menuitem mi = (Menuitem) event.getTarget();
|
||||||
if (DOCUMENT_ACTION_MENUITEM_ATTRIBUTE.equals(mi.getSclass())) {
|
if (DOCUMENT_ACTION_MENUITEM_SCLASS.equals(mi.getSclass())) {
|
||||||
final Button button = (Button) mi.getParent().getAttribute(BUTTON_ATTRIBUTE);
|
final Button button = (Button) mi.getParent().getAttribute(BUTTON_ATTRIBUTE);
|
||||||
WDocActionPanel panel = (WDocActionPanel) mi.getParent().getAttribute(DOC_ACTION_PANEL_ATTRIBUTE);
|
WDocActionPanel panel = (WDocActionPanel) mi.getParent().getAttribute(DOC_ACTION_PANEL_ATTRIBUTE);
|
||||||
panel.setSelectedItem(mi.getValue());
|
panel.setSelectedItem(mi.getValue());
|
||||||
|
|
|
@ -71,7 +71,7 @@ import org.zkoss.zul.RowRendererExt;
|
||||||
import org.zkoss.zul.Timebox;
|
import org.zkoss.zul.Timebox;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Row renderer for Quick GridTab grid.
|
* Row renderer for Quick GridTab grid (Base on {@link GridTabRowRenderer})
|
||||||
*
|
*
|
||||||
* @author Logilite Technologies
|
* @author Logilite Technologies
|
||||||
* @since Nov 03, 2017
|
* @since Nov 03, 2017
|
||||||
|
@ -79,7 +79,9 @@ import org.zkoss.zul.Timebox;
|
||||||
public class QuickGridTabRowRenderer
|
public class QuickGridTabRowRenderer
|
||||||
implements RowRenderer<Object[]>, RowRendererExt, RendererCtrl, EventListener<Event> {
|
implements RowRenderer<Object[]>, RowRendererExt, RendererCtrl, EventListener<Event> {
|
||||||
|
|
||||||
|
/** Component boolean attribute to indicate this component is own by QuickGridView **/
|
||||||
public static final String IS_QUICK_FORM_COMPONENT = "IS_QUICK_FORM_COMPONENT";
|
public static final String IS_QUICK_FORM_COMPONENT = "IS_QUICK_FORM_COMPONENT";
|
||||||
|
/** Editor component attribute to store row index (absolute) **/
|
||||||
public static final String GRID_ROW_INDEX_ATTR = "grid.row.index";
|
public static final String GRID_ROW_INDEX_ATTR = "grid.row.index";
|
||||||
private static final String CELL_DIV_STYLE = "height: 100%; cursor: pointer; ";
|
private static final String CELL_DIV_STYLE = "height: 100%; cursor: pointer; ";
|
||||||
private static final String CELL_DIV_STYLE_ALIGN_CENTER = CELL_DIV_STYLE + "text-align:center; ";
|
private static final String CELL_DIV_STYLE_ALIGN_CENTER = CELL_DIV_STYLE + "text-align:center; ";
|
||||||
|
@ -90,18 +92,27 @@ public class QuickGridTabRowRenderer
|
||||||
|
|
||||||
private GridTab gridTab;
|
private GridTab gridTab;
|
||||||
private int windowNo;
|
private int windowNo;
|
||||||
|
/** Sync field editor changes to GridField **/
|
||||||
private GridTabDataBinder dataBinder;
|
private GridTabDataBinder dataBinder;
|
||||||
private Paging paging;
|
private Paging paging;
|
||||||
|
|
||||||
|
/** internal listener for row event **/
|
||||||
private RowListener rowListener;
|
private RowListener rowListener;
|
||||||
|
|
||||||
|
/** Grid that own this renderer **/
|
||||||
private Grid grid = null;
|
private Grid grid = null;
|
||||||
|
/** QuickGridView that uses this renderer **/
|
||||||
private QuickGridView gridPanel = null;
|
private QuickGridView gridPanel = null;
|
||||||
|
/** current focus row **/
|
||||||
private Row currentRow;
|
private Row currentRow;
|
||||||
|
/** values of current row. updated in {@link #render(Row, Object[], int)}. **/
|
||||||
private Object[] currentValues;
|
private Object[] currentValues;
|
||||||
|
/** true if currrent row is in edit mode **/
|
||||||
private boolean editing = false;
|
private boolean editing = false;
|
||||||
public int currentRowIndex = -1;
|
public int currentRowIndex = -1;
|
||||||
|
/** AD window content part that own this renderer **/
|
||||||
private AbstractADWindowContent m_windowPanel;
|
private AbstractADWindowContent m_windowPanel;
|
||||||
|
/** internal listener for button ActionEvent **/
|
||||||
private ActionListener buttonListener;
|
private ActionListener buttonListener;
|
||||||
// Row-wise Editors Map
|
// Row-wise Editors Map
|
||||||
public Map<Row, ArrayList<WEditor>> editorsListMap = new LinkedHashMap<Row, ArrayList<WEditor>>();
|
public Map<Row, ArrayList<WEditor>> editorsListMap = new LinkedHashMap<Row, ArrayList<WEditor>>();
|
||||||
|
@ -128,6 +139,12 @@ public class QuickGridTabRowRenderer
|
||||||
this.dataBinder = new GridTabDataBinder(gridTab);
|
this.dataBinder = new GridTabDataBinder(gridTab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get editor for GridField and set value to object parameter.
|
||||||
|
* @param gridField
|
||||||
|
* @param object
|
||||||
|
* @return {@link WEditor}
|
||||||
|
*/
|
||||||
private WEditor getEditorCell(GridField gridField, Object object) {
|
private WEditor getEditorCell(GridField gridField, Object object) {
|
||||||
WEditor editor = WebEditorFactory.getEditor(gridField, true);
|
WEditor editor = WebEditorFactory.getEditor(gridField, true);
|
||||||
if (editor != null) {
|
if (editor != null) {
|
||||||
|
@ -137,6 +154,11 @@ public class QuickGridTabRowRenderer
|
||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup field editor
|
||||||
|
* @param gridField
|
||||||
|
* @param editor
|
||||||
|
*/
|
||||||
private void prepareFieldEditor(GridField gridField, WEditor editor) {
|
private void prepareFieldEditor(GridField gridField, WEditor editor) {
|
||||||
if (editor instanceof WButtonEditor)
|
if (editor instanceof WButtonEditor)
|
||||||
{
|
{
|
||||||
|
@ -161,6 +183,10 @@ public class QuickGridTabRowRenderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param field
|
||||||
|
* @return column index for field, -1 if not found
|
||||||
|
*/
|
||||||
public int getColumnIndex(GridField field) {
|
public int getColumnIndex(GridField field) {
|
||||||
GridField[] fields = gridPanel.getFields();
|
GridField[] fields = gridPanel.getFields();
|
||||||
for(int i = 0; i < fields.length; i++) {
|
for(int i = 0; i < fields.length; i++) {
|
||||||
|
@ -178,6 +204,7 @@ public class QuickGridTabRowRenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Render data for row.
|
||||||
* @param row
|
* @param row
|
||||||
* @param data
|
* @param data
|
||||||
* @param index
|
* @param index
|
||||||
|
@ -409,7 +436,7 @@ public class QuickGridTabRowRenderer
|
||||||
*
|
*
|
||||||
* @param component
|
* @param component
|
||||||
* @param isDisable
|
* @param isDisable
|
||||||
* @return
|
* @return true if component is read only
|
||||||
*/
|
*/
|
||||||
public boolean isDisableReadonlyComponent(Component component, boolean isDisable)
|
public boolean isDisableReadonlyComponent(Component component, boolean isDisable)
|
||||||
{
|
{
|
||||||
|
@ -548,7 +575,7 @@ public class QuickGridTabRowRenderer
|
||||||
*
|
*
|
||||||
* @param zclass
|
* @param zclass
|
||||||
* @param isDisable
|
* @param isDisable
|
||||||
* @return
|
* @return modify zclass
|
||||||
*/
|
*/
|
||||||
private String addOrRemoveCssClass(String zclass, boolean isDisable)
|
private String addOrRemoveCssClass(String zclass, boolean isDisable)
|
||||||
{
|
{
|
||||||
|
@ -568,14 +595,27 @@ public class QuickGridTabRowRenderer
|
||||||
|
|
||||||
private Cell currentCell = null;
|
private Cell currentCell = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return current {@link Cell}
|
||||||
|
*/
|
||||||
public Cell getCurrentCell() {
|
public Cell getCurrentCell() {
|
||||||
return currentCell;
|
return currentCell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set current cell
|
||||||
|
* @param currentCell
|
||||||
|
*/
|
||||||
public void setCurrentCell(Cell currentCell) {
|
public void setCurrentCell(Cell currentCell) {
|
||||||
this.currentCell = currentCell;
|
this.currentCell = currentCell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set current cell
|
||||||
|
* @param row
|
||||||
|
* @param col
|
||||||
|
* @param code cell navigation code (right, left, down, up, next)
|
||||||
|
*/
|
||||||
public void setCurrentCell(int row, int col, int code) {
|
public void setCurrentCell(int row, int col, int code) {
|
||||||
if (col < 0 || row < 0)
|
if (col < 0 || row < 0)
|
||||||
return;
|
return;
|
||||||
|
@ -660,7 +700,7 @@ public class QuickGridTabRowRenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Property change listener of editor field
|
* Add property change listener (WEditor) to GridField
|
||||||
*
|
*
|
||||||
* @param editorsList
|
* @param editorsList
|
||||||
*/
|
*/
|
||||||
|
@ -676,7 +716,7 @@ public class QuickGridTabRowRenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove Property change listener of editor field
|
* Remove property change listener (WEditor) from GridField
|
||||||
*
|
*
|
||||||
* @param editorsList
|
* @param editorsList
|
||||||
*/
|
*/
|
||||||
|
@ -691,7 +731,7 @@ public class QuickGridTabRowRenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true add Property Change Listener, a false Remove Property Change Listener
|
* If isAddListener is true add Property Change Listener, otherwise Remove Property Change Listener
|
||||||
*
|
*
|
||||||
* @param isAddListener
|
* @param isAddListener
|
||||||
* @param col
|
* @param col
|
||||||
|
@ -714,8 +754,8 @@ public class QuickGridTabRowRenderer
|
||||||
} // addRemovePropertyChangeListener
|
} // addRemovePropertyChangeListener
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param code
|
* @param code cell navigation code
|
||||||
* @return
|
* @return true to add property change listener, false otherwise
|
||||||
*/
|
*/
|
||||||
public Boolean isAddRemoveListener(int code)
|
public Boolean isAddRemoveListener(int code)
|
||||||
{
|
{
|
||||||
|
@ -726,7 +766,8 @@ public class QuickGridTabRowRenderer
|
||||||
} // isAddRemoveListener
|
} // isAddRemoveListener
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param row
|
* Set current row
|
||||||
|
* @param row absolute row index
|
||||||
*/
|
*/
|
||||||
public void setRowTo(int row)
|
public void setRowTo(int row)
|
||||||
{
|
{
|
||||||
|
@ -736,6 +777,11 @@ public class QuickGridTabRowRenderer
|
||||||
setCurrentRow(currentRow);
|
setCurrentRow(currentRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param row
|
||||||
|
* @param col
|
||||||
|
* @return true if cell is editable, false otherwise
|
||||||
|
*/
|
||||||
private boolean isEditable(int row, int col)
|
private boolean isEditable(int row, int col)
|
||||||
{
|
{
|
||||||
Cell cell = null;
|
Cell cell = null;
|
||||||
|
@ -790,6 +836,9 @@ public class QuickGridTabRowRenderer
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set focus to {@link #currentCell}
|
||||||
|
*/
|
||||||
public void setFocusOnCurrentCell() {
|
public void setFocusOnCurrentCell() {
|
||||||
if (currentCell == null || currentCell.getChildren().size() <= 0) {
|
if (currentCell == null || currentCell.getChildren().size() <= 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -845,6 +894,7 @@ public class QuickGridTabRowRenderer
|
||||||
} // setFocusOnCurrentCell
|
} // setFocusOnCurrentCell
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Set current focus row
|
||||||
* @param row
|
* @param row
|
||||||
*/
|
*/
|
||||||
public void setCurrentRow(Row row)
|
public void setCurrentRow(Row row)
|
||||||
|
@ -876,7 +926,7 @@ public class QuickGridTabRowRenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enter edit mode
|
* Enter edit mode for current focus row.
|
||||||
*/
|
*/
|
||||||
public void editCurrentRow() {
|
public void editCurrentRow() {
|
||||||
if (currentRow != null && currentRow.getParent() != null && currentRow.isVisible() && grid != null
|
if (currentRow != null && currentRow.getParent() != null && currentRow.isVisible() && grid != null
|
||||||
|
@ -929,13 +979,16 @@ public class QuickGridTabRowRenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Set {@link QuickGridView} that own this renderer.
|
||||||
* @param gridPanel
|
* @param gridPanel
|
||||||
*/
|
*/
|
||||||
public void setGridPanel(QuickGridView gridPanel) {
|
public void setGridPanel(QuickGridView gridPanel) {
|
||||||
this.gridPanel = gridPanel;
|
this.gridPanel = gridPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal listener for row event (ON_CLICK, ON_DOUBLE_CLICK and ON_OK).
|
||||||
|
*/
|
||||||
static class RowListener implements EventListener<Event> {
|
static class RowListener implements EventListener<Event> {
|
||||||
|
|
||||||
private Grid _grid;
|
private Grid _grid;
|
||||||
|
@ -964,13 +1017,15 @@ public class QuickGridTabRowRenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return boolean
|
* @return true if current row is in edit mode, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean isEditing() {
|
public boolean isEditing() {
|
||||||
return editing;
|
return editing;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Set AD window content part that own this renderer.
|
||||||
|
* {@link #buttonListener} need this to call {@link AbstractADWindowContent#actionPerformed(ActionEvent)}.
|
||||||
* @param windowPanel
|
* @param windowPanel
|
||||||
*/
|
*/
|
||||||
public void setADWindowPanel(AbstractADWindowContent windowPanel) {
|
public void setADWindowPanel(AbstractADWindowContent windowPanel) {
|
||||||
|
|
|
@ -73,7 +73,7 @@ import org.zkoss.zul.event.ZulEvents;
|
||||||
import org.zkoss.zul.impl.CustomGridDataLoader;
|
import org.zkoss.zul.impl.CustomGridDataLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Quick Grid view implemented using the Grid component.
|
* Quick Grid view implemented using the Grid component (Base on {@link GridView}).
|
||||||
*
|
*
|
||||||
* @author Logilite Technologies
|
* @author Logilite Technologies
|
||||||
* @since Nov 03, 2017
|
* @since Nov 03, 2017
|
||||||
|
@ -81,30 +81,39 @@ import org.zkoss.zul.impl.CustomGridDataLoader;
|
||||||
public class QuickGridView extends Vbox
|
public class QuickGridView extends Vbox
|
||||||
implements EventListener<Event>, IdSpace, IFieldEditorContainer, StateChangeListener {
|
implements EventListener<Event>, IdSpace, IFieldEditorContainer, StateChangeListener {
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 228387400133234920L;
|
private static final long serialVersionUID = 228387400133234920L;
|
||||||
|
|
||||||
static CLogger log = CLogger.getCLogger(QuickGridView.class);
|
static CLogger log = CLogger.getCLogger(QuickGridView.class);
|
||||||
|
|
||||||
|
/** Style for Grid and Grid Footer **/
|
||||||
private static final String HEADER_GRID_STYLE = "border: none; margin:0; padding: 0;";
|
private static final String HEADER_GRID_STYLE = "border: none; margin:0; padding: 0;";
|
||||||
|
|
||||||
|
/** default paging size **/
|
||||||
private static final int DEFAULT_PAGE_SIZE = 20;
|
private static final int DEFAULT_PAGE_SIZE = 20;
|
||||||
|
|
||||||
|
/** default paging size for mobile client **/
|
||||||
private static final int DEFAULT_MOBILE_PAGE_SIZE = 20;
|
private static final int DEFAULT_MOBILE_PAGE_SIZE = 20;
|
||||||
|
|
||||||
|
/** minimum column width **/
|
||||||
private static final int MIN_COLUMN_WIDTH = 100;
|
private static final int MIN_COLUMN_WIDTH = 100;
|
||||||
|
|
||||||
|
/** maximum column width **/
|
||||||
private static final int MAX_COLUMN_WIDTH = 300;
|
private static final int MAX_COLUMN_WIDTH = 300;
|
||||||
|
|
||||||
|
/** minimum column width for combobox field **/
|
||||||
private static final int MIN_COMBOBOX_WIDTH = 160;
|
private static final int MIN_COMBOBOX_WIDTH = 160;
|
||||||
|
|
||||||
|
/** minimum column width for numeric field **/
|
||||||
private static final int MIN_NUMERIC_COL_WIDTH = 120;
|
private static final int MIN_NUMERIC_COL_WIDTH = 120;
|
||||||
|
|
||||||
public static final int SALES_ORDER_LINE_TAB_ID = 187;
|
public static final int SALES_ORDER_LINE_TAB_ID = 187;
|
||||||
|
|
||||||
|
/** GridView boolean attribute to indicate ON_POST_SELECTED_ROW_CHANGED_EVENT have been posted in current execution cycle **/
|
||||||
private static final String ATTR_ON_POST_SELECTED_ROW_CHANGED = "org.adempiere.webui.adwindow.GridView.onPostSelectedRowChanged";
|
private static final String ATTR_ON_POST_SELECTED_ROW_CHANGED = "org.adempiere.webui.adwindow.GridView.onPostSelectedRowChanged";
|
||||||
|
|
||||||
|
/** shortcut key for cell navigation **/
|
||||||
public static final String CNTRL_KEYS = "#left#right#up#down#home@k@r";
|
public static final String CNTRL_KEYS = "#left#right#up#down#home@k@r";
|
||||||
|
|
||||||
// 'Enter' Work as Down key
|
// 'Enter' Work as Down key
|
||||||
|
@ -123,47 +132,63 @@ public class QuickGridView extends Vbox
|
||||||
public static final int NAVIGATE_CODE = 1;
|
public static final int NAVIGATE_CODE = 1;
|
||||||
public static final int FOCUS_CODE = 0;
|
public static final int FOCUS_CODE = 0;
|
||||||
|
|
||||||
|
/** data grid instance **/
|
||||||
private Grid listbox = null;
|
private Grid listbox = null;
|
||||||
|
|
||||||
private int pageSize = DEFAULT_PAGE_SIZE;
|
private int pageSize = DEFAULT_PAGE_SIZE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list field display in grid mode, in case user customize grid
|
* list field display in grid mode, in case user customize grid
|
||||||
* this list container only customize list.
|
* this list container only display list.
|
||||||
*/
|
*/
|
||||||
private GridField[] gridFields;
|
private GridField[] gridFields;
|
||||||
|
|
||||||
|
/** GridTable model for GridTab **/
|
||||||
private AbstractTableModel tableModel;
|
private AbstractTableModel tableModel;
|
||||||
|
|
||||||
private int numColumns = 5;
|
private int numColumns = 5;
|
||||||
|
|
||||||
private int windowNo;
|
private int windowNo;
|
||||||
|
|
||||||
|
/** GridTab that back this QuickGridView **/
|
||||||
private GridTab gridTab;
|
private GridTab gridTab;
|
||||||
|
|
||||||
|
/** true if this QuickGridView instance have been init with GridTab **/
|
||||||
private boolean init;
|
private boolean init;
|
||||||
|
|
||||||
|
/** Zk List model for {@link #tableModel} **/
|
||||||
public GridTableListModel listModel;
|
public GridTableListModel listModel;
|
||||||
|
|
||||||
public Paging paging;
|
public Paging paging;
|
||||||
|
|
||||||
|
/** Row renderer for this QuickGridView instance **/
|
||||||
private QuickGridTabRowRenderer renderer;
|
private QuickGridTabRowRenderer renderer;
|
||||||
|
|
||||||
|
/** Footer for paging **/
|
||||||
private Div gridFooter;
|
private Div gridFooter;
|
||||||
|
|
||||||
|
/** true if current row is always in edit mode **/
|
||||||
private boolean modeless = true;
|
private boolean modeless = true;
|
||||||
|
|
||||||
|
/** AD window content part that own this GridView instance **/
|
||||||
private AbstractADWindowContent windowPanel;
|
private AbstractADWindowContent windowPanel;
|
||||||
|
|
||||||
|
/** true when grid is refreshing its data **/
|
||||||
private boolean refreshing;
|
private boolean refreshing;
|
||||||
|
|
||||||
|
/** AD_Field_ID:Column Width **/
|
||||||
private Map<Integer, String> columnWidthMap;
|
private Map<Integer, String> columnWidthMap;
|
||||||
|
|
||||||
|
/** checkbox to select all row of current page **/
|
||||||
protected Checkbox selectAll;
|
protected Checkbox selectAll;
|
||||||
|
|
||||||
boolean isHasCustomizeData = false;
|
/** true if there are AD_Tab_Customization for GridTab **/
|
||||||
|
protected boolean isHasCustomizeData = false;
|
||||||
|
|
||||||
Keylistener keyListener;
|
/** reference to desktop key listener **/
|
||||||
|
protected Keylistener keyListener;
|
||||||
|
|
||||||
|
/** true if no new row or new row have been saved **/
|
||||||
public boolean isNewLineSaved = true;
|
public boolean isNewLineSaved = true;
|
||||||
|
|
||||||
// Prevent focus change until render is complete
|
// Prevent focus change until render is complete
|
||||||
|
@ -171,16 +196,28 @@ public class QuickGridView extends Vbox
|
||||||
// To prevent 'onFocus' event fire twice on same component.
|
// To prevent 'onFocus' event fire twice on same component.
|
||||||
private Component preEventComponent;
|
private Component preEventComponent;
|
||||||
|
|
||||||
public IQuickForm quickForm;
|
/** IQuickForm that own this QuickGridView instance **/
|
||||||
|
public IQuickForm quickForm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list field display in grid mode, in case user customize grid
|
||||||
|
* this list container only customize list.
|
||||||
|
* @return GridField[]
|
||||||
|
*/
|
||||||
public GridField[] getGridField() {
|
public GridField[] getGridField() {
|
||||||
return gridFields;
|
return gridFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param gridField
|
||||||
|
*/
|
||||||
public void setGridField(GridField[] gridField) {
|
public void setGridField(GridField[] gridField) {
|
||||||
this.gridFields = gridField;
|
this.gridFields = gridField;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link QuickGridTabRowRenderer}
|
||||||
|
*/
|
||||||
public QuickGridTabRowRenderer getRenderer() {
|
public QuickGridTabRowRenderer getRenderer() {
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
@ -239,6 +276,11 @@ public class QuickGridView extends Vbox
|
||||||
addEventListener(EVENT_ONFOCUS_AFTER_SAVE, this);
|
addEventListener(EVENT_ONFOCUS_AFTER_SAVE, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param abstractADWindowContent
|
||||||
|
* @param gridTab
|
||||||
|
* @param wQuickForm
|
||||||
|
*/
|
||||||
public QuickGridView(AbstractADWindowContent abstractADWindowContent, GridTab gridTab, IQuickForm wQuickForm)
|
public QuickGridView(AbstractADWindowContent abstractADWindowContent, GridTab gridTab, IQuickForm wQuickForm)
|
||||||
{
|
{
|
||||||
this(abstractADWindowContent.getWindowNo());
|
this(abstractADWindowContent.getWindowNo());
|
||||||
|
@ -247,6 +289,9 @@ public class QuickGridView extends Vbox
|
||||||
init(gridTab);
|
init(gridTab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create data grid instances
|
||||||
|
*/
|
||||||
protected void createListbox()
|
protected void createListbox()
|
||||||
{
|
{
|
||||||
listbox = new Grid();
|
listbox = new Grid();
|
||||||
|
@ -258,7 +303,7 @@ public class QuickGridView extends Vbox
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Init data grid
|
||||||
* @param gridTab
|
* @param gridTab
|
||||||
*/
|
*/
|
||||||
public void init(GridTab gridTab)
|
public void init(GridTab gridTab)
|
||||||
|
@ -278,6 +323,10 @@ public class QuickGridView extends Vbox
|
||||||
this.init = true;
|
this.init = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup {@link #gridFields} from gridTab.
|
||||||
|
* @param gridTab
|
||||||
|
*/
|
||||||
private void setupFields(GridTab gridTab) {
|
private void setupFields(GridTab gridTab) {
|
||||||
this.gridTab = gridTab;
|
this.gridTab = gridTab;
|
||||||
gridTab.addStateChangeListener(this);
|
gridTab.addStateChangeListener(this);
|
||||||
|
@ -370,14 +419,14 @@ public class QuickGridView extends Vbox
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return true if data grid have been init with GridTab
|
||||||
*/
|
*/
|
||||||
public boolean isInit() {
|
public boolean isInit() {
|
||||||
return init;
|
return init;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* refresh after switching from form view
|
* Refresh data grid (int of quick form or column setup has change)
|
||||||
* @param gridTab
|
* @param gridTab
|
||||||
*/
|
*/
|
||||||
public void refresh(GridTab gridTab) {
|
public void refresh(GridTab gridTab) {
|
||||||
|
@ -397,12 +446,15 @@ public class QuickGridView extends Vbox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if data grid is refreshing data from GridTab
|
||||||
|
*/
|
||||||
public boolean isRefreshing() {
|
public boolean isRefreshing() {
|
||||||
return refreshing;
|
return refreshing;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update current row from model
|
* Update current row index from model
|
||||||
*/
|
*/
|
||||||
public void updateListIndex() {
|
public void updateListIndex() {
|
||||||
if (gridTab == null || !gridTab.isOpen()) return;
|
if (gridTab == null || !gridTab.isOpen()) return;
|
||||||
|
@ -451,18 +503,24 @@ public class QuickGridView extends Vbox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hide paging component
|
||||||
|
*/
|
||||||
private void hidePagingControl() {
|
private void hidePagingControl() {
|
||||||
if (gridFooter.isVisible())
|
if (gridFooter.isVisible())
|
||||||
gridFooter.setVisible(false);
|
gridFooter.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* show paging component
|
||||||
|
*/
|
||||||
private void showPagingControl() {
|
private void showPagingControl() {
|
||||||
if (!gridFooter.isVisible())
|
if (!gridFooter.isVisible())
|
||||||
gridFooter.setVisible(true);
|
gridFooter.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* echo ON_POST_SELECTED_ROW_CHANGED_EVENT after current row index has changed
|
||||||
*/
|
*/
|
||||||
protected void echoOnPostSelectedRowChanged() {
|
protected void echoOnPostSelectedRowChanged() {
|
||||||
if (getAttribute(ATTR_ON_POST_SELECTED_ROW_CHANGED) == null) {
|
if (getAttribute(ATTR_ON_POST_SELECTED_ROW_CHANGED) == null) {
|
||||||
|
@ -480,11 +538,17 @@ public class QuickGridView extends Vbox
|
||||||
this.pageSize = pageSize;
|
this.pageSize = pageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove all components
|
||||||
|
*/
|
||||||
public void clear()
|
public void clear()
|
||||||
{
|
{
|
||||||
this.getChildren().clear();
|
this.getChildren().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup {@link Columns} of data grid
|
||||||
|
*/
|
||||||
private void setupColumns()
|
private void setupColumns()
|
||||||
{
|
{
|
||||||
if (init) return;
|
if (init) return;
|
||||||
|
@ -608,6 +672,9 @@ public class QuickGridView extends Vbox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render data grid
|
||||||
|
*/
|
||||||
private void render()
|
private void render()
|
||||||
{
|
{
|
||||||
updateEmptyMessage();
|
updateEmptyMessage();
|
||||||
|
@ -635,6 +702,9 @@ public class QuickGridView extends Vbox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show zero records for processing message
|
||||||
|
*/
|
||||||
private void updateEmptyMessage() {
|
private void updateEmptyMessage() {
|
||||||
if (gridTab.getRowCount() == 0)
|
if (gridTab.getRowCount() == 0)
|
||||||
{
|
{
|
||||||
|
@ -646,6 +716,10 @@ public class QuickGridView extends Vbox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update {@link #listModel} with {@link #tableModel} changes.
|
||||||
|
* Re-create {@link #renderer}.
|
||||||
|
*/
|
||||||
private void updateModel() {
|
private void updateModel() {
|
||||||
if (listModel != null)
|
if (listModel != null)
|
||||||
((GridTable)tableModel).removeTableModelListener(listModel);
|
((GridTable)tableModel).removeTableModelListener(listModel);
|
||||||
|
@ -1128,6 +1202,10 @@ public class QuickGridView extends Vbox
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set focus to cell (source)
|
||||||
|
* @param source
|
||||||
|
*/
|
||||||
private void setFocusOnDiv(Component source) {
|
private void setFocusOnDiv(Component source) {
|
||||||
int rowCount = gridTab.getTableModel().getRowCount();
|
int rowCount = gridTab.getTableModel().getRowCount();
|
||||||
int colCount = renderer.getCurrentRow().getChildren().size();
|
int colCount = renderer.getCurrentRow().getChildren().size();
|
||||||
|
@ -1141,6 +1219,9 @@ public class QuickGridView extends Vbox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if all row of current page is selected
|
||||||
|
*/
|
||||||
public boolean isAllSelected() {
|
public boolean isAllSelected() {
|
||||||
org.zkoss.zul.Rows rows = listbox.getRows();
|
org.zkoss.zul.Rows rows = listbox.getRows();
|
||||||
List<Component> childs = rows.getChildren();
|
List<Component> childs = rows.getChildren();
|
||||||
|
@ -1162,6 +1243,10 @@ public class QuickGridView extends Vbox
|
||||||
return all;
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* turn on/off select all rows for current page
|
||||||
|
* @param b
|
||||||
|
*/
|
||||||
public void toggleSelectionForAll(boolean b) {
|
public void toggleSelectionForAll(boolean b) {
|
||||||
org.zkoss.zul.Rows rows = listbox.getRows();
|
org.zkoss.zul.Rows rows = listbox.getRows();
|
||||||
List<Component> childs = rows.getChildren();
|
List<Component> childs = rows.getChildren();
|
||||||
|
@ -1188,6 +1273,10 @@ public class QuickGridView extends Vbox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update list model and data grid with new current row index
|
||||||
|
* @param index
|
||||||
|
*/
|
||||||
private void onSelectedRowChange(int index) {
|
private void onSelectedRowChange(int index) {
|
||||||
if (updateModelIndex(index)) {
|
if (updateModelIndex(index)) {
|
||||||
updateListIndex();
|
updateListIndex();
|
||||||
|
@ -1195,7 +1284,12 @@ public class QuickGridView extends Vbox
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event after the current selected row change
|
* Save changes.
|
||||||
|
* Call {@link #dataSave(int)}
|
||||||
|
* @param code cell navigation code
|
||||||
|
* @param row
|
||||||
|
* @param col
|
||||||
|
* @return true if save succesfully
|
||||||
*/
|
*/
|
||||||
private boolean save(int code, int row, int col)
|
private boolean save(int code, int row, int col)
|
||||||
{
|
{
|
||||||
|
@ -1211,6 +1305,9 @@ public class QuickGridView extends Vbox
|
||||||
return isSave;
|
return isSave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event after the current row index has changed.
|
||||||
|
*/
|
||||||
public void onPostSelectedRowChanged() {
|
public void onPostSelectedRowChanged() {
|
||||||
removeAttribute(ATTR_ON_POST_SELECTED_ROW_CHANGED);
|
removeAttribute(ATTR_ON_POST_SELECTED_ROW_CHANGED);
|
||||||
if (listbox.getRows() == null || listbox.getRows().getChildren().isEmpty())
|
if (listbox.getRows() == null || listbox.getRows().getChildren().isEmpty())
|
||||||
|
@ -1244,6 +1341,11 @@ public class QuickGridView extends Vbox
|
||||||
onPostSelectedRowChanged();
|
onPostSelectedRowChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param row
|
||||||
|
* @param index
|
||||||
|
* @return true if row have been rendered by row renderer
|
||||||
|
*/
|
||||||
private boolean isRowRendered(org.zkoss.zul.Row row, int index) {
|
private boolean isRowRendered(org.zkoss.zul.Row row, int index) {
|
||||||
if (row.getChildren().size() == 0) {
|
if (row.getChildren().size() == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1255,6 +1357,11 @@ public class QuickGridView extends Vbox
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update gridTab current row index.
|
||||||
|
* @param rowIndex row index of current page
|
||||||
|
* @return true if gridTab current row index has change
|
||||||
|
*/
|
||||||
public boolean updateModelIndex(int rowIndex) {
|
public boolean updateModelIndex(int rowIndex) {
|
||||||
if (pageSize > 0) {
|
if (pageSize > 0) {
|
||||||
int start = listModel.getPage() * listModel.getPageSize();
|
int start = listModel.getPage() * listModel.getPageSize();
|
||||||
|
@ -1309,9 +1416,8 @@ public class QuickGridView extends Vbox
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change display properties of current row
|
* Perform dynamic display for editors in list
|
||||||
*
|
* @param noData true if data grid is empty
|
||||||
* @param noData
|
|
||||||
* @param list
|
* @param list
|
||||||
*/
|
*/
|
||||||
private void dynamicDisplayEditors(boolean noData, List<WEditor> list) {
|
private void dynamicDisplayEditors(boolean noData, List<WEditor> list) {
|
||||||
|
@ -1367,6 +1473,7 @@ public class QuickGridView extends Vbox
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Set AD window content part that own this QuickGridView instance
|
||||||
* @param winPanel
|
* @param winPanel
|
||||||
*/
|
*/
|
||||||
public void setADWindowPanel(AbstractADWindowContent winPanel) {
|
public void setADWindowPanel(AbstractADWindowContent winPanel) {
|
||||||
|
@ -1375,6 +1482,9 @@ public class QuickGridView extends Vbox
|
||||||
renderer.setADWindowPanel(windowPanel);
|
renderer.setADWindowPanel(windowPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-Init QuickGridView with cache gridTab.
|
||||||
|
*/
|
||||||
public void reInit() {
|
public void reInit() {
|
||||||
listbox.getChildren().clear();
|
listbox.getChildren().clear();
|
||||||
listbox.detach();
|
listbox.detach();
|
||||||
|
@ -1400,6 +1510,7 @@ public class QuickGridView extends Vbox
|
||||||
/**
|
/**
|
||||||
* list field display in grid mode, in case user customize grid
|
* list field display in grid mode, in case user customize grid
|
||||||
* this list container only customize list.
|
* this list container only customize list.
|
||||||
|
* @return GridField[]
|
||||||
*/
|
*/
|
||||||
public GridField[] getFields() {
|
public GridField[] getFields() {
|
||||||
return gridFields;
|
return gridFields;
|
||||||
|
@ -1430,10 +1541,16 @@ public class QuickGridView extends Vbox
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* not used. candidate for removal.
|
||||||
|
*/
|
||||||
protected void onADTabPanelParentChanged() {
|
protected void onADTabPanelParentChanged() {
|
||||||
positionPagingControl();
|
positionPagingControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* not used. candidate for removal.
|
||||||
|
*/
|
||||||
private void positionPagingControl()
|
private void positionPagingControl()
|
||||||
{
|
{
|
||||||
if (gridFooter.getParent() != this)
|
if (gridFooter.getParent() != this)
|
||||||
|
@ -1446,18 +1563,27 @@ public class QuickGridView extends Vbox
|
||||||
paging.setDetailed(true);
|
paging.setDetailed(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set status text
|
||||||
|
* @param text
|
||||||
|
* @param error
|
||||||
|
*/
|
||||||
public void setStatusLine(String text, boolean error)
|
public void setStatusLine(String text, boolean error)
|
||||||
{
|
{
|
||||||
windowPanel.getStatusBarQF().setStatusLine(text, error);
|
windowPanel.getStatusBarQF().setStatusLine(text, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add new row to data grid
|
||||||
|
*/
|
||||||
public void createNewLine() {
|
public void createNewLine() {
|
||||||
isNewLineSaved = false;
|
isNewLineSaved = false;
|
||||||
gridTab.dataNew(false);
|
gridTab.dataNew(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param code
|
* Save changes
|
||||||
|
* @param code cell navigation code
|
||||||
*/
|
*/
|
||||||
public boolean dataSave(int code) {
|
public boolean dataSave(int code) {
|
||||||
boolean isSave = false;
|
boolean isSave = false;
|
||||||
|
@ -1501,6 +1627,10 @@ public class QuickGridView extends Vbox
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param source
|
||||||
|
* @return row that own source cell
|
||||||
|
*/
|
||||||
private int getFocusedRowIndex(Component source)
|
private int getFocusedRowIndex(Component source)
|
||||||
{
|
{
|
||||||
int rowCount = gridTab.getTableModel().getRowCount();
|
int rowCount = gridTab.getTableModel().getRowCount();
|
||||||
|
@ -1516,6 +1646,9 @@ public class QuickGridView extends Vbox
|
||||||
return 0;
|
return 0;
|
||||||
} // getFocusedRowIndex
|
} // getFocusedRowIndex
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return sort column (if any)
|
||||||
|
*/
|
||||||
public Column findCurrentSortColumn()
|
public Column findCurrentSortColumn()
|
||||||
{
|
{
|
||||||
if (listbox.getColumns() != null)
|
if (listbox.getColumns() != null)
|
||||||
|
|
|
@ -45,6 +45,8 @@ import org.zkoss.zul.Separator;
|
||||||
import org.zkoss.zul.Space;
|
import org.zkoss.zul.Space;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Status bar component of AD Window.
|
||||||
|
*
|
||||||
* This class is based on org.compiere.apps.StatusBar written by Jorg Janke.
|
* This class is based on org.compiere.apps.StatusBar written by Jorg Janke.
|
||||||
* @author Jorg Janke
|
* @author Jorg Janke
|
||||||
*
|
*
|
||||||
|
@ -55,32 +57,45 @@ import org.zkoss.zul.Space;
|
||||||
public class StatusBar extends Panel implements EventListener<Event>
|
public class StatusBar extends Panel implements EventListener<Event>
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
*
|
* generated serial id
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 7091641684809092888L;
|
private static final long serialVersionUID = 7091641684809092888L;
|
||||||
|
|
||||||
|
/** panel for record info text **/
|
||||||
private Panel infoPanel;
|
private Panel infoPanel;
|
||||||
|
|
||||||
|
/** html content of {@link #infoPanel} **/
|
||||||
private Html infoLine;
|
private Html infoLine;
|
||||||
|
|
||||||
|
/** west div for status text (info or error message) **/
|
||||||
private Div west;
|
private Div west;
|
||||||
|
|
||||||
|
/** east div for record info text **/
|
||||||
private Div east;
|
private Div east;
|
||||||
|
|
||||||
private ProcessInfoLog[] pInfoLogs;
|
private ProcessInfoLog[] pInfoLogs;
|
||||||
|
|
||||||
|
/** current status text **/
|
||||||
private String m_statusText;
|
private String m_statusText;
|
||||||
|
|
||||||
|
/** indicate current status text is info or error message */
|
||||||
private boolean m_statusError;
|
private boolean m_statusError;
|
||||||
|
|
||||||
|
/** message popup **/
|
||||||
private Window msgPopup;
|
private Window msgPopup;
|
||||||
|
|
||||||
|
/** content div for {@link #msgPopup} **/
|
||||||
private Div msgPopupCnt;
|
private Div msgPopupCnt;
|
||||||
|
|
||||||
|
/** layout for {@link #west} **/
|
||||||
private Hlayout messageContainer;
|
private Hlayout messageContainer;
|
||||||
|
|
||||||
|
/** Caption for {@link #msgPopup} **/
|
||||||
private Caption msgPopupCaption;
|
private Caption msgPopupCaption;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
public StatusBar()
|
public StatusBar()
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
|
@ -89,6 +104,10 @@ public class StatusBar extends Panel implements EventListener<Event>
|
||||||
createPopup();
|
createPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout status bar.
|
||||||
|
* West is for message and East is for HTML record info (usually generated from AD_StatusLine).
|
||||||
|
*/
|
||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
infoPanel = new Panel();
|
infoPanel = new Panel();
|
||||||
|
@ -114,7 +133,7 @@ public class StatusBar extends Panel implements EventListener<Event>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Info Line
|
* Set record Info Line
|
||||||
* @param text text
|
* @param text text
|
||||||
*/
|
*/
|
||||||
public void setInfo (String text)
|
public void setInfo (String text)
|
||||||
|
@ -128,6 +147,7 @@ public class StatusBar extends Panel implements EventListener<Event>
|
||||||
} // setInfo
|
} // setInfo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Call {@link #setStatusLine(String, boolean, ProcessInfoLog[])}.
|
||||||
* @param text
|
* @param text
|
||||||
*/
|
*/
|
||||||
public void setStatusLine (String text)
|
public void setStatusLine (String text)
|
||||||
|
@ -136,6 +156,7 @@ public class StatusBar extends Panel implements EventListener<Event>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Call {@link #setStatusLine(String, boolean, ProcessInfoLog[])}.
|
||||||
* @param text
|
* @param text
|
||||||
* @param error
|
* @param error
|
||||||
*/
|
*/
|
||||||
|
@ -145,6 +166,7 @@ public class StatusBar extends Panel implements EventListener<Event>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Set status message (west part) text.
|
||||||
* @param text
|
* @param text
|
||||||
* @param error
|
* @param error
|
||||||
* @param m_logs
|
* @param m_logs
|
||||||
|
@ -154,6 +176,7 @@ public class StatusBar extends Panel implements EventListener<Event>
|
||||||
pInfoLogs = m_logs;
|
pInfoLogs = m_logs;
|
||||||
Div div = null;
|
Div div = null;
|
||||||
|
|
||||||
|
//detect duplicate call within the current execution cycle
|
||||||
Execution execution = Executions.getCurrent();
|
Execution execution = Executions.getCurrent();
|
||||||
if (execution != null) {
|
if (execution != null) {
|
||||||
String key = this.getClass().getName()+"."+getUuid();
|
String key = this.getClass().getName()+"."+getUuid();
|
||||||
|
@ -174,6 +197,7 @@ public class StatusBar extends Panel implements EventListener<Event>
|
||||||
if (text == null || text.trim().length() == 0 )
|
if (text == null || text.trim().length() == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
//show auto dismiss popup notification at top left of ancestor tab panel
|
||||||
String labelText = buildLabelText(m_statusText);
|
String labelText = buildLabelText(m_statusText);
|
||||||
int duration = MSysConfig.getIntValue(MSysConfig.ZK_ERROR_MSG_LIFETIME_MILLISECONDS, 3500, Env.getAD_Client_ID(Env.getCtx()));
|
int duration = MSysConfig.getIntValue(MSysConfig.ZK_ERROR_MSG_LIFETIME_MILLISECONDS, 3500, Env.getAD_Client_ID(Env.getCtx()));
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -206,6 +230,7 @@ public class StatusBar extends Panel implements EventListener<Event>
|
||||||
label.addEventListener(Events.ON_CLICK, this);
|
label.addEventListener(Events.ON_CLICK, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//add document/record link from ProcessInfoLog
|
||||||
if (m_logs != null) {
|
if (m_logs != null) {
|
||||||
div = new Div();
|
div = new Div();
|
||||||
for (int i = 0; i < m_logs.length; i++) {
|
for (int i = 0; i < m_logs.length; i++) {
|
||||||
|
@ -228,6 +253,11 @@ public class StatusBar extends Panel implements EventListener<Event>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shorten statusText if exceed predefine max length of 80
|
||||||
|
* @param statusText
|
||||||
|
* @return shorten statusText
|
||||||
|
*/
|
||||||
private String buildLabelText(String statusText) {
|
private String buildLabelText(String statusText) {
|
||||||
if (statusText == null)
|
if (statusText == null)
|
||||||
return "";
|
return "";
|
||||||
|
@ -240,12 +270,20 @@ public class StatusBar extends Panel implements EventListener<Event>
|
||||||
return statusText.substring(0, 80);
|
return statusText.substring(0, 80);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create html content for {@link #msgPopupCnt}
|
||||||
|
*/
|
||||||
protected void createPopupContent() {
|
protected void createPopupContent() {
|
||||||
Html t = new Html(WTextEditorDialog.sanitize(m_statusText));
|
Html t = new Html(WTextEditorDialog.sanitize(m_statusText));
|
||||||
msgPopupCnt.getChildren().clear();
|
msgPopupCnt.getChildren().clear();
|
||||||
msgPopupCnt.appendChild(t);
|
msgPopupCnt.appendChild(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shorten statusText if length exceed the predefine max length of 140
|
||||||
|
* @param statusText
|
||||||
|
* @return shorten statusText
|
||||||
|
*/
|
||||||
private String buildNotificationText(String statusText) {
|
private String buildNotificationText(String statusText) {
|
||||||
if (statusText == null)
|
if (statusText == null)
|
||||||
return "";
|
return "";
|
||||||
|
@ -258,6 +296,11 @@ public class StatusBar extends Panel implements EventListener<Event>
|
||||||
return statusText.substring(0, 136) + " ...";
|
return statusText.substring(0, 136) + " ...";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find {@link Tabpanel} or {@link WQuickForm} that own comp
|
||||||
|
* @param comp
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
private Component findTabpanel(Component comp) {
|
private Component findTabpanel(Component comp) {
|
||||||
Component parent = comp.getParent();
|
Component parent = comp.getParent();
|
||||||
while (parent != null) {
|
while (parent != null) {
|
||||||
|
@ -278,13 +321,15 @@ public class StatusBar extends Panel implements EventListener<Event>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show message popup ({@link #msgPopup})
|
||||||
|
*/
|
||||||
private void showPopup() {
|
private void showPopup() {
|
||||||
appendChild(msgPopup);
|
appendChild(msgPopup);
|
||||||
LayoutUtils.openOverlappedWindow(messageContainer, msgPopup, "overlap_end");
|
LayoutUtils.openOverlappedWindow(messageContainer, msgPopup, "overlap_end");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @return process logs
|
* @return process logs
|
||||||
*/
|
*/
|
||||||
public ProcessInfoLog[] getPLogs() {
|
public ProcessInfoLog[] getPLogs() {
|
||||||
|
@ -292,17 +337,22 @@ public class StatusBar extends Panel implements EventListener<Event>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return current status line text
|
||||||
* @return current status line text
|
*/
|
||||||
*/
|
|
||||||
public String getStatusLine() {
|
public String getStatusLine() {
|
||||||
return m_statusText;
|
return m_statusText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if current status text is error text
|
||||||
|
*/
|
||||||
public boolean getStatusError() {
|
public boolean getStatusError() {
|
||||||
return m_statusError;
|
return m_statusError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new message popup instance
|
||||||
|
*/
|
||||||
private void createPopup() {
|
private void createPopup() {
|
||||||
msgPopupCnt = new Div();
|
msgPopupCnt = new Div();
|
||||||
ZKUpdateUtil.setVflex(msgPopupCnt, "1");
|
ZKUpdateUtil.setVflex(msgPopupCnt, "1");
|
||||||
|
@ -321,6 +371,9 @@ public class StatusBar extends Panel implements EventListener<Event>
|
||||||
msgPopup.appendChild(msgPopupCaption);
|
msgPopup.appendChild(msgPopupCaption);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle onClientInfo event from browser
|
||||||
|
*/
|
||||||
protected void onClientInfo() {
|
protected void onClientInfo() {
|
||||||
ZKUpdateUtil.setWindowWidthX(msgPopup, 500);
|
ZKUpdateUtil.setWindowWidthX(msgPopup, 500);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,18 +27,38 @@ import org.zkoss.zk.ui.event.EventListener;
|
||||||
import org.zkoss.zk.ui.event.Events;
|
import org.zkoss.zk.ui.event.Events;
|
||||||
import org.zkoss.zul.Toolbarbutton;
|
import org.zkoss.zul.Toolbarbutton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model for AD_ToolBarButton with IsCustomization=Y
|
||||||
|
* @author hengsin
|
||||||
|
*/
|
||||||
public class ToolbarCustomButton implements EventListener<Event>, Evaluatee {
|
public class ToolbarCustomButton implements EventListener<Event>, Evaluatee {
|
||||||
|
|
||||||
|
/** Toolbarbutton instance **/
|
||||||
private Toolbarbutton toolbarButton;
|
private Toolbarbutton toolbarButton;
|
||||||
|
/** AD_ToolBarButton.ActionClassName **/
|
||||||
private String actionId;
|
private String actionId;
|
||||||
private int windowNo;
|
private int windowNo;
|
||||||
private int tabNo = -1;
|
private int tabNo = -1;
|
||||||
|
/** model instance for AD_ToolBarButton **/
|
||||||
private MToolBarButton mToolbarButton;
|
private MToolBarButton mToolbarButton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mToolbarButton
|
||||||
|
* @param btn
|
||||||
|
* @param actionId
|
||||||
|
* @param windowNo
|
||||||
|
*/
|
||||||
public ToolbarCustomButton(MToolBarButton mToolbarButton, Toolbarbutton btn, String actionId, int windowNo) {
|
public ToolbarCustomButton(MToolBarButton mToolbarButton, Toolbarbutton btn, String actionId, int windowNo) {
|
||||||
this(mToolbarButton, btn, actionId, windowNo, -1);
|
this(mToolbarButton, btn, actionId, windowNo, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mToolbarButton
|
||||||
|
* @param btn
|
||||||
|
* @param actionId
|
||||||
|
* @param windowNo
|
||||||
|
* @param tabNo
|
||||||
|
*/
|
||||||
public ToolbarCustomButton(MToolBarButton mToolbarButton, Toolbarbutton btn, String actionId, int windowNo, int tabNo) {
|
public ToolbarCustomButton(MToolBarButton mToolbarButton, Toolbarbutton btn, String actionId, int windowNo, int tabNo) {
|
||||||
toolbarButton = btn;
|
toolbarButton = btn;
|
||||||
this.actionId = actionId;
|
this.actionId = actionId;
|
||||||
|
@ -49,6 +69,9 @@ public class ToolbarCustomButton implements EventListener<Event>, Evaluatee {
|
||||||
toolbarButton.addEventListener(Events.ON_CLICK, this);
|
toolbarButton.addEventListener(Events.ON_CLICK, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call {@link IAction#execute(Object)}.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(Event event) throws Exception {
|
public void onEvent(Event event) throws Exception {
|
||||||
IServiceHolder<IAction> serviceHolder = Actions.getAction(actionId);
|
IServiceHolder<IAction> serviceHolder = Actions.getAction(actionId);
|
||||||
|
@ -77,10 +100,17 @@ public class ToolbarCustomButton implements EventListener<Event>, Evaluatee {
|
||||||
return Env.getContext (Env.getCtx(), windowNo, tabNo, variableName, false, true);
|
return Env.getContext (Env.getCtx(), windowNo, tabNo, variableName, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegate to {@link #dynamicDisplay(boolean)}
|
||||||
|
*/
|
||||||
public void dynamicDisplay() {
|
public void dynamicDisplay() {
|
||||||
dynamicDisplay(false);
|
dynamicDisplay(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamic update of button state.
|
||||||
|
* @param forceValidation if true, execute dynamic update event if button is in detached state
|
||||||
|
*/
|
||||||
public void dynamicDisplay(boolean forceValidation) {
|
public void dynamicDisplay(boolean forceValidation) {
|
||||||
if (toolbarButton.getParent() == null && !forceValidation)
|
if (toolbarButton.getParent() == null && !forceValidation)
|
||||||
return;
|
return;
|
||||||
|
@ -107,6 +137,9 @@ public class ToolbarCustomButton implements EventListener<Event>, Evaluatee {
|
||||||
toolbarButton.setVisible(visible);
|
toolbarButton.setVisible(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate pressedLogic (if defined)
|
||||||
|
*/
|
||||||
public void pressedLogic() {
|
public void pressedLogic() {
|
||||||
if (toolbarButton.getParent() == null)
|
if (toolbarButton.getParent() == null)
|
||||||
return;
|
return;
|
||||||
|
@ -130,6 +163,9 @@ public class ToolbarCustomButton implements EventListener<Event>, Evaluatee {
|
||||||
((ToolBarButton) toolbarButton).setPressed(isPressed);
|
((ToolBarButton) toolbarButton).setPressed(isPressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate readOnlyLogic (if defined)
|
||||||
|
*/
|
||||||
public void readOnlyLogic() {
|
public void readOnlyLogic() {
|
||||||
if (toolbarButton.getParent() == null)
|
if (toolbarButton.getParent() == null)
|
||||||
return;
|
return;
|
||||||
|
@ -154,6 +190,13 @@ public class ToolbarCustomButton implements EventListener<Event>, Evaluatee {
|
||||||
toolbarButton.setDisabled(isReadOnly);
|
toolbarButton.setDisabled(isReadOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate SQL or boolean logic expression.
|
||||||
|
* For SQL expression, return true if the SQL expression has result (it doesn't check the return value of the SQL statement).
|
||||||
|
* @param logic
|
||||||
|
* @param tabNo
|
||||||
|
* @return result of evaluation of logic
|
||||||
|
*/
|
||||||
private boolean validateLogic(String logic, int tabNo) {
|
private boolean validateLogic(String logic, int tabNo) {
|
||||||
boolean isValid = false;
|
boolean isValid = false;
|
||||||
|
|
||||||
|
@ -169,6 +212,9 @@ public class ToolbarCustomButton implements EventListener<Event>, Evaluatee {
|
||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link Toolbarbutton}
|
||||||
|
*/
|
||||||
public Toolbarbutton getToolbarbutton() {
|
public Toolbarbutton getToolbarbutton() {
|
||||||
return toolbarButton;
|
return toolbarButton;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,22 +28,30 @@ import org.zkoss.zk.ui.event.Events;
|
||||||
import org.zkoss.zul.Button;
|
import org.zkoss.zul.Button;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Model for AD_ToolBarButton with AD_Process_ID > 0
|
||||||
* @author hengsin
|
* @author hengsin
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class ToolbarProcessButton implements IProcessButton, Evaluatee {
|
public class ToolbarProcessButton implements IProcessButton, Evaluatee {
|
||||||
|
|
||||||
|
/** model instance for AD_ToolBarButton **/
|
||||||
private MToolBarButton mToolbarButton;
|
private MToolBarButton mToolbarButton;
|
||||||
private IADTabpanel adTabpanel;
|
/** {@link IADTabpanel} that own this ToolbarProcessButton instance **/
|
||||||
|
private IADTabpanel adTabpanel;
|
||||||
|
/** translated process name **/
|
||||||
private String name;
|
private String name;
|
||||||
|
/** translated process description **/
|
||||||
private String description;
|
private String description;
|
||||||
|
/** ActionListener for button **/
|
||||||
private ActionListener actionListener;
|
private ActionListener actionListener;
|
||||||
|
/** Button instance **/
|
||||||
private Button button;
|
private Button button;
|
||||||
private int windowNo;
|
private int windowNo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param windowNo
|
* @param mToolbarButton
|
||||||
*
|
* @param adTabpanel
|
||||||
|
* @param listener
|
||||||
|
* @param windowNo
|
||||||
*/
|
*/
|
||||||
public ToolbarProcessButton(MToolBarButton mToolbarButton, IADTabpanel adTabpanel, ActionListener listener, int windowNo) {
|
public ToolbarProcessButton(MToolBarButton mToolbarButton, IADTabpanel adTabpanel, ActionListener listener, int windowNo) {
|
||||||
this.mToolbarButton = mToolbarButton;
|
this.mToolbarButton = mToolbarButton;
|
||||||
|
@ -118,10 +126,16 @@ public class ToolbarProcessButton implements IProcessButton, Evaluatee {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link Button}
|
||||||
|
*/
|
||||||
public Button getButton() {
|
public Button getButton() {
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamic update of button state.
|
||||||
|
*/
|
||||||
public void dynamicDisplay() {
|
public void dynamicDisplay() {
|
||||||
String displayLogic = mToolbarButton.getDisplayLogic();
|
String displayLogic = mToolbarButton.getDisplayLogic();
|
||||||
if (displayLogic == null || displayLogic.trim().length() == 0)
|
if (displayLogic == null || displayLogic.trim().length() == 0)
|
||||||
|
@ -140,6 +154,9 @@ public class ToolbarProcessButton implements IProcessButton, Evaluatee {
|
||||||
return Env.getContext (Env.getCtx(), windowNo, tabNo, variableName, false, true);
|
return Env.getContext (Env.getCtx(), windowNo, tabNo, variableName, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate readOnlyLogic (if defined)
|
||||||
|
*/
|
||||||
public void readOnlyLogic() {
|
public void readOnlyLogic() {
|
||||||
|
|
||||||
String readOnlyLogic = mToolbarButton.getReadOnlyLogic();
|
String readOnlyLogic = mToolbarButton.getReadOnlyLogic();
|
||||||
|
@ -150,6 +167,9 @@ public class ToolbarProcessButton implements IProcessButton, Evaluatee {
|
||||||
button.setDisabled(disabled);
|
button.setDisabled(disabled);
|
||||||
} // readOnlyLogic
|
} // readOnlyLogic
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate pressedLogic (if defined)
|
||||||
|
*/
|
||||||
public void pressedLogic() {
|
public void pressedLogic() {
|
||||||
|
|
||||||
String pressedLogic = mToolbarButton.getPressedLogic();
|
String pressedLogic = mToolbarButton.getPressedLogic();
|
||||||
|
@ -160,8 +180,14 @@ public class ToolbarProcessButton implements IProcessButton, Evaluatee {
|
||||||
button.setAttribute(ProcessButtonPopup.BUTTON_ATTRIBUTE_PRESSED, isPressed ? "Y" : "N");
|
button.setAttribute(ProcessButtonPopup.BUTTON_ATTRIBUTE_PRESSED, isPressed ? "Y" : "N");
|
||||||
} // pressedLogic
|
} // pressedLogic
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate SQL or boolean logic expression.
|
||||||
|
* For SQL expression, return true if the SQL expression has result (it doesn't check the return value of the SQL statement).
|
||||||
|
* @param logic SQL (@SQL=) or boolean expression
|
||||||
|
* @param tabNo
|
||||||
|
* @return result of evaluation of logic
|
||||||
|
*/
|
||||||
private boolean validateLogic(String logic, int tabNo) {
|
private boolean validateLogic(String logic, int tabNo) {
|
||||||
|
|
||||||
boolean isValid = false;
|
boolean isValid = false;
|
||||||
if (logic.startsWith("@SQL=")) {
|
if (logic.startsWith("@SQL=")) {
|
||||||
isValid = Evaluator.parseSQLLogic(logic, Env.getCtx(), windowNo, tabNo, getColumnName());
|
isValid = Evaluator.parseSQLLogic(logic, Env.getCtx(), windowNo, tabNo, getColumnName());
|
||||||
|
|
|
@ -1,7 +1,41 @@
|
||||||
|
/***********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* 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., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - hengsin *
|
||||||
|
**********************************************************************/
|
||||||
package org.adempiere.webui.adwindow.validator;
|
package org.adempiere.webui.adwindow.validator;
|
||||||
|
|
||||||
import org.adempiere.util.Callback;
|
import org.adempiere.util.Callback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for AD Window event
|
||||||
|
* @author hengsin
|
||||||
|
*/
|
||||||
public interface WindowValidator {
|
public interface WindowValidator {
|
||||||
|
/**
|
||||||
|
* Handle {@link WindowValidatorEvent}.
|
||||||
|
* Call callback with the result of the event (success or error).
|
||||||
|
* @param event
|
||||||
|
* @param callback optional callback
|
||||||
|
*/
|
||||||
public void onWindowEvent(WindowValidatorEvent event, Callback<Boolean> callback);
|
public void onWindowEvent(WindowValidatorEvent event, Callback<Boolean> callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,60 @@
|
||||||
|
/***********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* 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., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - hengsin *
|
||||||
|
**********************************************************************/
|
||||||
package org.adempiere.webui.adwindow.validator;
|
package org.adempiere.webui.adwindow.validator;
|
||||||
|
|
||||||
import org.adempiere.webui.adwindow.ADWindow;
|
import org.adempiere.webui.adwindow.ADWindow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validation event for AD Window
|
||||||
|
* @author hengsin
|
||||||
|
*/
|
||||||
public class WindowValidatorEvent {
|
public class WindowValidatorEvent {
|
||||||
|
/** {@link ADWindow} instance **/
|
||||||
private ADWindow window;
|
private ADWindow window;
|
||||||
|
/** Event name **/
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param window
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
public WindowValidatorEvent(ADWindow window, String name) {
|
public WindowValidatorEvent(ADWindow window, String name) {
|
||||||
this.window = window;
|
this.window = window;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link ADWindow}
|
||||||
|
*/
|
||||||
public ADWindow getWindow() {
|
public ADWindow getWindow() {
|
||||||
return this.window;
|
return this.window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Event name
|
||||||
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,34 @@
|
||||||
|
/***********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* 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., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - hengsin *
|
||||||
|
**********************************************************************/
|
||||||
package org.adempiere.webui.adwindow.validator;
|
package org.adempiere.webui.adwindow.validator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Predefine AD Window validation event type
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
public enum WindowValidatorEventType {
|
public enum WindowValidatorEventType {
|
||||||
BEFORE_IGNORE("beforeIgnore"),
|
BEFORE_IGNORE("beforeIgnore"),
|
||||||
AFTER_IGNORE("afterIgnore"),
|
AFTER_IGNORE("afterIgnore"),
|
||||||
|
@ -14,12 +43,19 @@ public enum WindowValidatorEventType {
|
||||||
BEFORE_COPY("beforeCopy"),
|
BEFORE_COPY("beforeCopy"),
|
||||||
AFTER_COPY("afterCopy");
|
AFTER_COPY("afterCopy");
|
||||||
|
|
||||||
|
/** Event name **/
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
private WindowValidatorEventType(String name) {
|
private WindowValidatorEventType(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Event name
|
||||||
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,27 @@
|
||||||
|
/***********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* 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., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - hengsin *
|
||||||
|
**********************************************************************/
|
||||||
package org.adempiere.webui.adwindow.validator;
|
package org.adempiere.webui.adwindow.validator;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -13,14 +37,25 @@ import org.osgi.framework.ServiceReference;
|
||||||
import org.osgi.util.tracker.ServiceTracker;
|
import org.osgi.util.tracker.ServiceTracker;
|
||||||
import org.osgi.util.tracker.ServiceTrackerCustomizer;
|
import org.osgi.util.tracker.ServiceTrackerCustomizer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Manage {@link WindowValidator} osgi services
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class WindowValidatorManager implements BundleActivator, ServiceTrackerCustomizer<WindowValidator, WindowValidator> {
|
public class WindowValidatorManager implements BundleActivator, ServiceTrackerCustomizer<WindowValidator, WindowValidator> {
|
||||||
|
|
||||||
|
/** Singleton WindowValidatorManager instance **/
|
||||||
private static WindowValidatorManager instance = null;
|
private static WindowValidatorManager instance = null;
|
||||||
|
|
||||||
|
/** {@link BundleContext} instance **/
|
||||||
private BundleContext context;
|
private BundleContext context;
|
||||||
|
/** AD_Window_UU:List<WindowValidator> **/
|
||||||
private Map<String, List<WindowValidator>> validatorMap = new HashMap<String, List<WindowValidator>>();
|
private Map<String, List<WindowValidator>> validatorMap = new HashMap<String, List<WindowValidator>>();
|
||||||
|
/** WindowValidator for all AD Window **/
|
||||||
private List<WindowValidator> globalValidators = new ArrayList<WindowValidator>();
|
private List<WindowValidator> globalValidators = new ArrayList<WindowValidator>();
|
||||||
|
|
||||||
|
/** WindowValidator osgi service tracker **/
|
||||||
private ServiceTracker<WindowValidator, WindowValidator> serviceTracker;
|
private ServiceTracker<WindowValidator, WindowValidator> serviceTracker;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -46,7 +81,12 @@ public class WindowValidatorManager implements BundleActivator, ServiceTrackerCu
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addService(WindowValidator service, String uuid) {
|
/**
|
||||||
|
* Add {@link WindowValidator} service for an AD Window
|
||||||
|
* @param service
|
||||||
|
* @param uuid AD_Window_UU
|
||||||
|
*/
|
||||||
|
protected void addService(WindowValidator service, String uuid) {
|
||||||
List<WindowValidator> list = validatorMap.get(uuid);
|
List<WindowValidator> list = validatorMap.get(uuid);
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
list = new ArrayList<WindowValidator>();
|
list = new ArrayList<WindowValidator>();
|
||||||
|
@ -81,13 +121,21 @@ public class WindowValidatorManager implements BundleActivator, ServiceTrackerCu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeService(WindowValidator service, String uuid) {
|
/**
|
||||||
|
*
|
||||||
|
* @param service
|
||||||
|
* @param uuid
|
||||||
|
*/
|
||||||
|
protected void removeService(WindowValidator service, String uuid) {
|
||||||
List<WindowValidator> list = validatorMap.get(uuid);
|
List<WindowValidator> list = validatorMap.get(uuid);
|
||||||
if (list != null) {
|
if (list != null) {
|
||||||
list.remove(service);
|
list.remove(service);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create {@link #serviceTracker} and {@link #instance}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void start(BundleContext context) throws Exception {
|
public void start(BundleContext context) throws Exception {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
@ -97,6 +145,9 @@ public class WindowValidatorManager implements BundleActivator, ServiceTrackerCu
|
||||||
instance = this;
|
instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close {@link #serviceTracker} and dispose {@link #instance}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void stop(BundleContext context) throws Exception {
|
public void stop(BundleContext context) throws Exception {
|
||||||
serviceTracker.close();
|
serviceTracker.close();
|
||||||
|
@ -104,10 +155,19 @@ public class WindowValidatorManager implements BundleActivator, ServiceTrackerCu
|
||||||
instance = null;
|
instance = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return {@link WindowValidatorManager}
|
||||||
|
*/
|
||||||
public static WindowValidatorManager getInstance() {
|
public static WindowValidatorManager getInstance() {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fire window validator event for all register {@link WindowValidator} service
|
||||||
|
* @param event
|
||||||
|
* @param callback optional callback
|
||||||
|
*/
|
||||||
public void fireWindowValidatorEvent(WindowValidatorEvent event, Callback<Boolean> callback) {
|
public void fireWindowValidatorEvent(WindowValidatorEvent event, Callback<Boolean> callback) {
|
||||||
ADWindow window = event.getWindow();
|
ADWindow window = event.getWindow();
|
||||||
String uuid = window.getAD_Window_UU();
|
String uuid = window.getAD_Window_UU();
|
||||||
|
@ -129,19 +189,32 @@ public class WindowValidatorManager implements BundleActivator, ServiceTrackerCu
|
||||||
chain.start();
|
chain.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class to call a list of {@link WindowValidator} through {@link Callback} chain.
|
||||||
|
*/
|
||||||
private static class ChainCallback implements Callback<Boolean> {
|
private static class ChainCallback implements Callback<Boolean> {
|
||||||
|
/** optional callback to invoke after execution of all {@link #validators} or when there's error **/
|
||||||
private Callback<Boolean> callback;
|
private Callback<Boolean> callback;
|
||||||
private WindowValidator[] validators;
|
private WindowValidator[] validators;
|
||||||
|
/** event for {@link #validators} **/
|
||||||
private WindowValidatorEvent event;
|
private WindowValidatorEvent event;
|
||||||
|
/** current index of {@link #validators} **/
|
||||||
private int index = -1;
|
private int index = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param event
|
||||||
|
* @param validators
|
||||||
|
* @param callback optional callback to invoke after execution of all {@link #validators} or when there's error
|
||||||
|
*/
|
||||||
public ChainCallback(WindowValidatorEvent event, WindowValidator[] validators, Callback<Boolean> callback) {
|
public ChainCallback(WindowValidatorEvent event, WindowValidator[] validators, Callback<Boolean> callback) {
|
||||||
this.event = event;
|
this.event = event;
|
||||||
this.validators = validators;
|
this.validators = validators;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the @link {@link WindowValidator} callback chain.
|
||||||
|
*/
|
||||||
public void start() {
|
public void start() {
|
||||||
index = 0;
|
index = 0;
|
||||||
if (index < validators.length)
|
if (index < validators.length)
|
||||||
|
|
|
@ -31,6 +31,7 @@ import java.util.Properties;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import org.adempiere.util.LogAuthFailure;
|
import org.adempiere.util.LogAuthFailure;
|
||||||
|
import org.adempiere.webui.AdempiereWebUI;
|
||||||
import org.adempiere.webui.LayoutUtils;
|
import org.adempiere.webui.LayoutUtils;
|
||||||
import org.adempiere.webui.apps.AEnv;
|
import org.adempiere.webui.apps.AEnv;
|
||||||
import org.adempiere.webui.component.Button;
|
import org.adempiere.webui.component.Button;
|
||||||
|
@ -660,7 +661,7 @@ public class LoginPanel extends Window implements EventListener<Event>
|
||||||
// [ adempiere-ZK Web Client-2832968 ] User context lost?
|
// [ adempiere-ZK Web Client-2832968 ] User context lost?
|
||||||
// https://sourceforge.net/p/adempiere/zk-web-client/303/
|
// https://sourceforge.net/p/adempiere/zk-web-client/303/
|
||||||
// it's harmless, if there is no bug then this must never fail
|
// it's harmless, if there is no bug then this must never fail
|
||||||
currSess.setAttribute("Check_AD_User_ID", Env.getAD_User_ID(ctx));
|
currSess.setAttribute(AdempiereWebUI.CHECK_AD_USER_ID_ATTR, Env.getAD_User_ID(ctx));
|
||||||
// End of temporary code for [ adempiere-ZK Web Client-2832968 ] User context lost?
|
// End of temporary code for [ adempiere-ZK Web Client-2832968 ] User context lost?
|
||||||
|
|
||||||
/* Check DB version */
|
/* Check DB version */
|
||||||
|
|
|
@ -30,6 +30,7 @@ import java.util.Properties;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
import org.adempiere.util.Callback;
|
import org.adempiere.util.Callback;
|
||||||
|
import org.adempiere.webui.AdempiereWebUI;
|
||||||
import org.adempiere.webui.IWebClient;
|
import org.adempiere.webui.IWebClient;
|
||||||
import org.adempiere.webui.component.FWindow;
|
import org.adempiere.webui.component.FWindow;
|
||||||
import org.adempiere.webui.component.Window;
|
import org.adempiere.webui.component.Window;
|
||||||
|
@ -297,7 +298,7 @@ public class LoginWindow extends FWindow implements EventListener<Event>
|
||||||
else
|
else
|
||||||
loginName = user.getLDAPUser() != null ? user.getLDAPUser() : user.getName();
|
loginName = user.getLDAPUser() != null ? user.getLDAPUser() : user.getName();
|
||||||
loginOk(loginName, true, login.getClients());
|
loginOk(loginName, true, login.getClients());
|
||||||
getDesktop().getSession().setAttribute("Check_AD_User_ID", Env.getAD_User_ID(ctx));
|
getDesktop().getSession().setAttribute(AdempiereWebUI.CHECK_AD_USER_ID_ATTR, Env.getAD_User_ID(ctx));
|
||||||
pnlRole.setChangeRole(true);
|
pnlRole.setChangeRole(true);
|
||||||
pnlRole.changeRole(ctx);
|
pnlRole.changeRole(ctx);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue