summaryrefslogblamecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
blob: e048a1359af24b7e6893717a0c1c1a39689d2a60 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
                               
 
                                     

                                              


                               

                                               


                                         



                                        
                                     
                              
                                 
                                              
                                                   
                                                 
                                                      
                                                     
                                                       


                                                             
                                         

                                                            
                                   




                                                                                
                                             
 


                                                                                                                  



                                                                                                                           
                                                   
           
                       
           







                                                                                 
 

                                               

                                                                                                                        

                                    
                 

                                                    
                                   
                                                                         
                                             
                                   


           
           
                                                                      
                                                      


                                                                                    
           





                                                                                                        
                                                                   

                                                                




                                                                

                                                                                                                        


                               










                                                                                                          

                                     
                                                
                                   


           
                                                                               


                                                                        
           

                                 
                                                                      







                                                                 
 

                                                                    
                                 
                                                                                                     



                                                                            


                                                                                

                                                                                                             

                                         


                         


                                                                    



                                                                   

                                                                                                                                   

                                         


                         
                                      
                                                                   

                                                              
                                                                             
                                                             

                                                           

                         
 







                                                                                               


                                                             
                                                               

                                               

                                                           
                                           
 
                                              


                                                            





                                                                    

                                                                  
                                                                 



                 




                                                                                            



                                                                                                               


           














                                                                                                                     
                                          
                                       









                                                                              

                                                                      
                                                     

                         
 











                                                                               
                                                                                           







                                                                                   
                                                                                                  

                         
                                              



                                                                                   










                                                                                                    
                                                                                              

         



                                   
 
package org.openslx.dozmod.gui;

import java.lang.reflect.Constructor;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

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.Shell;
import org.openslx.dozmod.App;
import org.openslx.dozmod.Config;
import org.openslx.dozmod.gui.Gui.GuiCallable;
import org.openslx.dozmod.gui.helper.CompositePage;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.gui.window.DisclaimerWindow;
import org.openslx.dozmod.gui.window.ImageListWindow;
import org.openslx.dozmod.gui.window.LectureListWindow;
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;
import org.openslx.util.QuickTimer;

public abstract class MainWindow {

	private final static Logger LOGGER = Logger.getLogger(MainWindow.class);

	private static final Shell mainShell;

	private static CompositePage currentPage;

	private static final Map<Class<? extends CompositePage>, CompositePage> pages = new ConcurrentHashMap<>();

	private static final String THRIFT_CONNECTION_ERROR = "Lost connection to the masterserver. Do you want to retry?";

	/**
	 * Set the visible page of the main window.
	 * 
	 * @param clazz
	 */
	public static void showPage(Class<? extends CompositePage> clazz) {
		if (currentPage != null && currentPage.getLayoutData() != null) {
			if (!currentPage.hide()) {
				return; // Canceled by currently shown page
			}
			((GridData) currentPage.getLayoutData()).exclude = true;
			currentPage.setVisible(false);
		}

		currentPage = pages.get(clazz);
		if (currentPage == null) {
			showMessageBox("Tried to show unknown page " + clazz.getSimpleName(), MessageType.ERROR, LOGGER,
					null);
			Gui.exit(1);
			return;
		}

		// sets the starting preferred size.
		currentPage.show();
		((GridData) currentPage.getLayoutData()).exclude = false;
		currentPage.setVisible(true);
		mainShell.layout();
	}

	/**
	 * 
	 * @param clazz Class to open as a popup over the main window.
	 *            MUST be a subclass of Composite.
	 * @param modal modal mode - other windows will be blocked until this popup
	 *            is closed
	 * @param noclose don't allow closing the popup via the (X) in the title bar
	 */
	public static void openPopup(Class<? extends Composite> clazz, boolean modal, boolean noclose) {
		int style = SWT.TITLE | SWT.BORDER | SWT.RESIZE;
		if (modal)
			style |= SWT.APPLICATION_MODAL;
		if (!noclose)
			style |= SWT.CLOSE;
		Shell dialogShell = Gui.newShell(mainShell, style);
		// populate dialogShell
		dialogShell.setLayout(new GridLayout(1, false));
		Constructor<?> con = null;
		try {
			con = clazz.getConstructor(Shell.class);
			con.newInstance(dialogShell);
		} catch (Exception e1) {
			Gui.showMessageBox(mainShell, "Cannot show popup " + clazz.getName(), MessageType.DEBUG, LOGGER,
					e1);
			return;
		}

		if (noclose) {
			// Add listener that will cancel a close request via the X.
			// (Some platforms don't allow disabling it via style, so this is used to be safe)
			dialogShell.addListener(SWT.Close, new Listener() {
				@Override
				public void handleEvent(Event event) {
					event.doit = false;
				}
			});
		}

		dialogShell.layout();
		dialogShell.pack();
		Gui.limitShellSize(dialogShell);
		dialogShell.open();
	}

	/**
	 * Initializes 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 = Gui.newShell(SWT.SHELL_TRIM | SWT.CENTER);

		// Catch the close button (X)
		mainShell.addListener(SWT.Close, new Listener() {
			public void handleEvent(Event event) {
				MainWindow.askApplicationQuit();
				event.doit = false;
			}
		});

		// Set up thrift error message displaying
		ThriftManager.setErrorCallback(new ErrorCallback() {
			@Override
			public boolean thriftError(int failCount, String method, final Throwable t) {
				// if it's the first fail, retry immediately
				if (failCount == 1)
					return true;
				// Otherwise, ask user if we should retry
				return Gui.syncExec(new GuiCallable<Boolean>() {
					@Override
					public Boolean run() {
						return Gui.showMessageBox(mainShell, THRIFT_CONNECTION_ERROR,
								MessageType.ERROR_RETRY, LOGGER, t);
					}
				});
			}
		});

		// Same for config errors
		Config.setErrorCallback(new Config.ErrorCallback() {
			@Override
			public void writeError(final Throwable t) {
				Gui.asyncExec(new Runnable() {
					@Override
					public void run() {
						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
					askApplicationQuit();
					event.doit = false;
				}
			}
		});

		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);

		// register all pages of the main window
		registerPage(new MainMenuWindow(mainShell));
		registerPage(new ImageListWindow(mainShell));
		registerPage(new LectureListWindow(mainShell));
		// Show main menu by default
		showPage(MainMenuWindow.class);

		// center the window on the primary monitor
		Gui.centerShell(mainShell);

		Gui.limitShellSize(mainShell);
		mainShell.open();

		// here we can check for Session information
		if (Session.getSatelliteToken() != null) {
			// Wait for proxy server init
			App.waitForInit();
			// TODO: Try to resume session
		}
		// Session resume probably failed, show login window
		if (Session.getSatelliteToken() == null) {
			// User did not login, show the login mask
			openPopup(LoginWindow.class, true, true);
		}
	}

	/**
	 * Request application quit. Will show a message box asking the user for
	 * confirmation.
	 */
	protected static void askApplicationQuit() {
		// TODO: Only ask if an upload or download is running,, wizard is open etc..
		if (showMessageBox("Are you sure you want to quit?", MessageType.QUESTION_YESNO, null, null)) {
			QuickTimer.cancel();
			Gui.exit(0);
		}
	}

	/**
	 * Register a page that can be displayed in the main window.
	 * 
	 * @param window
	 */
	private static synchronized void registerPage(CompositePage window) {
		Class<? extends CompositePage> clazz = window.getClass();
		if (pages.containsKey(clazz))
			throw new IllegalArgumentException("Page " + clazz.getSimpleName() + " already registered!");
		pages.put(clazz, window);
		GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true);
		gd.exclude = true;
		window.setLayoutData(gd);
		window.setVisible(false);
	}

	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) {
				askApplicationQuit();
			}
		});

		// 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, 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, 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 Gui.showMessageBox(mainShell, message, messageType, logger, exception);
	}

	public static void open() {
		mainShell.open();
	}

}