/*
* FrontlineSMS <http://www.frontlinesms.com>
* Copyright 2007, 2008 kiwanja
*
* This file is part of FrontlineSMS.
*
* FrontlineSMS is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* FrontlineSMS 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 Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FrontlineSMS. If not, see <http://www.gnu.org/licenses/>.
*/
package net.frontlinesms.ui;
import java.awt.Image;
import net.frontlinesms.ErrorUtils;
import net.frontlinesms.FrontlineUtils;
import net.frontlinesms.ui.handler.core.FileChooser;
import net.frontlinesms.ui.i18n.LanguageBundle;
import org.apache.log4j.Logger;
import thinlet.FrameLauncher;
/**
* Base UI used for FrontlineSMS.
*/
@SuppressWarnings("serial")
public abstract class FrontlineUI extends ExtendedThinlet implements ThinletUiEventHandler {
//> UI DEFINITION FILES
/** Thinlet UI layout File: alert popup box */
protected static final String UI_FILE_ALERT = "/ui/core/util/dgAlert.xml";
/** Thinlet UI layout File: info popup box */
protected static final String UI_FILE_INFO = "/ui/core/util/dgInfo.xml";
//> UI COMPONENTS
/** Component of {@link #UI_FILE_ALERT} which contains the message to display */
private static final String COMPONENT_PN_ALERTS = "pnAlerts";
/** Component of {@link #UI_FILE_INFO} which contains the message to display */
private static final String COMPONENT_PN_INFO = "pnInfo";
//> INSTANCE PROPERTIES
/** Logging object */
protected final Logger log = FrontlineUtils.getLogger(this.getClass());
/** The language bundle currently in use. N.B. THIS CAN BE NULL, IN WHICH CASE THE DEFAULT BUNDLE SHOULD BE USED TODO handle and document this better */
public static LanguageBundle currentResourceBundle;
/** Frame launcher that this UI instance is displayed within. We need to keep a handle on it so that we can dispose of it when we quit or change UI modes. */
protected FrameLauncher frameLauncher;
/**
* Gets the icon for a specific language bundle
* @param languageBundle
* @return the flag image for the language bundle, or <code>null</code> if none could be found.
*/
public Image getFlagIcon(LanguageBundle languageBundle) {
return getFlagIcon(languageBundle.getCountry());
}
/**
* Gets the path to the icon for a specific country
* @param languageBundle
* @return the flag image for the language bundle, or <code>null</code> if none could be found.
*/
public String getFlagIconPath(String country) {
return country != null ? "/icons/flags/" + country + ".png" : null;
}
/**
* Gets the icon for a specific country
* @param languageBundle
* @return the flag image for the language bundle, or <code>null</code> if none could be found.
*/
public Image getFlagIcon(String country) {
return country == null ? null : getIcon(getFlagIconPath(country));
}
/**
* Loads a Thinlet UI descriptor from an XML file. If there are any
* problems loading the file, this will log Throwables thrown and
* allow the program to continue running.
*
* {@link #loadComponentFromFile(String, Object)} should always be used by external handlers in preference to this.
* @param filename path of the UI XML file to load from
* @return thinlet component loaded from the file
*/
public Object loadComponentFromFile(String filename) {
return loadComponentFromFile(filename, this);
}
/**
* Loads a Thinlet UI descriptor from an XML file and sets the provided event handler.
* If there are any problems loading the file, this will log Throwables thrown and
* allow the program to continue running.
* @param filename path of the UI XML file to load from
* @param thinletEventHandler event handler for the UI component
* @return thinlet component loaded from the file
*/
public Object loadComponentFromFile(String filename, ThinletUiEventHandler thinletEventHandler) {
log.trace("ENTER");
try {
log.debug("Filename [" + filename + "]");
log.trace("EXIT");
return parse(filename, thinletEventHandler);
} catch(Throwable t) {
log.error("Error parsing file [" + filename + "]", t);
log.trace("EXIT");
throw new RuntimeException(t);
}
}
/**
* This method opens a fileChooser.
* @param textFieldToBeSet The text field whose value should be sert to the chosen file
*/
public void showFileChooser(Object textFieldToBeSet) {
FileChooser.showFileChooser(this, textFieldToBeSet);
}
/**
* This method opens a fileChooser and specifies a handler.
* @param handler The UI handler
* @param methodName The method to be called on the handler
*/
public void showFileChooser(ThinletUiEventHandler handler, String methodName) {
FileChooser.showFileChooser(this, handler, methodName);
}
/**
* Popup an alert to the user with the supplied messages.
* @param alertMessages
*/
public void alert(String[] alertMessages) {
Object alertDialog = loadComponentFromFile(UI_FILE_ALERT);
Object pnAlerts = find(alertDialog, COMPONENT_PN_ALERTS);
for (String alertMessage : alertMessages) {
add(pnAlerts, createLabel(alertMessage));
}
add(alertDialog);
}
/**
* Popup an alert to the user with the supplied messages.
* @param alertMessages
*/
public void alert(Object[] alertItems) {
Object alertDialog = loadComponentFromFile(UI_FILE_ALERT);
Object pnAlerts = find(alertDialog, COMPONENT_PN_ALERTS);
for (Object alertItem : alertItems) {
add(pnAlerts, alertItem);
}
add(alertDialog);
}
/**
* Popup an alert to the user with the supplied message.
* @param alertMessage
*/
public void alert(String alertMessage) {
alert(new String[] { alertMessage });
}
/**
* Popup an info message to the user with the supplied messages.
* @param infoMessages
*/
public void infoMessage(String[] infoMessages) {
Object infoDialog = loadComponentFromFile(UI_FILE_INFO);
Object pnInfo = find(infoDialog, COMPONENT_PN_INFO);
for (String infoMessage : infoMessages) {
add(pnInfo, createLabel(infoMessage));
}
//setText(find(infoDialog, COMPONENT_INFO_MESSAGE), infoMessage);
add(infoDialog);
}
/**
* Popup an info message to the user with the supplied message.
* @param infoMessage
*/
public void infoMessage(String infoMessage) {
infoMessage(new String[] { infoMessage });
}
/**
* Removes the supplied dialog from the application.
*
* @param dialog
*/
public void removeDialog(Object dialog) {
remove(dialog);
}
/**
* Opens a link in the system browser
* @param url the url to open
* @see FrontlineUtils#openExternalBrowser(String)
*/
public void openBrowser(String url) {
FrontlineUtils.openExternalBrowser(url);
}
/**
* Opens a page of the help manual
* @param page The name of the help manual page, including file extension.
*/
public void showHelpPage(String page) {
FrontlineUtils.openHelpPageInBrowser(page);
}
/**
* Shows an error dialog informing the user that an unhandled error has occurred.
*/
@Override
protected void handleException(Throwable throwable) {
log.error("Unhandled exception from thinlet.", throwable);
ErrorUtils.showErrorDialog("Unexpected error", "There was an unexpected error.", throwable, false);
}
}