package org.openslx.dozmod.gui;
import java.lang.reflect.Constructor;
import org.apache.log4j.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.openslx.dozmod.Config;
import org.openslx.dozmod.gui.helper.Gui;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.gui.window.DisclaimerWindow;
import org.openslx.dozmod.gui.window.LoginWindow;
import org.openslx.dozmod.gui.window.MainMenuWindow;
import org.openslx.dozmod.gui.window.VirtualizerNoticeWindow;
import org.openslx.dozmod.thrift.Session;
import org.openslx.thrifthelper.ThriftManager;
import org.openslx.thrifthelper.ThriftManager.ErrorCallback;
public abstract class MainWindow {
private final static Logger LOGGER = Logger.getLogger(MainWindow.class);
private static final Shell mainShell;
private static Composite contentComposite;
private static final String THRIFT_CONNECTION_ERROR = "Lost connection to the masterserver. Do you want to retry?";
/**
* Add a new composite with content to the main Shell
*
* @param The composite to add, should be a GUI
*/
public static void setContent(Composite contentComposite) {
if (contentComposite == null)
return;
if (MainWindow.contentComposite != null)
MainWindow.contentComposite.dispose();
MainWindow.contentComposite = contentComposite;
// sets the starting preferred size.
contentComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
mainShell.layout();
}
/**
* @param clazz Class to open as a popup over the main window.
* MUST be a subclass of Composite.
*/
public static void openPopup(Class<? extends Composite> clazz, boolean modal) {
Shell dialogShell = new Shell(mainShell, SWT.DIALOG_TRIM | (modal ? SWT.APPLICATION_MODAL : 0));
// populate dialogShell
dialogShell.setLayout(new GridLayout(1, false));
LOGGER.debug(clazz.getDeclaredClasses());
Constructor<?> con = null;
try {
con = clazz.getConstructor(Shell.class);
con.newInstance(dialogShell);
} catch (Exception e1) {
showMessageBox(mainShell, "Cannot show popup " + clazz.getName(), MessageType.DEBUG, LOGGER, e1);
return;
}
dialogShell.layout();
dialogShell.pack();
Gui.limitShellSize(dialogShell);
dialogShell.open();
}
/**
* Initialises the GUI by creating the main window, adding the menu and
* creating the login mask as the first content window.
* Further sets up the global thrift error callback to catch any
* connection errors during the communication with the servers.
*/
static {
// init SWT stuff
mainShell = new Shell(Gui.display, SWT.SHELL_TRIM | SWT.CENTER);
// Set up thrift error message displaying
ThriftManager.setErrorCallback(new ErrorCallback() {
@Override
public boolean thriftError(int failCount, String method, Throwable t) {
// Ask user if we should retry
return showMessageBox(mainShell, THRIFT_CONNECTION_ERROR, MessageType.ERROR_RETRY, LOGGER, t);
}
});
// Same for config errors
Config.setErrorCallback(new Config.ErrorCallback() {
@Override
public void writeError(Throwable t) {
showMessageBox("Konnte Programmeinstellungen nicht speichern", MessageType.WARNING, LOGGER, t);
}
});
// Global key listener
Gui.display.addFilter(SWT.KeyDown, new Listener() {
@Override
public void handleEvent(Event event) {
if (event.character == 17) // Ctrl-Q = Quit
System.exit(0);
}
});
createMenu();
mainShell.setText("bwSuite");
// Set layout for the mainshell, items added to the shell should get a gridData
mainShell.setLayout(new GridLayout(1, true));
mainShell.setMinimumSize(850, 650);
// always show the main menu
setContent(new MainMenuWindow(mainShell));
// center the window on the primary monitor
Gui.centerShell(mainShell);
mainShell.open();
// here we can check for Session information
if (Session.getSatelliteToken() == null) {
// User did not login, show the login mask
openPopup(LoginWindow.class, true);
}
}
/**
* Run the GUI mainloop as long as the main window exists.
*/
public static void mainloop() {
while (!mainShell.isDisposed()) {
if (!Gui.display.readAndDispatch())
Gui.display.sleep();
}
}
private static void createMenu() {
// the File menu button
Menu menuBar = new Menu(mainShell, SWT.BAR);
MenuItem cascadeFileMenu = new MenuItem(menuBar, SWT.CASCADE);
cascadeFileMenu.setText("&File");
Menu fileMenu = new Menu(mainShell, SWT.DROP_DOWN);
cascadeFileMenu.setMenu(fileMenu);
MenuItem exitItem = new MenuItem(fileMenu, SWT.PUSH);
exitItem.setText("&Exit");
exitItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
System.exit(0);
}
});
// the About menu button
MenuItem cascadeAboutMenu = new MenuItem(menuBar, SWT.CASCADE);
cascadeAboutMenu.setText("&About");
Menu aboutMenu = new Menu(mainShell, SWT.DROP_DOWN);
cascadeAboutMenu.setMenu(aboutMenu);
MenuItem disclaimerItem = new MenuItem(aboutMenu, SWT.PUSH);
disclaimerItem.setText("&Disclaimer");
disclaimerItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
MainWindow.openPopup(DisclaimerWindow.class, false);
}
});
MenuItem virtualizerNoticeItem = new MenuItem(aboutMenu, SWT.PUSH);
virtualizerNoticeItem.setText("&Virtualizer");
virtualizerNoticeItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
MainWindow.openPopup(VirtualizerNoticeWindow.class, false);
}
});
mainShell.setMenuBar(menuBar);
}
/**
* Generic helper to show a message box to the user, and optionally log the
* message to the log file. The main window will be the parent of the
* message box.
*
* @param message Message to display. Can be multiline.
* @param messageType Type of message (warning, information)
* @param logger Logger instance to log to. Can be null.
* @param exception Exception related to this message. Can be null.
* @return true if OK, YES or RETRY was clicked, false for CANCEL or NO
*/
public static boolean showMessageBox(String message, MessageType messageType, Logger logger,
Throwable exception) {
return showMessageBox(mainShell, message, messageType, logger, exception);
}
/**
* Generic helper to show a message box to the user, and optionally log the
* message to the log file.
*
* @param parent parent shell this message box belongs to
* @param message Message to display. Can be multiline.
* @param messageType Type of message (warning, information)
* @param logger Logger instance to log to. Can be null.
* @param exception Exception related to this message. Can be null.
* @return true if OK, YES or RETRY was clicked, false for CANCEL or NO
*/
public static boolean showMessageBox(Shell parent, String message, MessageType messageType,
Logger logger, Throwable exception) {
if (logger != null)
logger.log(messageType.logPriority, message, exception);
if (exception != null)
message += "\n\n" + exception.getClass().getSimpleName() + " (Siehe Logdatei)";
MessageBox box = new MessageBox(parent, messageType.style);
box.setMessage(message);
box.setText(messageType.title);
int ret = box.open();
return ret == SWT.OK || ret == SWT.RETRY || ret == SWT.YES;
}
}