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



                                     

                                     
                               

                                    

                           

                                              
 




                             
                          
                              
 
                               
                                    
                                                
                              
                                 
                                              
                                              

                                                     
                                                   
                                                 
                                                 
                                                
                                                      
                                                     
                                                       


                                                             
                                                  
                                         






                                                                                
                                               

                                                  
 

                                                 

                                                          
                                                                                                                  
 

                                                                                


                                                                                                                           
                                                   
           
                       
           
                                                                           

                                                         

                                                                           

                                                      
 

                                               

                                                                                                             

                                    
                 

                                                    
                                          
                                             
                                      

         
                                                      
                                                            

         
                
                                                                     




                                                                 











                                                                        

         
           
                                                                               


                                                                        
           

                                   
                                 
                                                                                

                                             
                                                                  

                                                                  
                                                                

                         
 

                                                                    
                                 
                                                                                                     



                                                                            


                                                                                

                                                                                                              

                                         


                         


                                                                    



                                                                   

                                                                                                                              

                                         


                         
                                      


                                                                                                                      



                                                                                                   


                                                                          
                                                        





                                                                                                                                
                                 
                                                          

                         
 

                             
                                                                                               

                                                                                           
 
                                                        
                                                   
                                                    
                                                      
 




                                                                   
                                                                                      
                 
                                                                                           

                                                    
                                                                                      
 
                                                           
                                                                                    
                                                       
                                            
 
                                                            

                                                                

                                                     
                             
                                                                                                                         
                                                              

                                                                                                                



                                                                              
                 
 
                                                                    

                                                                  
                                                     
                 

                                                                                                                  
 

                                               


           



                                                                                






                                                           
                            






                                                                                             

                         


                                                                                                   

                                    
                                           


           








                                                                                                                     
                                          


                                         
                                                               












                                                                

         
                                          
                                       
                                                  
                                                
 
                                                          

                                             

                                                               
                                                           
                                              
 







                                                                      
                                                                 
                                 
                                                                    
                                                     

                         
 
                                        
                                                            
                                              
 

                                                                               

                                                            
 
                                                                       
                                 
                                                                    
                                                                  


                         
                                                                              
                                 
                                                                    
                                                                         

                         
         
 
 
package org.openslx.dozmod.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JSeparator;

import org.apache.log4j.Logger;
import org.apache.thrift.TException;
import org.openslx.bwlp.thrift.iface.WhoamiInfo;
import org.openslx.dozmod.App;
import org.openslx.dozmod.Config;
import org.openslx.dozmod.Config.SavedSession;
import org.openslx.dozmod.gui.Gui.GuiCallable;
import org.openslx.dozmod.gui.activity.ActivityPanel;
import org.openslx.dozmod.gui.activity.UploadPanel;
import org.openslx.dozmod.gui.helper.CompositePage;
import org.openslx.dozmod.gui.helper.DebugWindow;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.gui.helper.UiFeedback;
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.state.UploadWizardState;
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 JFrame mainWindow;
	private static final JPanel mainContainer;
	private static final JPanel activityPanel;

	private static CompositePage currentPage;

	private static boolean isQuitQuestionOpen = false;

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

	private static final List<ActivityPanel> activities = new ArrayList<>();

	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) {
			if (!currentPage.requestHide()) {
				return; // Canceled by currently shown page
			}
			currentPage.setVisible(false);
		}

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

		// sets the starting preferred size.
		currentPage.requestShow();
		currentPage.setVisible(true);
		mainWindow.validate();
	}

	public static void centerShell(Window shell) {
		Gui.centerShellOverShell(mainWindow, shell);
	}

	static {
		mainWindow = Gui.syncExec(new GuiCallable<JFrame>() {
			@Override
			public JFrame run() {
				return new JFrame("bwLehrstuhl");
			}
		});
		mainContainer = Gui.syncExec(new GuiCallable<JPanel>() {
			@Override
			public JPanel run() {
				return new JPanel();
			}
		});
		activityPanel = Gui.syncExec(new GuiCallable<JPanel>() {
			@Override
			public JPanel run() {
				return new JPanel();
			}
		});
	}

	/**
	 * 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.
	 */

	public static void open() {
		// init SWT stuff
		mainWindow.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

		// Catch the close button (X)
		mainWindow.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				MainWindow.askApplicationQuit();
			}
		});

		// 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(mainWindow, 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() {
						Gui.showMessageBox(mainWindow, "Konnte Programmeinstellungen nicht speichern",
								MessageType.WARNING, LOGGER, t);
					}
				});
			}
		});

		// Global key listener
		KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
			@Override
			public boolean dispatchKeyEvent(KeyEvent event) {
				int type = event.getID();
				int code = event.getKeyChar();
				if (code == 17) { // Ctrl-Q = Quit
					if (type == KeyEvent.KEY_RELEASED && !isQuitQuestionOpen) {
						isQuitQuestionOpen = true;
						askApplicationQuit();
					}
					event.consume();
				} else if (code == 27 && type == KeyEvent.KEY_PRESSED) {
					Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
					if (window instanceof UiFeedback) {
						((UiFeedback) window).escapePressed();
						event.consume();
					}
				}
				return event.isConsumed();
			}
		});

		createMenu();

		// Set layout for the mainshell, items added to the shell should get a gridData
		mainContainer.setLayout(new BoxLayout(mainContainer, BoxLayout.PAGE_AXIS));
		mainWindow.setMinimumSize(new Dimension(850, 650));

		// register all pages of the main window
		registerPage(new MainMenuWindow());
		registerPage(new ImageListWindow());
		registerPage(new LectureListWindow());

		// Debug?
		if (System.getProperty("log") != null) {
			DebugWindow win = new DebugWindow();
			win.setMinimumSize(new Dimension(0, 250));
			win.setPreferredSize(win.getMinimumSize());
			mainWindow.getContentPane().add(win, BorderLayout.PAGE_START);
		}
		activityPanel.setLayout(new BoxLayout(activityPanel, BoxLayout.PAGE_AXIS));
		activityPanel.setVisible(false);
		activityPanel.add(new JSeparator());
		mainWindow.getContentPane().add(activityPanel, BorderLayout.PAGE_END);

		// center the window on the primary monitor
		mainWindow.getContentPane().add(mainContainer, BorderLayout.CENTER);
		mainWindow.setLocationRelativeTo(null);
		mainWindow.setVisible(true);

		// here we can check for Session information
		SavedSession session = Config.getSavedSession();
		if (session != null) {
			// Wait for proxy server init
			App.waitForInit();
			try {
				WhoamiInfo whoami = ThriftManager.getNewSatClient(session.address).whoami(session.token);
				// TODO: Satellite whoami call
				Session.initialize(whoami, session.address, session.token, session.masterToken);
				ThriftManager.setSatelliteAddress(Session.getSatelliteAddress());
				LOGGER.info("Saved session used for resume.");
			} catch (TException e1) {
				LOGGER.info("Session resume failed.", e1);
			}
		}

		// Session resume probably failed, show login window
		if (Session.getSatelliteToken() == null) {
			// User did not login, show the login mask
			LoginWindow.open(mainWindow);
		}
		mainWindow.setTitle("bwLehrstuhl - " + Session.getFirstName() + " " + Session.getLastName() + " ["
				+ Session.getSatelliteAddress() + "]");

		// Show main menu by default
		showPage(MainMenuWindow.class);
	}

	/**
	 * Request application quit. Will show a message box asking the user for
	 * confirmation.
	 */
	protected static void askApplicationQuit() {
		boolean open = false;
		for (ActivityPanel activity : activities) {
			if (activity.wantConfirmQuit()) {
				open = true;
				break;
			}
		}
		if (!open) {
			Window[] windows = Window.getWindows();
			for (Window window : windows) {
				if (window.isVisible() && window instanceof UiFeedback
						&& ((UiFeedback) window).wantConfirmQuit()) {
					open = true;
					break;
				}
			}
		}
		if (!open
				|| Gui.showMessageBox(mainWindow, "Are you sure you want to quit?",
						MessageType.QUESTION_YESNO, null, null)) {
			Gui.exit(0);
		}
		isQuitQuestionOpen = false;
	}

	/**
	 * 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);
		mainContainer.add(window);
		window.setVisible(false);
	}

	public static void addUpload(UploadWizardState state) {
		UploadPanel panel = new UploadPanel(state);
		activities.add(panel);
		activityPanel.add(panel);
		activityPanel.setVisible(true);
		mainWindow.validate();
	}

	public static void removeActivity(ActivityPanel panel) {
		activities.remove(panel);
		activityPanel.remove(panel);
		if (activities.isEmpty())
			activityPanel.setVisible(false);
		mainWindow.validate();
	}

	private static void createMenu() {
		// the File menu button
		JMenuBar menuBar = new JMenuBar();
		mainWindow.setJMenuBar(menuBar);

		JMenu cascadeFileMenu = new JMenu("File");
		menuBar.add(cascadeFileMenu);

		JMenuItem logoutItem = new JMenuItem("Logout");
		cascadeFileMenu.add(logoutItem);
		JMenuItem exitItem = new JMenuItem("Exit");
		cascadeFileMenu.add(exitItem);

		logoutItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				Config.saveCurrentSession("", "", "");
				askApplicationQuit();
			}
		});

		exitItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				askApplicationQuit();
			}
		});

		// the About menu button
		JMenu cascadeAboutMenu = new JMenu("About");
		menuBar.add(cascadeAboutMenu);

		JMenuItem disclaimerItem = new JMenuItem("Disclaimer");
		JMenuItem virtualizerNoticeItem = new JMenuItem("Virtualizer");
		cascadeAboutMenu.add(disclaimerItem);
		cascadeAboutMenu.add(virtualizerNoticeItem);

		disclaimerItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				DisclaimerWindow.open(mainWindow);
			}
		});

		virtualizerNoticeItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				VirtualizerNoticeWindow.open(mainWindow);
			}
		});
	}

}