blob: a173b7ab4248ab44af4c11a470fd1cdc6c51cbb7 [file] [log] [blame]
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*******************************************************************************/
package org.ofbiz.pos.screen;
import java.awt.AWTEvent;
import java.awt.Frame;
import java.awt.Window;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.math.BigDecimal;
import java.util.Locale;
import net.xoetrope.xui.XPage;
import net.xoetrope.xui.XProject;
import net.xoetrope.xui.XProjectManager;
import org.ofbiz.base.splash.SplashLoader;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilFormatOut;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.guiapp.xui.XuiContainer;
import org.ofbiz.guiapp.xui.XuiSession;
import org.ofbiz.pos.PosTransaction;
import org.ofbiz.pos.adaptor.KeyboardAdaptor;
import org.ofbiz.pos.component.InputWithPassword;
import org.ofbiz.pos.component.Journal;
import org.ofbiz.pos.component.Operator;
import org.ofbiz.pos.component.Output;
import org.ofbiz.pos.component.PosButton;
import org.ofbiz.pos.component.PromoStatusBar;
import org.ofbiz.pos.device.DeviceLoader;
@SuppressWarnings("serial")
public class PosScreen extends XPage implements Runnable, DialogCallback, FocusListener {
public static final String module = PosScreen.class.getName();
public static final Frame appFrame = XProjectManager.getCurrentProject().getAppFrame();
public static final Window appWin = XProjectManager.getCurrentProject().getAppWindow();
public static final String BUTTON_ACTION_METHOD = "buttonPressed";
public static final long MAX_INACTIVITY = Long.valueOf(UtilProperties.getPropertyValue(PosTransaction.resource, "MaxInactivity", "1800000"));
public static PosScreen currentScreen;
protected XProject currentProject = XProjectManager.getCurrentProject();
protected static boolean monitorRunning = false;
protected static boolean firstInit = false;
protected static long lastActivity = 0;
protected static Thread activityMonitor = null;
protected ClassLoader classLoader = null;
protected XuiSession session = null;
protected Output output = null;
protected InputWithPassword input = null;
protected Journal journal = null;
protected Operator operator = null;
protected PosButton buttons = null;
protected String scrLocation = null;
protected boolean isLocked = false;
protected boolean inDialog = false;
protected PromoStatusBar promoStatusBar = null;
private Locale defaultLocale = Locale.getDefault();
public PosScreen() {
super();
this.classLoader = Thread.currentThread().getContextClassLoader();
this.addFocusListener(this);
}
@Override
public void pageCreated() {
super.pageCreated();
// initial settings
this.setEnabled(false);
this.setVisible(false);
// setup the shared components
this.session = XuiContainer.getSession();
this.output = new Output(this);
this.input = new InputWithPassword(this);
this.journal = new Journal(this);
this.operator = new Operator(this);
this.promoStatusBar = new PromoStatusBar(this);
this.setLastActivity(System.currentTimeMillis());
if (!firstInit) {
firstInit = true;
// pre-load a few screens
currentProject.getPageManager().loadPage(this.getScreenLocation() + "/paypanel");
currentProject.getPageManager().loadPage(this.getScreenLocation() + "/mgrpanel");
currentProject.getPageManager().loadPage(this.getScreenLocation() + "/promopanel");
// start the shared monitor thread
if (activityMonitor == null) {
monitorRunning = true;
activityMonitor = new Thread(this);
activityMonitor.setDaemon(false);
activityMonitor.start();
}
// configure the window listener
KeyboardAdaptor.attachComponents(appWin, false);
appFrame.addFocusListener(this);
appWin.addFocusListener(this);
// close the splash screen
SplashLoader.close();
}
// buttons are different per screen
this.buttons = new PosButton(this);
// make sure all components have the keyboard set
KeyboardAdaptor.attachComponents(this);
}
@Override
public void pageActivated() {
super.pageActivated();
this.setLastActivity(System.currentTimeMillis());
// The input receives keyboard events even when it's page is deactivated, so
// we'll clear it early to prevent the characters from displaying momentarily
input.clearInput();
if (session.getUserLogin() == null) {
this.setLock(true);
} else {
this.setLock(isLocked);
}
currentScreen = this;
this.refresh();
}
@Override
public void pageDeactivated() {
super.pageDeactivated();
if (Debug.verboseOn()) {
this.logInfo();
}
}
public void logInfo() {
Debug.logInfo("App Frame :", module);
Debug.logInfo("name - " + appFrame.getName(), module);
Debug.logInfo("title - " + appFrame.getTitle(), module);
Debug.logInfo("active - " + appFrame.isActive(), module);
Debug.logInfo("enabled - " + appFrame.isEnabled(), module);
Debug.logInfo("visible - " + appFrame.isVisible(), module);
Debug.logInfo("showing - " + appFrame.isShowing(), module);
Debug.logInfo("opaque - " + appFrame.isOpaque(), module);
Debug.logInfo("focusable - " + appFrame.isFocusable(), module);
Debug.logInfo("focused - " + appFrame.isFocused(), module);
Debug.logInfo("hasFocus - " + appFrame.hasFocus(), module);
Debug.logInfo("", module);
Debug.logInfo("App Window :", module);
Debug.logInfo("name - " + appWin.getName(), module);
Debug.logInfo("active - " + appWin.isActive(), module);
Debug.logInfo("enabled - " + appWin.isEnabled(), module);
Debug.logInfo("visible - " + appWin.isVisible(), module);
Debug.logInfo("showing - " + appWin.isShowing(), module);
Debug.logInfo("opaque - " + appWin.isOpaque(), module);
Debug.logInfo("focusable - " + appWin.isFocusable(), module);
Debug.logInfo("focused - " + appWin.isFocused(), module);
Debug.logInfo("hasFocus - " + appWin.hasFocus(), module);
Debug.logInfo("", module);
Debug.logInfo("POS Screen :", module);
Debug.logInfo("name - " + this.getName(), module);
Debug.logInfo("enabled - " + this.isEnabled(), module);
Debug.logInfo("visible - " + this.isVisible(), module);
Debug.logInfo("showing - " + this.isShowing(), module);
Debug.logInfo("opaque - " + this.isOpaque(), module);
Debug.logInfo("focusable - " + this.isFocusable(), module);
Debug.logInfo("focused - " + this.hasFocus(), module);
}
public void refresh() {
this.refresh(true);
}
public void refresh(boolean updateOutput) {
PosTransaction trans = PosTransaction.getCurrentTx(this.getSession());
if (trans == null) {
updateOutput = false;
}
appFrame.requestFocus();
this.lockScreenButton(this);
//this.requestFocus();
if (!isLocked) {
this.setEnabled(true);
this.setVisible(true);
journal.refresh(this);
input.clearInput();
operator.refresh();
if (updateOutput) {
if (input.isFunctionSet("PAID")) {
output.print(UtilProperties.getMessage(PosTransaction.resource,"PosChange",defaultLocale)
+ UtilFormatOut.formatPrice(trans.getTotalDue().negate()));
} else if (input.isFunctionSet("TOTAL")) {
if (trans.getTotalDue().compareTo(BigDecimal.ZERO) > 0) {
output.print(UtilProperties.getMessage(PosTransaction.resource,"PosTotalD",defaultLocale) + " " + UtilFormatOut.formatPrice(trans.getTotalDue()));
} else {
output.print(UtilProperties.getMessage(PosTransaction.resource,"PosPayFin",defaultLocale));
}
} else {
if (PosTransaction.getCurrentTx(session).isOpen()) {
output.print(UtilProperties.getMessage(PosTransaction.resource,"PosIsOpen",defaultLocale));
} else {
output.print(UtilProperties.getMessage(PosTransaction.resource,"PosIsClosed",defaultLocale));
}
}
} else {
promoStatusBar.clear();
}
//journal.focus();
} else {
output.print(UtilProperties.getMessage(PosTransaction.resource,"PosULogin",defaultLocale));
//input.focus();
}
this.repaint();
//this.logInfo();
}
public boolean isLocked() {
return isLocked;
}
public void setLock(boolean lock) {
this.buttons.setLock(lock);
this.input.setLock(lock);
this.output.setLock(lock);
this.journal.setLock(lock);
this.operator.setLock(lock);
this.isLocked = lock;
if (lock) {
this.input.setFunction("LOGIN");
}
DeviceLoader.enable(!lock);
}
public XuiSession getSession() {
return this.session;
}
public InputWithPassword getInput() {
return this.input;
}
public Output getOutput() {
return this.output;
}
public Journal getJournal() {
return this.journal;
}
public PosButton getButtons() {
return this.buttons;
}
public PromoStatusBar getPromoStatusBar() {
return this.promoStatusBar;
}
public void setLastActivity(long l) {
lastActivity = l;
}
public ClassLoader getClassLoader() {
return classLoader;
}
// generic button XUI event calls into PosButton to lookup the external reference
public synchronized void buttonPressed() {
this.setLastActivity(System.currentTimeMillis());
buttons.buttonPressed(this, (AWTEvent)this.getCurrentEvent());
journal.focus();
}
// generic page display methods - extends those in XPage
@Override
public PosScreen showPage(String pageName) {
return this.showPage(pageName, true);
}
public PosScreen showPage(String pageName, boolean refresh) {
if (pageName.startsWith("/")) {
pageName = pageName.substring(1);
}
XPage newPage = (XPage)currentProject.getPageManager().showPage(this.getScreenLocation() + "/" + pageName);
if (newPage instanceof PosScreen) {
if (refresh) ((PosScreen) newPage).refresh();
return (PosScreen) newPage;
}
return null;
}
public void lockScreenButton(PosScreen pos) {
if ((this.getScreenLocation() + "/pospanel").equals(pos.getName())) {
pos.getButtons().setLock("menuMain", true);
} else if ((this.getScreenLocation() + "/mgrpanel").equals(pos.getName())) {
pos.getButtons().setLock("menuMgr", true);
} else if ((this.getScreenLocation() + "/paypanel").equals(pos.getName())) {
pos.getButtons().setLock("menuPay", true);
} else if ((this.getScreenLocation() + "/promopanel").equals(pos.getName())) {
pos.getButtons().setLock("menuPromo", true);
}
}
public PosDialog showDialog(String pageName) {
return showDialog(pageName, this, null);
}
public PosDialog showDialog(String pageName, String text) {
return showDialog(pageName, this, text);
}
public PosDialog showDialog(String pageName, DialogCallback cb) {
return showDialog(pageName, cb, null);
}
public PosDialog showDialog(String pageName, DialogCallback cb, String text) {
if (pageName.startsWith("/")) {
pageName = pageName.substring(1);
}
XPage dialogPage = (XPage)currentProject.getPageManager().loadPage(this.getScreenLocation() + "/" + pageName);
PosDialog dialog = PosDialog.getInstance(dialogPage, true, 0);
dialog.showDialog(this, cb, text);
return dialog;
}
// PosDialog Callback method
public void receiveDialogCb(PosDialog dialog) {
Debug.logInfo("Dialog closed; refreshing screen", module);
this.refresh();
}
// run method for auto-locking POS on inactivity
public void run() {
while (monitorRunning) {
if (!isLocked && (System.currentTimeMillis() - lastActivity) > MAX_INACTIVITY) {
Debug.logInfo("POS terminal auto-lock activated", module);
PosScreen.currentScreen.showPage("pospanel").setLock(true);
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Debug.logError(e, module);
}
}
}
public void focusGained(FocusEvent event) {
if (Debug.verboseOn()) {
String from = event != null && event.getOppositeComponent() != null ? event.getOppositeComponent().getName() : "??";
Debug.logInfo(event.getSource() + " focus gained from " + from, module);
}
}
public void focusLost(FocusEvent event) {
if (Debug.verboseOn()) {
String to = event != null && event.getOppositeComponent() != null ? event.getOppositeComponent().getName() : "??";
Debug.logInfo(event.getSource() + " focus lost to " + to, module);
}
}
public String getScreenLocation() {
if (this.scrLocation == null) {
synchronized(this) {
if (this.scrLocation == null) {
String xuiProps = this.getSession().getContainer().getXuiPropertiesName();
String startClass = UtilProperties.getPropertyValue(xuiProps, "StartClass", "default/pospanel");
this.scrLocation = startClass.substring(0, startClass.lastIndexOf("/"));
}
}
}
return this.scrLocation;
}
public void setWaitCursor() {
setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
}
public void setNormalCursor() {
setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.DEFAULT_CURSOR));
}
}