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

                                      
                      

                                     

                                 

                                   
                           
                      
                     

                                              
 

                                  
                          
                             
                               
                             
                                      
                             
                                  
                             

                                               
 
                               
                                    

                                                         
                                                    
                                              
                                  
                                         
                                                                
                                                 
                                               
                                                        
                                                                                 
                                                                    
                                                   
                                                   
                                                          
                                         

                                                                     
                                                    
                                                 

                                        
                             
 



                                                             
                           





                                                                                       
                                  































                                                                                                                     

                                          

                                                                                   
 
                                                                                                       
                                         
                                             











                                                                                                                                            
                                                                                                













                                                                                   
 



                                                              
                                                                         

                                                                                          

                                                                      

                                    
 
                                                                                             
 
                                                                                
                                                                                      
                                 
                                               
                                                                 




                                                                                                                    
                                                                                                                    
                                                                             
                                                                                   

                                         
                                                     

                         
 
                                                                  

                                                                    
                                                           



                                                     
                                                                      
                                 
                                                                    
                                                                                                                     

                         
 
                                                                       

                                                                    
                                                                                  



                                 
                                                                         

                                                                    
                                                                               
                         


                                     
                                                                      
                                 
                                                                    
                                                                           

                         
 




                                                                          
                                                                                       


                                                                         
                                                                                                         
                                                                                                                     






                                                                                                    
                                                                              
 
                                                                                                                              


                                                                                                                   

                                                                                                         
                                                                                                               




                                                                                               
                                                                                                                        
                                                                                                                                          
                                                                                           

                                                 
 
                                 
                                                                            
                                                                                                                                                                                                     
                                 
                                                                            
                                                                                       
                                 



                                               
                                                 
                                                   



                                                 
                                                                 

                                                                
                                                                                                    



                                                                                                                                                    
                                                                                          

                                                
                         
 



                                                                
 



                                                                 
 
                                                                 

                                                           
                                                                                         


                                                                                 
                                                                             



                                                                          
                                 
 
                                                                                                   


                                                                                          
                                                                                                                  
                                         


                                                                                               



                                 
                                                             







                                                                       
                                                                                                      

                                                                        
                                                                                    


                                                             
                                              
                                                                  
                        
                                                                  
                 
                                             

                                          
                                                                                           
                                                                                         
                                                                                

                                                                     
                                                         

                         
                                                                                           
                                                                                         
                                                                               

                                                                     
                                                           

                         
         
 
           

                                                                                    
           

                                                                                 

                                                                     
                                                               
                                                                                      
                                                                                      
                                                                       
                                                                      



                                                                                         
         
 



                                                                       

                                    






                                                                                                                

         
           


                                                                                
                                                         

                                                                       








                                                                                                           


                                                                                                                                               







                                                                                                                                                                      


           

                                                                      
                                           
                                                       

                               





                                                                                                
                 

                                            

                                                                                 

                                                                      



                                                                                                        

                                                                    

         
                                                       


                                                    
                                                                                                 


                                                              

                                                                                                







                                         


                                                         




                                   
                                                   

                                                                  
                                             
                                   

         
                                                                   

                                        

                                                                                                                                 
                                                                                                        
                                                                               

                         




                                                                     
         
 
package org.openslx.dozmod.gui.window;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.apache.log4j.Logger;
import org.apache.thrift.TException;
import org.openslx.bwlp.thrift.iface.ImageDetailsRead;
import org.openslx.bwlp.thrift.iface.ImageVersionDetails;
import org.openslx.bwlp.thrift.iface.LectureSummary;
import org.openslx.bwlp.thrift.iface.UserInfo;
import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.MainWindow;
import org.openslx.dozmod.gui.control.table.ListTable.ListModel;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.gui.helper.PopupMenu;
import org.openslx.dozmod.gui.helper.TextChangeListener;
import org.openslx.dozmod.gui.window.LectureDetailsWindow.LectureUpdatedCallback;
import org.openslx.dozmod.gui.window.layout.LectureListWindowLayout;
import org.openslx.dozmod.gui.wizard.LectureWizard;
import org.openslx.dozmod.permissions.LecturePerms;
import org.openslx.dozmod.thrift.ImageLocalDetailsActions;
import org.openslx.dozmod.thrift.Session;
import org.openslx.dozmod.thrift.ThriftActions;
import org.openslx.dozmod.thrift.ThriftActions.DeleteLectureCallback;
import org.openslx.dozmod.thrift.cache.LectureCache;
import org.openslx.dozmod.thrift.cache.UserCache;
import org.openslx.util.QuickTimer;
import org.openslx.util.QuickTimer.Task;
import org.openslx.util.Util;

/**
 * Window for displaying a table with the available lectures.
 * Lectures can be created and deleted here.
 */
@SuppressWarnings("serial")
public class LectureListWindow extends LectureListWindowLayout {

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

	public final LectureListWindow me = this;

	// Filter types as an enum
	public enum FilterType {
		ALL("Alle anzeigen", null),
		OWN("Nur eigene/zugewiesene anzeigen", new RowFilter<ListModel<LectureSummary>, Integer>() {
			public boolean include(Entry<? extends ListModel<LectureSummary>, ? extends Integer> entry) {
				LectureSummary lecture = entry.getModel().getModelRow(entry.getIdentifier());
				return lecture.userPermissions.admin || lecture.ownerId.equals(Session.getUserId());
			}
		}),
		ACTIVE("Nur aktive anzeigen", new RowFilter<ListModel<LectureSummary>, Integer>() {
			public boolean include(Entry<? extends ListModel<LectureSummary>, ? extends Integer> entry) {
				LectureSummary lecture = entry.getModel().getModelRow(entry.getIdentifier());
				return lecture.isEnabled && lecture.endTime > Util.unixTime();
			}
		}),
		EDITABLE("Nur editierbare anzeigen", new RowFilter<ListModel<LectureSummary>, Integer>() {
			public boolean include(Entry<? extends ListModel<LectureSummary>, ? extends Integer> entry) {
				LectureSummary lecture = entry.getModel().getModelRow(entry.getIdentifier());
				return LecturePerms.canEdit(lecture);
			}
		}),
		EXPIRING("Bald auslaufende anzeigen", new RowFilter<ListModel<LectureSummary>, Integer>() {
			public boolean include(Entry<? extends ListModel<LectureSummary>, ? extends Integer> entry) {
				LectureSummary lecture = entry.getModel().getModelRow(entry.getIdentifier());
				return Math.abs(lecture.endTime - Util.unixTime()) < 86400 * 7;
			}
		}),
		EXAMS("Prüfungsveranstaltungen anzeigen", new RowFilter<ListModel<LectureSummary>, Integer>() {
			public boolean include(Entry<? extends ListModel<LectureSummary>, ? extends Integer> entry) {
				LectureSummary lecture = entry.getModel().getModelRow(entry.getIdentifier());
				return lecture.isExam;
			}
		});

		private final String name;
		
		private final RowFilter<ListModel<LectureSummary>, Integer> filter;

		private FilterType(String name, RowFilter<ListModel<LectureSummary>, Integer> filter) {
			this.name = name;
			this.filter = filter;
		}

		@Override
		public String toString() {
			return name;
		}
	}

	private Pattern searchFieldPattern = null;

	private final RowFilter<ListModel<LectureSummary>, Integer> filterSearchTerm = new RowFilter<ListModel<LectureSummary>, Integer>() {
		public boolean include(Entry<? extends ListModel<LectureSummary>, ? extends Integer> entry) {
			LectureSummary lecture = tblLectures.getModelRow(entry.getIdentifier());
			if (searchFieldPattern.matcher(lecture.lectureName).find())
				return true;
			UserInfo user = UserCache.find(lecture.ownerId);
			if (user == null)
				return false;
			if (searchFieldPattern.matcher(user.firstName).find())
				return true;
			if (searchFieldPattern.matcher(user.lastName).find())
				return true;
			if (searchFieldPattern.matcher(user.eMail).find())
				return true;
			return false;
		}
	};

	/**
	 * Popup menu items
	 */
	private JMenuItem popupItemNew = new JMenuItem("Neu");
	private JMenuItem popupItemEdit = new JMenuItem("Detailansicht");
	private JMenuItem popupItemLinked = new JMenuItem("VM-Details anzeigen");
	private JMenuItem popupItemDownload = new JMenuItem("Verlinkte VM herunterladen");
	private JMenuItem popupItemDelete = new JMenuItem("Löschen");

	public LectureListWindow() {
		super();

		tblLectures.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

		// filter the objects in the table depending on the search field
		txtSearch.getDocument().addDocumentListener(new TextChangeListener() {
			@Override
			public void changed() {
				String str = txtSearch.getText();
				if (str == null || str.isEmpty()) {
					searchFieldPattern = null;
				} else {
					try {
						searchFieldPattern = Pattern.compile(str, Pattern.CASE_INSENSITIVE);
						txtSearch.setForeground(UIManager.getColor("TextField.foreground"));
					} catch (PatternSyntaxException ex) {
						txtSearch.setForeground(Color.RED);
					}
				}
				applyFilterOnTable();
			}
		});

		cboFilter.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				txtSearch.setEnabled(true);
				applyFilterOnTable();
			}
		});

		btnNewLecture.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				new LectureWizard(SwingUtilities.getWindowAncestor(me), null, null).setVisible(true);
			}
		});

		btnEditLecture.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				openLectureDetails(tblLectures.getSelectedItem());
			}
		});

		// delete lecture
		btnDeleteLecture.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				deleteLectures(tblLectures.getSelectedItems());
			}
		});

		// return to mainMenu
		btnSwitchView.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				MainWindow.showPage(ImageListWindow.class);
			}
		});

		/**
		 * Popup menu for the version table on the right side
		 */
		final PopupMenu pop = new PopupMenu(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				LectureSummary lecture = tblLectures.getSelectedItem();
				if (lecture == null)
					return;
				if (e.getSource().equals(popupItemNew)) {
					if (Gui.showMessageBox(me, "Um eine Veranstaltung zu erstellen, "
							+ "müssen Sie eine VM auswählen. Zur VM-Auswahl wechseln?",
							MessageType.QUESTION_YESNO, LOGGER, null)) {
						MainWindow.showPage(ImageListWindow.class);
					}
				}
				if (e.getSource().equals(popupItemEdit)) {
					openLectureDetails(lecture);
				}
				if (e.getSource().equals(popupItemDownload)) {

					//TODO fix for students, who cannot see imageDetails somehow get filesize from server.
					ImageDetailsRead image = ThriftActions.getImageDetails(
							JOptionPane.getFrameForComponent(me), lecture.imageBaseId);
					if (image != null) {
						long versionSize = -1;
						for (ImageVersionDetails version : image.getVersions()) {
							if (version.versionId.equals(lecture.imageVersionId)) {
								versionSize = version.fileSize;
								break;
							}
						}
						if (versionSize != -1) {
							ThriftActions.initDownload(JOptionPane.getFrameForComponent(me),
									lecture.imageVersionId, image.imageName, image.virtId, image.osId,
									versionSize, null);
						}
					}

				}
				if (e.getSource().equals(popupItemLinked)) {
					ImageDetailsWindow.open(JOptionPane.getFrameForComponent(me), lecture.imageBaseId, null, new ImageLocalDetailsActions(JOptionPane.getFrameForComponent(me)));
				}
				if (e.getSource().equals(popupItemDelete)) {
					deleteLectures(tblLectures.getSelectedItems());
				}
			}
		});
		pop.addMenuItem(popupItemNew);
		pop.addMenuItem(popupItemEdit);
		pop.addMenuItem(popupItemLinked);
		pop.addMenuItem(popupItemDownload);
		pop.addSeparator();
		pop.addMenuItem(popupItemDelete);

		// finally the table listeners
		tblLectures.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
					if (!Session.canListImages()) {
						Gui.showMessageBox("Ihnen fehlen die benötigten Berechtigungen.", MessageType.ERROR, LOGGER, null);
						return;
					}
					openLectureDetails(tblLectures.getSelectedItem());
				}
				processClick(e);
			}

			@Override
			public void mousePressed(MouseEvent e) {
				processClick(e);
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				processClick(e);
			}

			private void processClick(MouseEvent e) {

				// rowIndex at mouse cursor
				int mouseRowIndex = tblLectures.rowAtPoint(e.getPoint());

				// is the click event on an already selected row?
				boolean alreadySelectedRow = false;
				for (int i : tblLectures.getSelectedRows()) {
					if (i == mouseRowIndex) {
						alreadySelectedRow = true;
						break;
					}
				}

				if (mouseRowIndex >= 0 && mouseRowIndex < tblLectures.getRowCount()
						&& SwingUtilities.isRightMouseButton(e)) {
					// select row if it wasn't in selection before
					if (!alreadySelectedRow) {
						tblLectures.setRowSelectionInterval(mouseRowIndex, mouseRowIndex);
					}
					if (e.isPopupTrigger()) {
						pop.show(e.getComponent(), e.getX(), e.getY());
					}
				}
			}
		});

		tblLectures.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				if (e.getKeyCode() == KeyEvent.VK_F5) {
					refreshList(true);
				}
			}
		});

		tblLectures.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				LectureSummary item = tblLectures.getSelectedItem();
				updateAvailableOptions(item);
			}
		});
		if (Session.canListImages()) {
			cboFilter.setSelectedItem(FilterType.OWN);
		} else {
			cboFilter.setSelectedItem(FilterType.ALL);
		}
		updateAvailableOptions(null);

		// Some keyboard shortcuts
		tblLectures.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
				KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "details");
		tblLectures.getActionMap().put("details", new AbstractAction() {
			@Override
			public void actionPerformed(ActionEvent ae) {
				btnEditLecture.doClick();
			}
		});
		tblLectures.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
				KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "delete");
		tblLectures.getActionMap().put("delete", new AbstractAction() {
			@Override
			public void actionPerformed(ActionEvent ae) {
				btnDeleteLecture.doClick();
			}
		});
	}

	/**
	 * Updates the buttons/popup menu items according to the user's permissions,
	 * status and number of selections
	 * 
	 * @param lecture the lecture to check the user's permissions for, can be
	 *            null
	 */
	private void updateAvailableOptions(LectureSummary lecture) {
		boolean admin = LecturePerms.canAdmin(lecture);
		boolean singleSelection = !(tblLectures.getSelectedRows().length > 1);
		btnEditLecture.setEnabled(Session.canListImages() && singleSelection);
		btnDeleteLecture.setEnabled(admin || !singleSelection);
		popupItemDelete.setEnabled(admin || !singleSelection);
		popupItemLinked.setEnabled(Session.canListImages() && singleSelection);
		popupItemDownload.setEnabled(Session.canListImages() && singleSelection);
		popupItemNew.setEnabled(Session.canListImages() && singleSelection);
		popupItemEdit.setEnabled(Session.canListImages() && singleSelection);
	}

	/**
	 * Opens the given lecture's details as a popup window
	 */
	private void openLectureDetails(final LectureSummary lecture) {
		if (lecture == null)
			return;
		LectureDetailsWindow.open((JFrame) SwingUtilities.getWindowAncestor(me), lecture.getLectureId(),
				new LectureUpdatedCallback() {
					@Override
					public void updated(boolean success) {
						refreshList(success);
					}
				});
	}

	/**
	 * Delete a list of lectures and display the lectures, which couldn't be
	 * deleted.
	 * 
	 * @param lectureList the lectures to be deleted.
	 */
	private void deleteLectures(List<LectureSummary> lectureList) {

		ThriftActions.deleteLecture(JOptionPane.getFrameForComponent(me), lectureList,
				new DeleteLectureCallback() {
					@Override
					public void deleted(Map<LectureSummary, TException> fLectures) {
						refreshList(true);
						if (fLectures.size() > 0) {
							StringBuilder builder = new StringBuilder();
							for (LectureSummary lecture : fLectures.keySet()) {
								builder.append("\n\n");
								builder.append(lecture.lectureName + " \n" );
								builder.append("Begründung: " + fLectures.get(lecture).getLocalizedMessage());
								LOGGER.error("Couldn't delete lecture " + lecture.lectureName + ", reason:", fLectures.get(lecture) );
								// TODO Should the exception be printed in the debugger or is this to much information?
							}
							Gui.showMessageBox("Folgende Veranstaltungen konnten nicht gelöscht werden: "
									+ builder.toString(), MessageType.INFO, LOGGER, null);
						}
					}
				});
	}

	/**
	 * Applies the filter entered in the search field to the table
	 */
	private void applyFilterOnTable() {
		if (cboFilter.getSelectedIndex() == -1)
			return;

		// Filter list we are about to fill
		List<RowFilter<ListModel<LectureSummary>, Integer>> filters = new ArrayList<>();

		// string for text in filter text field
		if (searchFieldPattern != null) {
			filters.add(filterSearchTerm);
		}

		// filters from the combobox
		FilterType filterType = (FilterType) cboFilter.getSelectedItem();
		tblLectures.setHighlightOwn(true);
		if (filterType != null && filterType.filter != null) {
			filters.add(filterType.filter);
		}

		// for using multiple filters
		RowFilter<ListModel<LectureSummary>, Integer> andFilters = RowFilter.andFilter(filters);
		tblLectures.getRowSorter().setRowFilter(andFilters);
		setLectureCountLabel(tblLectures.getRowCount());
	}

	private void refreshList(final boolean force) {
		QuickTimer.scheduleOnce(new Task() {
			@Override
			public void fire() {
				final List<LectureSummary> lectureList = LectureCache.get(force);
				Gui.asyncExec(new Runnable() {
					@Override
					public void run() {
						tblLectures.setData(lectureList, true);
						setLectureCountLabel(tblLectures.getRowCount());
					}
				});
			}
		});
	}

	@Override
	public boolean requestHide() {
		if (cboFilter.getSelectedIndex() == -1) {
			cboFilter.setSelectedIndex(0);
		}
		return true;
	}

	@Override
	public void requestShow() {
		// en-/disable buttons when student
		btnSwitchView.setEnabled(Session.canListImages());
		btnNewLecture.setEnabled(Session.canListImages());
		updateAvailableOptions(null);
		refreshList(false);
	}

	public void filterByImageBaseId(final String imageBaseId) {
		if (imageBaseId == null)
			return;
		RowFilter<ListModel<LectureSummary>, Integer> imageFilter = new RowFilter<ListModel<LectureSummary>, Integer>() {
			public boolean include(Entry<? extends ListModel<LectureSummary>, ? extends Integer> entry) {
				LectureSummary lecture = tblLectures.getModelRow(entry.getIdentifier());
				return imageBaseId.equals(lecture.imageBaseId);
			}
		};
		cboFilter.setSelectedIndex(-1);
		txtSearch.setText("");
		txtSearch.setEnabled(false);
		tblLectures.getRowSorter().setRowFilter(imageFilter);
		setLectureCountLabel(tblLectures.getRowCount());
	}
}