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

                                      

                                     

                                 

                                   
                      
 

                                  
                          
                             
                               
                             
                                      
                                  

                                               
 
                               
                                                      
                                  
                                         
                                                       
                                                 
                                               
                                                                             
                                                                  
                                                         
                                                   
                                                 
                                                          
                                         
                                               
                                                              
                                                                
                                                    

                                        
 
   

                                                                             
   
                           
                                                                                                        
 

                                                                                     


                         
                                               
 
           
                                                      
           
                                                                                
 
           

                           
                                                                                          
                                                                               

                                                                              
 


                      

                                  
 


                                                                     

                                                                          
                                                                                
                                                                                         
                                 


                                                                                       
                                                                              
                                                                                           

                                                                            
                                                                                    



                                 

                                                                                            
                                             
                                                     
                                               


                                                   
 


                                  






                                                                                                     
 



                                                                       
                                                                                



                                 
                                                                
                                 
                                                                
                                                                                                    
                                                                                       
                                 

                                                
 










                                                                 

















                                                                                                                 


                                                                                               
                                 

                         



                                                
                                                                 

                                                                    
                                                                                                               
                                                                          

                         
                                                                      


                                                                                 

                         
                                                                       




                                                                               
                                                                    

                                                                    
                                                                                   

                         
                                                                  
                                 

                                                                            

                         





                                                                                                
                                                                      

                                                                    
                                                                             

                         
 





                                                                                          
                                                         






                                                                                          
                                                    


                         
                                             
         



                                                                                         
           

                                                                                          






                                                                          
                                  

                                                         
                                                                                                       

                                                                       
                 
                            
         
 

                                                                                   
                                         


                                                                    
                                                                    
                                                                                    










                                                                                            
                                                        
         
 
                                            
                                                         

         


                                                                                         
           












                                                                                                                              




                                                          


                                                               

                                                                                                              
                                                               
                                                                                          
                                         
                                                                                                       
         
 







                                                                   
                                              
                                                                                                         
                                                                                                 
         
 
           
                                             




                                                              
                               


                                                      

                                                                                   

                                 
                 
         
 




                                                                      
                                                
                                                                    
                                                                                                              
         
 
           






                                                                            
                                                  



                                                            
                                                         









                                                                                                                   
                                                                        







                                                       



                                             
           
                                                              
           

                                                
                                                              

         


                                                                                         
           







                                                                                          

                                                                                                    
                                                         
                                                                                     
         
 
 
package org.openslx.dozmod.gui.window;

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.List;

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.SwingUtilities;
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.control.table.ImageTable;
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.ImageCreationWizard;
import org.openslx.dozmod.gui.wizard.LectureWizard;
import org.openslx.dozmod.permissions.ImagePerms;
import org.openslx.dozmod.thrift.ImageLocalDetailsActions;
import org.openslx.dozmod.thrift.Session;
import org.openslx.dozmod.thrift.ThriftActions;
import org.openslx.dozmod.thrift.ThriftActions.DeleteCallback;
import org.openslx.dozmod.thrift.ThriftActions.DownloadCallback;
import org.openslx.dozmod.thrift.cache.LectureCache;
import org.openslx.util.QuickTimer;
import org.openslx.util.QuickTimer.Task;

/**
 * Window with the list of available images.
 * Has filters for the images and buttons to create, edit and delete buttons.
 */
@SuppressWarnings("serial")
public class ImageListWindow extends ImageListWindowLayout implements DownloadCallback, DeleteCallback {

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

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

	/**
	 * The image table held by the ImageListViewer
	 */
	public final ImageTable imageTable = ctlImageListViewer.getImageTable();

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

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

		/**
		 * 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(popupItemEdit)) {
					openImageDetails(imageTable.getSelectedItem());
				}
				if (e.getSource().equals(popupItemDownload)) {
					performImageDownload(imageTable.getSelectedItem());
				}
				if (e.getSource().equals(popupItemDelete)) {
					deleteImages(imageTable.getSelectedItems());
				}
			}
		});

		imageTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

		// add them to the popup menu
		pop.addMenuItem(popupItemNewLecture);
		pop.addMenuItem(popupItemEdit);
		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) {
					ctlImageListViewer.refreshList(true, 1);
				}
			}
		});

		imageTable.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
					openImageDetails(imageTable.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 = imageTable.rowAtPoint(e.getPoint());

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

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

		/**
		 * Bottom button panel listeners
		 */
		btnNewVm.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				new ImageCreationWizard(SwingUtilities.getWindowAncestor(me)).setVisible(true);
				ctlImageListViewer.refreshList(true, 100);
			}
		});
		btnNewLecture.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				startLectureWizard(imageTable.getSelectedItem());
			}
		});
		btnEditDetails.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				openImageDetails(imageTable.getSelectedItem());
			}
		});
		btnDownload.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				performImageDownload(imageTable.getSelectedItem());
			}
		});
		btnDelete.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				deleteImages(imageTable.getSelectedItems());
			}
		});
		btnShowPublishedImages.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				ImagePublishedWindow.open(JOptionPane.getFrameForComponent(me));
			}
		});
		btnSwitchView.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				MainWindow.showPage(LectureListWindow.class);
			}
		});

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

		updateAvailableOptions(null);
	}

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

	/**
	 * 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, "Die gewählte VM besitzt keine gültige Image-Version",
					MessageType.ERROR, null, null);
			return false;
		}
		return true;
	}

	/**
	 * Updates the buttons/popup menu items according to the user's permissions
	 * and the selection in the table
	 * 
	 * @param item the image to check the user's permissions for
	 */
	private void updateAvailableOptions(ImageSummaryRead item) {
		boolean isValid = item != null && item.getLatestVersionId() != null;
		int selCount = imageTable.getSelectedRows().length;
		boolean download = isValid && selCount == 1 && ImagePerms.canDownload(item);
		boolean link = isValid && selCount == 1 && ImagePerms.canLink(item);
		boolean delete = ImagePerms.canAdmin(item) || selCount > 1;
		btnDownload.setEnabled(download);
		btnNewLecture.setEnabled(link);
		btnDelete.setEnabled(delete);
		popupItemDownload.setEnabled(download);
		popupItemNewLecture.setEnabled(link);
		popupItemDelete.setEnabled(delete);
		btnEditDetails.setEnabled(selCount == 1);
		btnShowPublishedImages.setEnabled(true);
	}

	public void refresh(boolean force) {
		ctlImageListViewer.refreshList(force, 1);
	}

	/********************************************************************************
	 * 
	 * 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);
	}

	/**
	 * Opens the given image details as a popup window
	 * 
	 * @param image the image to show the details of
	 */
	private void openImageDetails(ImageSummaryRead image) {
		if (image == null)
			return;
		ImageDetailsWindow.open((JFrame) SwingUtilities.getWindowAncestor(me), image.getImageBaseId(),
				new ImageUpdatedCallback() {
					public void updated() {
						ctlImageListViewer.refreshList(true, 100);
					}
				}, new ImageLocalDetailsActions(JOptionPane.getFrameForComponent(me)));
	}

	/**
	 * 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;
		btnDownload.setEnabled(false);
		ThriftActions.initDownload(JOptionPane.getFrameForComponent(this), image.latestVersionId,
				image.imageName, image.virtId, image.osId, image.fileSize, this);
	}

	/**
	 * Callback when download initialized
	 * 
	 * @param success true if downloading, false otherwise
	 */
	@Override
	public void downloadInitialized(boolean success) {
		if (!success) {
			Gui.asyncExec(new Runnable() {
				@Override
				public void run() {
					btnDownload.setEnabled(true);
					ctlImageListViewer.refreshList(true, 1000);
				}
			});
		}
	}

	/**
	 * Deletes the latest version of the given image if it has one
	 * 
	 * @param image image to delete
	 */
	//TODO seems like it's no longer needed.
	private void deleteBaseImage(final ImageSummaryRead image) {
		ThriftActions.deleteImageBase(JOptionPane.getFrameForComponent(this), image.getImageBaseId());
	}

	/**
	 * Delete a list of images and display the images, which couldn't be
	 * deleted.
	 * 
	 * @param imageList the images to be deleted.
	 */
	private void deleteImages(List<ImageSummaryRead> imageList) {
		boolean failedToDeleteAll = false;
		boolean deletedAtLeastOne = false;
		StringBuilder builder = new StringBuilder();
		for (ImageSummaryRead image : imageList) {
			if (ImagePerms.canAdmin(image)) {
				deleteBaseImage(image);
				deletedAtLeastOne = true;
			} else {
				failedToDeleteAll = true;
				builder.append('\n');
				builder.append(image.imageName);
			}
		}
		if (failedToDeleteAll) {
			Gui.showMessageBox("Folgende images konnten nicht gelöscht werden: " + builder.toString(),
					MessageType.INFO, LOGGER, null);
		}
		ctlImageListViewer.refreshList(deletedAtLeastOne, 1000);
		QuickTimer.scheduleOnce(new Task() {

			@Override
			public void fire() {
				LectureCache.get(true);
			}
		});

	}

	/**
	 * Callback when download initialised
	 * 
	 * @param success true if downloading, false otherwise
	 */
	@Override
	public void isDeleted(boolean success) {
		ctlImageListViewer.refreshList(success, 1000);
	}

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

	@Override
	public void requestShow() {
		// we need to enable the "Show published images" button here, since we need to check
		// Session.getSatApiVersion() which is not set when this class is instantiated
		ctlImageListViewer.refreshList(false, 1);
		btnShowPublishedImages.setVisible(Session.isImagePublishSupported());
	}

}