summaryrefslogblamecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageListWindow.java
blob: 8265f70196280dc8b2412cada646b7e2d381bda1 (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 javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.RowFilter;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.apache.log4j.Logger;
import org.openslx.bwlp.thrift.iface.ImageSummaryRead;
import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.MainWindow;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.gui.helper.PopupMenu;
import org.openslx.dozmod.gui.window.ImageDetailsWindow.ImageUpdatedCallback;
import org.openslx.dozmod.gui.window.layout.ImageListWindowLayout;
import org.openslx.dozmod.gui.wizard.ImageWizard;
import org.openslx.dozmod.gui.wizard.LectureWizard;
import org.openslx.dozmod.permissions.ImagePerms;
import org.openslx.dozmod.thrift.Session;
import org.openslx.dozmod.thrift.ThriftActions;
import org.openslx.dozmod.thrift.ThriftActions.DownloadCallback;
import org.openslx.dozmod.thrift.cache.ImageCache;
import org.openslx.thrifthelper.ThriftManager;
import org.openslx.util.QuickTimer;
import org.openslx.util.QuickTimer.Task;

/**
 * 
 * @author Jonathan Bauer
 * 
 */
@SuppressWarnings("serial")
public class ImageListWindow extends ImageListWindowLayout implements DownloadCallback {

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

	/**
	 * Self-reference
	 */
	public final ImageListWindow me = this;

	/**
	 * Popup menu items
	 */
	private final JMenuItem popupItemNewLecture = new JMenuItem("Neue Veranstaltung");
	private final JMenuItem popupItemDelete = new JMenuItem("Löschen");
	private final JMenuItem popupItemDownload = new JMenuItem("Download");

	/**
	 * Constructor
	 */
	public ImageListWindow() {
		super();

		/**
		 * Filter field and combobox listeners
		 */
		// filter the objects in the table depending on the search field
		searchTextField.getDocument().addDocumentListener(new DocumentListener() {
			@Override
			public void removeUpdate(DocumentEvent e) {
				changedUpdate(e);
			}

			@Override
			public void insertUpdate(DocumentEvent e) {
				changedUpdate(e);
			}

			@Override
			public void changedUpdate(DocumentEvent e) {
				// stuff
				applyFilterOnTable();
			}
		});

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

		/**
		 * Popup menu for the version table on the right side
		 */
		final PopupMenu pop = new PopupMenu(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (e.getSource().equals(popupItemNewLecture)) {
					startLectureWizard(imageTable.getSelectedItem());
				}
				if (e.getSource().equals(popupItemDownload)) {
					performImageDownload(imageTable.getSelectedItem());
				}
				if (e.getSource().equals(popupItemDelete)) {

				}
			}
		});

		// add them to the popup menu
		pop.addMenuItem(popupItemNewLecture);
		pop.addMenuItem(popupItemDownload);
		pop.addSeparator();
		pop.addMenuItem(popupItemDelete);

		/**
		 * Table listeners
		 */
		imageTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				ImageSummaryRead item = imageTable.getSelectedItem();
				updateAvailableOptions(item);
			}
		});

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

		imageTable.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
					final ImageSummaryRead image = getSelectedImage();
					if (image == null)
						return;
					ImageDetailsWindow.open((JFrame) SwingUtilities.getWindowAncestor(me),
							image.getImageBaseId(), new ImageUpdatedCallback() {
								public void updated() {
									refreshList(true, 100);
								}
							});
				}
				processClick(e);
			}

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

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

			private void processClick(MouseEvent e) {
				int r = imageTable.rowAtPoint(e.getPoint());
				if (r >= 0 && r < imageTable.getRowCount()) {
					// highlight the row and popup the menu
					imageTable.setRowSelectionInterval(r, r);
					if (e.isPopupTrigger()) {
						pop.show(e.getComponent(), e.getX(), e.getY());
					}
				} else {
					imageTable.clearSelection();
				}
			}
		});

		/**
		 * Bottom button panel listeners
		 */
		newButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				new ImageWizard(SwingUtilities.getWindowAncestor(me)).setVisible(true);
				refreshList(true, 100);
			}
		});
		newLectureButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				startLectureWizard(imageTable.getSelectedItem());
			}
		});
		downloadButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				performImageDownload(imageTable.getSelectedItem());
				// TODO refresh
			}
		});
		deleteButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent ae) {
				deleteLatestVersion(getSelectedImage());
				// TODO refresh
			}
		});
		backButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				MainWindow.showPage(MainMenuWindow.class);
			}
		});

		updateAvailableOptions(null);
	}

	/********************************************************************************
	 * 
	 * General GUI and table helpers
	 * 
	 ********************************************************************************/

	/**
	 * Refreshes the image list in the table
	 * 
	 * @param forceRefresh true to force a refresh, false to use the cached list
	 */
	private void refreshList(final boolean forceRefresh, int delay) {
		QuickTimer.scheduleOnce(new Task() {
			@Override
			public void fire() {
				final List<ImageSummaryRead> imageList = ImageCache.get(forceRefresh);
				Gui.asyncExec(new Runnable() {
					@Override
					public void run() {
						imageTable.setData(imageList, true);
					}
				});
			}
		}, delay);
	}

	/**
	 * Helper to return the selected image from the table or show an error to
	 * the user if none is selected
	 * 
	 * @return the image selected in the table, null if there is no selection
	 */
	private final ImageSummaryRead getSelectedImage() {
		final ImageSummaryRead image = imageTable.getSelectedItem();
		if (image == null) {
			Gui.showMessageBox(this, "Kein Image ausgewählt!", MessageType.ERROR, LOGGER, null);
			return null;
		} else {
			return image;
		}
	}

	/**
	 * Helper to check if the given image has a latest version
	 * 
	 * @param image the image to check for a latest version
	 * @return true if the image has a latest version, false otherwise
	 */
	private boolean hasLatestVersion(ImageSummaryRead image) {
		if (image == null)
			return false;
		if (image.getLatestVersionId() == null) {
			Gui.showMessageBox(me, "Das gewählte Image besitzt keine gültige Image-Version",
					MessageType.ERROR, null, null);
			return false;
		}
		return true;
	}

	/**
	 * Filters the image list according to the filter text entered by the user
	 */
	private void applyFilterOnTable() {
		try {
			// List for filters
			List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>(3);

			// string for text in filter text field
			String filterField = searchTextField.getText();
			filters.add(RowFilter.regexFilter("(?i)" + filterField, 0, 1, 2));
			// filter for user (only show own)
			switch (filterCbo.getSelectedIndex()) {
			case 0:
				// no additional filters
				break;
			case 1:
				// filter for owner
				String userFilter = Session.getUserId();
				filters.add(RowFilter.regexFilter("(?i)" + userFilter, 2));
				break;
			case 2:
				// filter for editable
				RowFilter<Object, Object> filter = new RowFilter<Object, Object>() {
					public boolean include(Entry entry) {
						return ImagePerms.canEdit(imageTable.getModelRow((Integer) entry.getIdentifier()));
					}
				};
				filters.add(filter);
				break;
			case 3:
				// show only templates
				RowFilter<Object, Object> templateFilter = new RowFilter<Object, Object>() {
					public boolean include(Entry entry) {
						return imageTable.getModelRow((Integer) entry.getIdentifier()).isTemplate;
					}
				};
				filters.add(templateFilter);
			default:
				break;
			}
			// for using multiple filters
			RowFilter<Object, Object> andFilters = RowFilter.andFilter(filters);
			imageTable.getRowSorter().setRowFilter(andFilters);

			searchTextField.setForeground(UIManager.getColor("TextField.foreground"));
		} catch (IllegalArgumentException ex) {
			// TODO set background color of search field to something redish
			searchTextField.setForeground(Color.RED);
		}
	}

	/**
	 * Updates the buttons/popup menu items according to the user's permissions
	 * 
	 * @param item the image to check the user's permissions for
	 */
	private void updateAvailableOptions(ImageSummaryRead item) {
		boolean download = ImagePerms.canDownload(item);
		boolean link = ImagePerms.canLink(item);
		boolean admin = ImagePerms.canAdmin(item);
		downloadButton.setEnabled(download);
		newLectureButton.setEnabled(link);
		deleteButton.setEnabled(admin);
		popupItemDownload.setEnabled(download);
		popupItemNewLecture.setEnabled(link);
		popupItemDelete.setEnabled(admin);
	}

	/********************************************************************************
	 * 
	 * Helpers triggering the actual actions
	 * 
	 ********************************************************************************/

	/**
	 * Starts a lecture wizard for the given image if it has a valid version
	 * 
	 * @param image image to link the new lecture to
	 */
	private void startLectureWizard(ImageSummaryRead image) {
		if (!hasLatestVersion(image))
			return;
		new LectureWizard(SwingUtilities.getWindowAncestor(this), image, image.getLatestVersionId()).setVisible(true);
	}

	/**
	 * Triggers a download of the given image's latest version
	 * 
	 * @param image the image to download
	 */
	private void performImageDownload(ImageSummaryRead image) {
		if (!hasLatestVersion(image))
			return;
		downloadButton.setEnabled(false);
		ThriftActions.initDownload(JOptionPane.getFrameForComponent(this), image.latestVersionId,
				image.imageName, image.virtId, image.fileSize, this);
	}

	/**
	 * Callback when download initialized
	 * 
	 * @param success true if downloading, false otherwise
	 */
	@Override
	public void downloadInitialized(boolean success) {
		if (!success) {
			refreshList(true, 1000);
		}
	}

	/**
	 * Deletes the latest version of the given image if it has one
	 * 
	 * @param image image to delete
	 */
	private void deleteLatestVersion(final ImageSummaryRead image) {
		if (!hasLatestVersion(image))
			return;
		// requires confirmation of the user
		if (!Gui.showMessageBox(me, "Wollen Sie die letzte Version dieses Images wirklich löschen?",
				MessageType.QUESTION_YESNO, LOGGER, null))
			return;
		// try to actually delete this version of the image
		QuickTimer.scheduleOnce(new Task() {
			boolean success = false;
			Exception error = null;

			@Override
			public void fire() {
				try {
					ThriftManager.getSatClient().deleteImageVersion(Session.getSatelliteToken(),
							image.getLatestVersionId());
					LOGGER.info("Deleted version '" + image.getLatestVersionId() + "' of image '"
							+ image.getImageBaseId() + "'.");
					success = true;
				} catch (Exception e) {
					error = e;
				}
				Gui.asyncExec(new Runnable() {
					@Override
					public void run() {
						deletedLatestVersion(success, error);
					}
				});
			}
		});
	}

	/**
	 * Async callback when image was deleted
	 * 
	 * @param success true if the latest image version was deleted, false
	 *            otherwise
	 */
	public void deletedLatestVersion(boolean success, Exception e) {
		if (e != null) {
			Gui.showMessageBox(me, "Fehler", MessageType.ERROR, LOGGER, e);
		}
		if (success) {
			refreshList(true, 1000);
		}
	}

	/********************************************************************************
	 * 
	 * CompositePage abstract methods implementation
	 * 
	 ********************************************************************************/
	@Override
	public boolean requestHide() {
		return true;
	}

	@Override
	public void requestShow() {
		refreshList(false, 1);
	}
}