/******************************************************************************** * * * (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.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.net.URLEncoder; import java.util.Enumeration; import java.util.Vector; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.compendium.LanguageProperties; import com.compendium.ProjectCompendium; import com.compendium.core.ICoreConstants; import com.compendium.core.datamodel.IModel; import com.compendium.core.datamodel.NodePosition; import com.compendium.core.datamodel.NodeSummary; import com.compendium.core.datamodel.UserProfile; import com.compendium.core.datamodel.View; import com.compendium.ui.ExecuteControl; import com.compendium.ui.FormatProperties; import com.compendium.ui.IUIConstants; import com.compendium.ui.LabelListCellRenderer; import com.compendium.ui.UIButton; import com.compendium.ui.UIListViewFrame; import com.compendium.ui.UINavList; import com.compendium.ui.UITextArea; import com.compendium.ui.UIViewFrame; /** * UISendMailDialog defines the dialog that allows the user to send mail to a group of people. * * @author M. Begeman */ public class UISendMailDialog extends UIDialog implements ActionListener, IUIConstants { /** * class's own logger */ static final Logger log = LoggerFactory.getLogger(UIDialog.class); /** The parent frame for this dialog.*/ private JFrame oParent = null; /** The current pane to put the dialog contents in.*/ private Container oContentPane = null; /** The button to send the email.*/ private JButton pbSend = null; /** The button to close the dialog.*/ private JButton pbClose = null; /** The layout manager used.*/ private GridBagLayout gb = null; /** The constraints used.*/ private GridBagConstraints gc = null; /** The text area to hold the Message label.*/ private JLabel lblMessage = null; /** The text are to hold any user-entered mail message.*/ private static UITextArea txtMessage = null; /** The text area to hold the node label.*/ private JLabel lblToList = null; /** The list of potentials users to send mail to.*/ private UINavList lstUsers = null; /** Holds the list of selected users to send mail to.*/ private Vector vtUsers = new Vector(); /** The ID of the View the node being mailed is in */ private static View oContainingView = null; /** The NodeSummary object for the node being mailed */ private static NodeSummary oNode = null; /** * Constructor. Initializes and sets up the dialog. * * @param parent, the frame that is the parent for this dialog. * @param containingView, the view the node being sent resides in * @param ns, NodeSummary object for the node being sent */ public UISendMailDialog(JFrame parent, View containingView, NodeSummary ns) { super(parent, true); oParent = parent; oContainingView = containingView; oNode = ns; setTitle(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UISendMailDialog.cMailTitle")); //$NON-NLS-1$ oContentPane = getContentPane(); gb = new GridBagLayout(); oContentPane.setLayout(gb); drawDialog(); initUsersList(); setResizable(false); pack(); } /** * Draws the contents of this dialog. */ private void drawDialog() { int iGridy = 0; GridBagConstraints gc = new GridBagConstraints(); gc.insets = new Insets(5,5,5,5); gc.gridx = 0; gc.gridy = iGridy; gc.gridwidth = 2; gc.anchor = GridBagConstraints.WEST; lblToList = new JLabel(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UISendMailDialog.selectMail")); //$NON-NLS-1$ gb.setConstraints(lblToList, gc); oContentPane.add(lblToList); iGridy++; lstUsers = new UINavList(new DefaultListModel()); lstUsers.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); lstUsers.setCellRenderer(new LabelListCellRenderer()); lstUsers.setBackground(Color.white); JScrollPane sp1 = new JScrollPane(lstUsers); sp1.setPreferredSize(new Dimension(400,200)); gc.gridy=iGridy; gc.fill = GridBagConstraints.BOTH; gb.setConstraints(sp1, gc); oContentPane.add(sp1); iGridy++; if (FormatProperties.emailInbox) { lblMessage = new JLabel(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UISendMailDialog.label")); //$NON-NLS-1$ gc.gridy=iGridy; gc.fill = GridBagConstraints.NONE; gb.setConstraints(lblMessage, gc); oContentPane.add(lblMessage); iGridy++; txtMessage = new UITextArea(50, 50); txtMessage.setAutoscrolls(true); JScrollPane sp2 = new JScrollPane(txtMessage); sp2.setPreferredSize(new Dimension(400, 200)); gc.gridy=iGridy; gc.fill = GridBagConstraints.BOTH; gb.setConstraints(sp2, gc); oContentPane.add(sp2); iGridy++; } gc.fill = GridBagConstraints.NONE; pbSend = new UIButton(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UISendMailDialog.sendButton")); //$NON-NLS-1$ pbSend.setMnemonic(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UISendMailDialog.sendButtonMnemonic").charAt(0)); //$NON-NLS-1$ pbSend.addActionListener(this); gc.gridy = iGridy; gc.anchor = GridBagConstraints.WEST; gb.setConstraints(pbSend, gc); oContentPane.add(pbSend); pbClose = new UIButton(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UISendMailDialog.cancelButton")); //$NON-NLS-1$ pbClose.setMnemonic(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UISendMailDialog.cancelButtonMnemonic").charAt(0)); //$NON-NLS-1$ pbClose.addActionListener(this); gc.gridx = 1; gc.anchor = GridBagConstraints.CENTER; gb.setConstraints(pbClose, gc); oContentPane.add(pbClose); } /** * Fill in the dialog with a list of all Active users. */ private void initUsersList() { ((DefaultListModel)lstUsers.getModel()).removeAllElements(); vtUsers.removeAllElements(); for(Enumeration e = (ProjectCompendium.APP.getModel().getUsers()).elements();e.hasMoreElements();) { UserProfile up = (UserProfile)e.nextElement(); if (up.isActive()) { String authorName = up.getUserName(); String displayText = authorName; if (authorName.equals("")) { //$NON-NLS-1$ continue; } if(displayText.length() > 40) { displayText = displayText.substring(0,39); displayText += "...."; //$NON-NLS-1$ } JLabel lblAuthorsList = new JLabel(displayText,SwingConstants.LEFT); lblAuthorsList.setToolTipText(authorName); ((DefaultListModel)lstUsers.getModel()).addElement(lblAuthorsList); vtUsers.addElement(up); } } } /** * Handle action events coming from the buttons. * @param evt, the associated ACtionEvent. */ public void actionPerformed(ActionEvent evt) { Object source = evt.getSource(); // Handle button events if (source instanceof JButton) { if (source == pbSend) { onSend(); } else if (source == pbClose) { onCancel(); } } } /** * Send mail to the selected people. */ private void onSend() { String sToList = null; int [] selected = lstUsers.getSelectedIndices(); for(int i=0;i<selected.length;i++) { UserProfile up = (UserProfile)vtUsers.elementAt(selected[i]); onCreateInternalLinkInView(up); String sToName = ""; //$NON-NLS-1$ if (up.getUserDescription().startsWith("email:")) { //$NON-NLS-1$ sToName = up.getUserDescription().substring(6); //remainder after the 'email:' prefix } else { sToName = up.getUserName(); } if (sToList == null) { sToList = sToName; } else { sToList = sToList + "," + sToName; //$NON-NLS-1$ } } if (sToList != null) { sendDesktopMail(sToList); // Send the mail onCancel(); // Clean up } else { JOptionPane.showMessageDialog(this, LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UISendMailDialog.errorNoReceipient")); //$NON-NLS-1$ } } /** * Close the dialog. */ public void onCancel() { oContainingView = null; oNode = null; if (txtMessage != null) { txtMessage = null; } setVisible(false); dispose(); } /** * Handle the enter key action. Override superclass to do nothing. */ public void onEnter() {} /** * Sends an email message via the user's desktop mail client */ public static void sendDesktopMail(String sTo) { if (FormatProperties.emailInbox) { try { String URIString = null; URIString = "mailto:" + sTo; //Stuff username(s) into the To: field //$NON-NLS-1$ URIString = URIString + "?SUBJECT="; //$NON-NLS-1$ String sSubject = LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UISendMailDialog.cmailSubject")+" - "; //$NON-NLS-1$ if (oNode.getLabel().length() > 0) { sSubject = sSubject + oNode.getLabel(); } else { sSubject = sSubject + "(no label)"; //$NON-NLS-1$ } URIString = URIString + URLEncoder.encode(sSubject, "UTF-8"); //$NON-NLS-1$ URIString = URIString + "&BODY="; //$NON-NLS-1$ String URIBody = ""; if (txtMessage != null) { URIBody = txtMessage.getText(); } if (URIBody.length() > 0) URIBody = URIBody + "\n-----\n"; //$NON-NLS-1$ // URIBody = URIBody + "Node detail:\n\n"; // Begin aggregating the message body string. This will if (oNode.getDetail().length() == 0) { URIBody = URIBody + "<<no node detail>>\n"; //$NON-NLS-1$ } else { URIBody = URIBody + oNode.getDetail(); URIBody = URIBody + "\n"; //$NON-NLS-1$ } URIString= URIString + URLEncoder.encode(URIBody, "UTF-8"); //$NON-NLS-1$ URIString = URIString.replace("+", "%20"); // Required since UTF-8 turns spaces into + signs //$NON-NLS-1$ //$NON-NLS-2$ if (URIString.length() > 240) { // This limit avoids various desktop mail limits/bugs URIString = URIString.substring(0, 240); // Shorten the entire string to 240 bytes int iLastPercent = URIString.indexOf('%', 235); // Shorten it some more if we cut an encoding (like %20) in half if (iLastPercent > 0) URIString = URIString.substring(0, iLastPercent); URIString = URIString + "%0A..."; // Add an ellipses to indicate we cut content from the body //$NON-NLS-1$ } // log.info("Sending desktop email..."); // For debugging // log.info(URIString); // For debugging // log.info("String length: " + URIString.length()); ExecuteControl.launch(URIString); // Send the mailto: URL to the operating system } catch (java.io.UnsupportedEncodingException ex) { log.info("Unsupported encoding exception."); //$NON-NLS-1$ log.info(ex.getMessage()); log.error("Error...", ex); } } } /** * Create a Reference node with internal link to this node * and put it in the inbox for the given View and user. * @param view the view to add the reference to. * @param up the UserProfile for the chosen user */ private void onCreateInternalLinkInView(UserProfile up) { View view = up.getLinkView(); if (view == null) { view = ProjectCompendium.APP.createInBox(up); if (view == null) { ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UISendMailDialog.errorGettingReference")); //$NON-NLS-1$ return; } } IModel model = ProjectCompendium.APP.getModel(); UserProfile currentUser = model.getUserProfile(); view.initialize(model.getSession(), model); String sRef = ICoreConstants.sINTERNAL_REFERENCE+oContainingView.getId()+"/"+oNode.getId(); //$NON-NLS-1$ String sAuthor = ProjectCompendium.APP.getModel().getUserProfile().getUserName(); String sMessageText = ""; if (txtMessage != null) { sMessageText = txtMessage.getText(); } try{ NodePosition node = view.addMemberNode(ICoreConstants.REFERENCE, "", //$NON-NLS-1$ "", //$NON-NLS-1$ sAuthor, "GO TO: "+oNode.getLabel(), //$NON-NLS-1$ LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UISendMailDialog.from")+": "+currentUser.getUserName()+"\n"+ //$NON-NLS-1$ //$NON-NLS-2$ LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UISendMailDialog.message")+": "+sMessageText+"\n"+ //$NON-NLS-1$ //$NON-NLS-2$ "-------\n"+ //$NON-NLS-1$ LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UISendMailDialog.linkToNodeIn")+ //$NON-NLS-1$ "( "+oContainingView.getLabel()+" )\n\n", //$NON-NLS-1$ //$NON-NLS-2$ 0, ((view.getNodeCount() + 1) *10)); node.getNode().setSource(sRef, "", sAuthor); //$NON-NLS-1$ node.getNode().setState(ICoreConstants.UNREADSTATE); view.setState(ICoreConstants.MODIFIEDSTATE); } catch (Exception e) { ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.DIALOGS_BUNDLE, "UISendMailDialog.errorAddingToInbox")+":\n\n"+e.getMessage()); //$NON-NLS-1$ } // If the view is open (it's your in box and you have it open), refresh the view. UIViewFrame oViewFrame = ProjectCompendium.APP.getInternalFrame(view); if (oViewFrame != null) { UIListViewFrame listFrame = (UIListViewFrame)oViewFrame; listFrame.getUIList().updateTable(); } ProjectCompendium.APP.refreshNodeIconIndicators(ProjectCompendium.APP.getInBoxID()); } }