/******************************************************************************** * * * (c) Copyright 2010 Verizon Communications USA and The Open University UK * * * * This software is freely distributed in accordance with * * the GNU Lesser General Public (LGPL) license, version 3 or later * * as published by the Free Software Foundation. * * For details see LGPL: http://www.fsf.org/licensing/licenses/lgpl.html * * and GPL: http://www.fsf.org/licensing/licenses/gpl-3.0.html * * * * This software is provided by the copyright holders and contributors "as is" * * and any express or implied warranties, including, but not limited to, the * * implied warranties of merchantability and fitness for a particular purpose * * are disclaimed. In no event shall the copyright owner or contributors be * * liable for any direct, indirect, incidental, special, exemplary, or * * consequential damages (including, but not limited to, procurement of * * substitute goods or services; loss of use, data, or profits; or business * * interruption) however caused and on any theory of liability, whether in * * contract, strict liability, or tort (including negligence or otherwise) * * arising in any way out of the use of this software, even if advised of the * * possibility of such damage. * * * ********************************************************************************/ package com.compendium.ui.dialogs; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.sql.SQLException; import java.util.Enumeration; import java.util.Vector; import javax.swing.DefaultListModel; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.border.EmptyBorder; import com.compendium.LanguageProperties; import com.compendium.ProjectCompendium; import com.compendium.core.CoreUtilities; import com.compendium.core.datamodel.IModel; import com.compendium.core.datamodel.NodeSummary; import com.compendium.core.datamodel.PCSession; import com.compendium.core.datamodel.View; import com.compendium.ui.IUIConstants; import com.compendium.ui.LabelListCellRenderer; import com.compendium.ui.UIAudio; import com.compendium.ui.UIButton; import com.compendium.ui.UIButtonPanel; import com.compendium.ui.UIImages; import com.compendium.ui.UINavList; import com.compendium.ui.UINode; import com.compendium.ui.UIUtilities; import com.compendium.ui.UIViewFrame; import com.compendium.ui.plaf.NodeUI; /** * class UITrashViewDialog is the dialog displaying the trashbin contents. * * @author Mohammed Sajid Ali / Michelle Bachler */ public class UITrashViewDialog extends UIDialog implements ActionListener, IUIConstants { /** The parent frame for this dialog.*/ private JFrame oParent = null; /** The main content pane for this dialog.*/ private Container oContentPane = null; /** The scrollpane for the list of deleted nodes.*/ private JScrollPane sp = null; /** The list for the deleted nodes.*/ private UINavList lstNodes = null; /** The button to purge selected nodes.*/ private UIButton pbPurge = null; /** The button to sort the node list by node label.*/ private UIButton pbLabel = null; /** The button to sort the node list by node creation date.*/ private UIButton pbCreationDate = null; /** The button to sort the node list by node modification date.*/ private UIButton pbModificationDate = null; /** The button to close the dialog.*/ private UIButton pbClose = null; /** The button to select all nodes in the dialog.*/ private UIButton pbSelectAll = null; /** The button to restore the selected nodes to the home view.*/ private UIButton pbRestore = null; /** The button to restore the select nodes to one of its former views.*/ private UIButton pbRestoreView = null; /** Activates the help opeing to the appropriate section.*/ private UIButton pbHelp = null; /** The sorted list of deleted nodes.*/ private Vector vtNodes = new Vector(); /** The list of deleted nodes.*/ private Vector vtResults = new Vector(); /** The UINode trashbin node.*/ private UINode oUINode = null; /** The dialog holding the progress bar.*/ private UIProgressDialog oProgressDialog = null; /** The progress bar.*/ private JProgressBar oProgressBar = null; /** The thread to run the progress.*/ private ProgressThread oThread = null; /** The counter for the progress bar.*/ private int Count = 0; /** The start of the label holding the view count.*/ private String sObjectCount = LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.deletedObjectCount")+" : "; //$NON-NLS-1$ /** Holds the count of the number of deleted nodes.*/ private JLabel lblCount = null; /** * Initializes and draw the dialog. * @param parent, the parent node for this dialog. * @param nodeui com.compendium.ui.plaf.nodeui, the trashbin node. */ public UITrashViewDialog(JFrame parent, NodeUI nodeui) { super(parent, true); oParent = parent; NodeUI oNodeUI = nodeui; oUINode = oNodeUI.getUINode(); setTitle(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.trashbinTitleA")+" ("+LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.trashbinTitleB") + ProjectCompendium.APP.getModel().getModelName() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ oContentPane = getContentPane(); oContentPane.setLayout(new BorderLayout()); GridBagLayout gb = new GridBagLayout(); JPanel listpanel = new JPanel(gb); GridBagConstraints gc = new GridBagConstraints(); gc = new GridBagConstraints(); gc.insets = new Insets(5,5,5,5); gc.fill=GridBagConstraints.NONE; gc.anchor = GridBagConstraints.WEST; gc.gridwidth = GridBagConstraints.REMAINDER; gc.weightx=1; gc.weighty=1; listpanel.setBorder(new EmptyBorder(10,15,15,10)); // Add label lblCount = new JLabel(""); //$NON-NLS-1$ listpanel.add(lblCount); gb.setConstraints(lblCount, gc); gc.gridwidth = 1; // Add label sort button pbLabel = new UIButton(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.labelColumnButton")); //$NON-NLS-1$ pbLabel.setMnemonic(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.labelColumnButtonMnemonic").charAt(0)); //$NON-NLS-1$ pbLabel.addActionListener(this); pbLabel.setFont(new Font("Dialog", Font.PLAIN, 9)); //$NON-NLS-1$ gb.setConstraints(pbLabel, gc); listpanel.add(pbLabel); // Add creation date sort button pbCreationDate = new UIButton(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.createDateColumnButton")); //$NON-NLS-1$ pbCreationDate.setMnemonic(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.createDateColumnButtonMnemonic").charAt(0)); //$NON-NLS-1$ pbCreationDate.addActionListener(this); pbCreationDate.setFont(new Font("Dialog", Font.PLAIN, 9)); //$NON-NLS-1$ gb.setConstraints(pbCreationDate, gc); listpanel.add(pbCreationDate); // Add modification date sort button pbModificationDate = new UIButton(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.modDateColumnButton")); //$NON-NLS-1$ pbModificationDate.setMnemonic(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.modDateColumnButtonMnemonic").charAt(0)); //$NON-NLS-1$ pbModificationDate.addActionListener(this); pbModificationDate.setFont(new Font("Dialog", Font.PLAIN, 9)); //$NON-NLS-1$ gc.gridwidth = GridBagConstraints.REMAINDER; gb.setConstraints(pbModificationDate, gc); listpanel.add(pbModificationDate); // Create the list lstNodes = new UINavList(new DefaultListModel()); lstNodes.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if(e.getClickCount() == 2) onPurge(); } }); lstNodes.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); lstNodes.setCellRenderer(new LabelListCellRenderer()); lstNodes.setBackground(Color.white); // create a scroll viewer to add scroll functionality in the list view JScrollPane sp = new JScrollPane(lstNodes); sp.setPreferredSize(new Dimension(250, 200)); // add list view to dialog gb.setConstraints(sp, gc); listpanel.add(sp); oContentPane.add(listpanel, BorderLayout.CENTER); oContentPane.add(createSideButtonPanel(), BorderLayout.EAST); oContentPane.add(createButtonPanel(), BorderLayout.SOUTH); // other initializations updateListView(); pack(); setResizable(false); } /** * Draw the panel of buttons for this dialog. */ private JPanel createSideButtonPanel() { GridBagLayout gb = new GridBagLayout(); GridBagConstraints gc = new GridBagConstraints(); gc = new GridBagConstraints(); gc.insets = new Insets(5,5,5,5); gc.fill=GridBagConstraints.HORIZONTAL; gc.anchor = GridBagConstraints.CENTER; gc.gridwidth = GridBagConstraints.REMAINDER; gc.weightx=1; gc.weighty=3; JPanel buttonpanel = new JPanel(); buttonpanel.setLayout(gb); buttonpanel.setBorder(new EmptyBorder(15,5,15,10)); JLabel label = new JLabel(""); //$NON-NLS-1$ gb.setConstraints(label, gc); buttonpanel.add(label); gc.weighty=1; pbPurge = new UIButton(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.purgeButton")); //$NON-NLS-1$ pbPurge.setMnemonic(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.purgeButtonMnemonic").charAt(0)); //$NON-NLS-1$ pbPurge.addActionListener(this); getRootPane().setDefaultButton(pbPurge); gb.setConstraints(pbPurge, gc); buttonpanel.add(pbPurge); pbSelectAll = new UIButton(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.selectAllButton")); //$NON-NLS-1$ pbSelectAll.setMnemonic(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.selectAllButtonMnemonic").charAt(0)); //$NON-NLS-1$ pbSelectAll.addActionListener(this); gb.setConstraints(pbSelectAll, gc); buttonpanel.add(pbSelectAll); pbRestore = new UIButton(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.restoreHereButton")); //$NON-NLS-1$ pbRestore.setMnemonic(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.restoreHereButtonMnemonic").charAt(0)); //$NON-NLS-1$ pbRestore.addActionListener(this); gb.setConstraints(pbRestore, gc); buttonpanel.add(pbRestore); pbRestoreView = new UIButton(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.restoreToViewButton")); //$NON-NLS-1$ pbRestoreView.setMnemonic(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.restoreToViewButtonMnemonic").charAt(0)); //$NON-NLS-1$ pbRestoreView.addActionListener(this); gb.setConstraints(pbRestoreView, gc); buttonpanel.add(pbRestoreView); return buttonpanel; } /** * Create the panel of buttons. */ private UIButtonPanel createButtonPanel() { UIButtonPanel oButtonPanel = new UIButtonPanel(); pbClose = new UIButton(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.closeButton")); //$NON-NLS-1$ pbClose.setMnemonic(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.closeButtonMenmonic").charAt(0)); //$NON-NLS-1$ pbClose.addActionListener(this); oButtonPanel.addButton(pbClose); pbHelp = new UIButton(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.helpButton")); //$NON-NLS-1$ ProjectCompendium.APP.mainHB.enableHelpOnButton(pbHelp, "basics.trashbin", ProjectCompendium.APP.mainHS); //$NON-NLS-1$ pbHelp.setMnemonic(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.helpButtonMnemonic").charAt(0)); //$NON-NLS-1$ oButtonPanel.addHelpButton(pbHelp); return oButtonPanel; } /** * Handle button push events. * @param event, the assoicated ActionEvent. */ public void actionPerformed(ActionEvent event) { Object source = event.getSource(); // Handle button events if (source instanceof JButton) { if (source == pbPurge) { onPurge(); } else if (source == pbLabel) { onSortBy(CoreUtilities.LABEL); } else if (source == pbCreationDate) { onSortBy(CoreUtilities.CREATION_DATE); } else if (source == pbModificationDate) { onSortBy(CoreUtilities.MODIFICATION_DATE); } else if (source == pbClose) { onCancel(); } else if (source == pbSelectAll) { onSelectAll(); } else if (source == pbRestore) { onRestore(); } else if (source == pbRestoreView) { onRestoreView(); } } } /** * Sort the list of deleted nodes by the given field. * @param sortCriteria, the field to sort the list by. */ private void onSortBy(int sortCritieria) { ((DefaultListModel)lstNodes.getModel()).removeAllElements(); //sort the vector vtNodes = CoreUtilities.sortList(vtNodes, sortCritieria); for(Enumeration e = vtNodes.elements();e.hasMoreElements();) { NodeSummary node = (NodeSummary)e.nextElement(); //log.info("Processing " + node.getLabel()); ImageIcon img = null; img = UINode.getNodeImageSmall(node.getType()); //trim text to fit the label for the timebeing since the label comes out of the scrollbar window StringBuffer sb = new StringBuffer(40); sb.ensureCapacity(40); String text = ""; //$NON-NLS-1$ text = node.getLabel(); if(text.length() > 40) { text = text.substring(0,36); text += "..."; //$NON-NLS-1$ } else { int i=0;String padString = ""; //$NON-NLS-1$ int pad = 40 - (node.getLabel()).length(); while(i++ < pad) { text += " "; //$NON-NLS-1$ } } String nodelabel = text; String creationDate = ""; //$NON-NLS-1$ String modificationDate = ""; //$NON-NLS-1$ if(sortCritieria == CoreUtilities.CREATION_DATE) creationDate = UIUtilities.getSimpleDateFormat("dd, MMMM, yyyy").format(node.getCreationDate()).toString(); //$NON-NLS-1$ else if(sortCritieria == CoreUtilities.MODIFICATION_DATE) modificationDate = UIUtilities.getSimpleDateFormat("dd, MMMM, yyyy").format(node.getModificationDate()).toString(); //$NON-NLS-1$ //text = nodelabel + " " + creationDate + " " + modificationDate; sb.insert(0,nodelabel); sb.append(creationDate); sb.append(modificationDate); //JLabel label = new JLabel(text,img,SwingConstants.LEFT); JLabel label = new JLabel(sb.toString(),img,SwingConstants.CENTER); label.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if(e.getClickCount() == 2) onPurge(); } }); label.setToolTipText(text); ((DefaultListModel)lstNodes.getModel()).addElement(label); } lstNodes.setSelectedIndex(0); } /** * The thread class that runs the progress bar. */ private class ProgressThread extends Thread { public ProgressThread() { oProgressDialog = new UIProgressDialog(ProjectCompendium.APP,LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.progressMessage"), LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.progressTitle")); //$NON-NLS-1$ //$NON-NLS-2$ oProgressDialog.showDialog(oProgressBar); oProgressDialog.setModal(true); } public void run() { oProgressDialog.setVisible(true); } } /** * Check if the user has cancelled the restore. */ private boolean checkProgress() { if (oProgressDialog.isCancelled()) { int result = JOptionPane.showConfirmDialog(oProgressDialog, LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.cancelPrugeMessage"), //$NON-NLS-1$ LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.cancelPurge"), //$NON-NLS-1$ JOptionPane.YES_NO_OPTION); if (result == JOptionPane.YES_OPTION) { oProgressDialog.setVisible(false); return true; } else { oProgressDialog.setCancelled(false); return false; } } return false; } /** * Start the progress bar for the purge request, the start the purge. * @see #processPurge */ public void onPurge() { //get the optionpane dialog int resp = JOptionPane.showConfirmDialog(ProjectCompendium.APP, LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.checkMessage")); //$NON-NLS-1$ if((resp == JOptionPane.NO_OPTION) || (resp == JOptionPane.CANCEL_OPTION) || (resp == JOptionPane.CLOSED_OPTION)) return ; oProgressBar = new JProgressBar(); oProgressBar.setMinimum(0); oProgressBar.setMaximum(100); oThread = new ProgressThread(); oThread.start(); Thread thread = new Thread("UITrashViewDialog: Purge") { //$NON-NLS-1$ public void run() { processPurge(); } }; thread.start(); } /** * Pruge all the selected nodes from the database permenantly. */ private void processPurge() { ProjectCompendium.APP.setWaitCursor(); Vector vtDeletedNodes = new Vector(); int [] selection = lstNodes.getSelectedIndices(); boolean audioPlayed = false; int count = selection.length; oProgressBar.setMaximum(count); for(int i=0;i<selection.length;i++) { if (checkProgress()) return; if (i < vtNodes.size()) { // SHOULDN'T BE NEEDED, BUT IT FELL OVER boolean deleted = false; NodeSummary node = (NodeSummary)vtNodes.elementAt(selection[i]); try { deleted = ProjectCompendium.APP.getModel().getNodeService().purgeNode(ProjectCompendium.APP.getModel().getSession(), node.getId()); //if node cannot be deleted then inform the user if(!deleted) { //popup the error message JOptionPane oOptionPane = new JOptionPane(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.cannotDelete") + node.getLabel()); //$NON-NLS-1$ JDialog oDialog = oOptionPane.createDialog(oContentPane,LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UITrashViewDialog.deleteError")); //$NON-NLS-1$ oDialog.setModal(true); oDialog.setVisible(true); oDialog.dispose(); } else { //mark the corresponding node in vtNodes vector as deleted vtDeletedNodes.addElement(node.getId()); //play audio once if(!audioPlayed) { ProjectCompendium.APP.getAudioPlayer().playAudio(UIAudio.PURGING_ACTION); audioPlayed = true; } } } catch(SQLException ex) { ProjectCompendium.APP.displayError("Exception: (UITrashViewDialog.onPurge) " + ex.getMessage()); //$NON-NLS-1$ } } Count = i+1; oProgressBar.setValue(Count); oProgressDialog.setStatus(Count); } // UPDATE TRASHBIN LIST updateListView(); ProjectCompendium.APP.setDefaultCursor(); oProgressDialog.setVisible(false); oProgressDialog.dispose(); if(vtNodes.size() == 0) onCancel(); } /** * Open an instance of UIDeletedViewDialog, for the user to select a view to restore to. * @see com.compendium.ui.dialogs.UIDeletedViewDialog */ private void onRestoreView() { int index = lstNodes.getSelectedIndex(); if (index != -1) { NodeSummary oNode = (NodeSummary)vtNodes.elementAt(index); UIDeletedViewDialog dialog = new UIDeletedViewDialog(oParent, oNode, this); dialog.setVisible(true); } } /** * Restore the selected nodes to the home view. */ private void onRestore() { ProjectCompendium.APP.setWaitCursor(); View homeView = ProjectCompendium.APP.getHomeView(); UIViewFrame homeFrame = ProjectCompendium.APP.getInternalFrame(homeView); View view = homeFrame.getView(); int [] selection = lstNodes.getSelectedIndices(); for(int i=0; i< selection.length;i++) { NodeSummary node = (NodeSummary)vtNodes.elementAt(selection[i]); ProjectCompendium.APP.restore(node, view); } // UPDATE TRASHBIN LIST updateListView(); // INCASE TRANSCLUSION NUMBERS NEED UPDATING ProjectCompendium.APP.refreshIconIndicators(); ProjectCompendium.APP.setDefaultCursor(); } /** * Updates the list of deleted views from the database. */ public void updateListView() { ((DefaultListModel)lstNodes.getModel()).removeAllElements(); vtNodes.removeAllElements(); IModel model = ProjectCompendium.APP.getModel(); PCSession session = model.getSession(); try { vtResults = ProjectCompendium.APP.getModel().getNodeService().getDeletedNodeSummary(session); } catch(SQLException re) {} //change the icon depending upon if the trashbin is full or not if(vtResults.size() > 0) { ImageIcon img = UIImages.getNodeIcon(IUIConstants.TRASHBINFULL_ICON); oUINode.setIcon(img); } else { ImageIcon img = UIImages.getNodeIcon(IUIConstants.TRASHBIN_ICON); oUINode.setIcon(img); } lblCount.setText(sObjectCount + String.valueOf(vtResults.size())); if(vtResults.size() < 1) return; //sort the vector vtResults = CoreUtilities.sortList(vtResults); for(Enumeration e = vtResults.elements();e.hasMoreElements();) { NodeSummary node = (NodeSummary)e.nextElement(); node.initialize(session, model); ImageIcon img = null; img = UINode.getNodeImageSmall(node.getType()); //trim text to fit the label for the timebeing since the label comes out of the scrollbar window String text = node.getLabel(); if(text.length() > 40) { text = text.substring(0,39); text += "...."; //$NON-NLS-1$ } JLabel label = new JLabel(text,img,SwingConstants.LEFT); label.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if(e.getClickCount() == 2) onPurge(); } }); label.setToolTipText(text); ((DefaultListModel)lstNodes.getModel()).addElement(label); vtNodes.addElement(node); } lstNodes.setSelectedIndex(0); } /** * Select All the nodes in the list. */ private void onSelectAll() { int size = 0; if(vtResults != null) size = vtResults.size(); lstNodes.setSelectionInterval(0,size-1); } }