/* * This file is part of muCommander, http://www.mucommander.com * Copyright (C) 2002-2016 Maxence Bernard * * muCommander is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * muCommander is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.mucommander.ui.dialog.file; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.IOException; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import com.mucommander.commons.file.AbstractFile; import com.mucommander.commons.file.util.FileSet; import com.mucommander.conf.MuConfigurations; import com.mucommander.conf.MuPreference; import com.mucommander.job.impl.SendMailJob; import com.mucommander.text.SizeFormat; import com.mucommander.text.Translator; import com.mucommander.ui.action.ActionProperties; import com.mucommander.ui.action.impl.EmailAction; import com.mucommander.ui.dialog.DialogToolkit; import com.mucommander.ui.dialog.pref.general.GeneralPreferencesDialog; import com.mucommander.ui.layout.XAlignedComponentPanel; import com.mucommander.ui.layout.YBoxPanel; import com.mucommander.ui.main.MainFrame; /** * Dialog allowing the user to email files to someone. * * <p>One or several recipients, as well as a mail subject and body can be input. * The dialog also allows the user to review the files that have been marked, * select/unselect some, and displays the total file size.</p> * * @author Maxence Bernard */ public class EmailFilesDialog extends JobDialog implements ActionListener, ItemListener { private FileSet flattenedFiles; private JTextField toField; private JTextField subjectField; private JTextArea bodyArea; private JLabel infoLabel; private JCheckBox fileCheckboxes[]; private static String lastTo = ""; private static String lastSubject = ""; private static String lastBody = ""; private JButton okButton; private JButton cancelButton; // Dialog size constraints private final static Dimension MINIMUM_DIALOG_DIMENSION = new Dimension(400,0); private final static Dimension MAXIMUM_DIALOG_DIMENSION = new Dimension(550,400); public EmailFilesDialog(MainFrame mainFrame, FileSet files) { super(mainFrame, ActionProperties.getActionLabel(EmailAction.Descriptor.ACTION_ID), files); // Notifies the user that mail preferences are not set and brings the preferences dialog if(!SendMailJob.mailPreferencesSet()) { showErrorDialog(Translator.get("email_dialog.prefs_not_set"), Translator.get("email_dialog.prefs_not_set_title")); GeneralPreferencesDialog preferencesDialog = GeneralPreferencesDialog.getDialog(); preferencesDialog.setActiveTab(GeneralPreferencesDialog.MAIL_TAB); preferencesDialog.showDialog(); return; } try { // Figures out which files to send and calculates the number of files and the number of bytes this.flattenedFiles = getFlattenedFiles(files); Container contentPane = getContentPane(); YBoxPanel mainPanel = new YBoxPanel(5); // Text fields panel XAlignedComponentPanel compPanel = new XAlignedComponentPanel(); // From (sender) field, non editable JLabel fromLabel = new JLabel(MuConfigurations.getPreferences().getVariable(MuPreference.MAIL_SENDER_NAME) +" <"+MuConfigurations.getPreferences().getVariable(MuPreference.MAIL_SENDER_ADDRESS)+">"); // fromField.setEditable(false); compPanel.addRow(Translator.get("email_dialog.from")+":", fromLabel, 10); // To (recipients) field toField = new JTextField(lastTo); compPanel.addRow(Translator.get("email_dialog.to")+":", toField, 10); // Subject field subjectField = new JTextField(lastSubject); compPanel.addRow(Translator.get("email_dialog.subject")+":", subjectField, 15); mainPanel.add(compPanel); // Body area bodyArea = new JTextArea(lastBody); bodyArea.setRows(6); bodyArea.setLineWrap(true); JScrollPane scrollPane = new JScrollPane(bodyArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); mainPanel.add(scrollPane); mainPanel.addSpace(15); // Label showing the number of files and total size infoLabel = new JLabel(); mainPanel.add(infoLabel); contentPane.add(mainPanel, BorderLayout.NORTH); // checkbox showing all files that are to be sent, allowing them to be unselected int nbFiles = flattenedFiles.size(); fileCheckboxes = new JCheckBox[nbFiles]; if(nbFiles>0) { YBoxPanel tempPanel2 = new YBoxPanel(); AbstractFile file; for(int i=0; i<nbFiles; i++) { file = flattenedFiles.elementAt(i); fileCheckboxes[i] = new JCheckBox(file.getName() +" ("+ SizeFormat.format(file.getSize(), SizeFormat.DIGITS_MEDIUM| SizeFormat.UNIT_SHORT| SizeFormat.INCLUDE_SPACE| SizeFormat.ROUND_TO_KB)+")", true); fileCheckboxes[i].addItemListener(this); tempPanel2.add(fileCheckboxes[i]); } scrollPane = new JScrollPane(tempPanel2, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); contentPane.add(scrollPane, BorderLayout.CENTER); } updateInfoLabel(); // OK / Cancel buttons panel okButton = new JButton(Translator.get("email_dialog.send")); cancelButton = new JButton(Translator.get("cancel")); contentPane.add(DialogToolkit.createOKCancelPanel(okButton, cancelButton, getRootPane(), this), BorderLayout.SOUTH); // 'To' field will receive initial focus setInitialFocusComponent(toField); // Packs dialog setMinimumSize(MINIMUM_DIALOG_DIMENSION); setMaximumSize(MAXIMUM_DIALOG_DIMENSION); } catch(IOException e) { showErrorDialog(Translator.get("email_dialog.read_error"), Translator.get("email_dialog.error_title")); } } /** * Updates the number of selected files and their total size. */ private void updateInfoLabel() { int nbFiles = fileCheckboxes.length; int nbSelected = 0; int bytesTotal = 0; long fileSize; for(int i=0; i<nbFiles; i++) { if(fileCheckboxes[i].isSelected()) { fileSize = flattenedFiles.elementAt(i).getSize(); if(fileSize>0) bytesTotal += fileSize; nbSelected++; } } String text = Translator.get("nb_files", ""+nbSelected) +(nbSelected==0?"":" ("+ SizeFormat.format(bytesTotal, SizeFormat.DIGITS_MEDIUM| SizeFormat.UNIT_LONG| SizeFormat.ROUND_TO_KB)+")"); infoLabel.setText(text); infoLabel.repaint(100); } /** * Returns a FileSet of *files* (as opposed to folders) that have been found either in the given * FileSet or in one of the subfolders. * * @param originalFiles files as selected by the user which may contain folders */ private FileSet getFlattenedFiles(FileSet originalFiles) throws IOException { int nbFiles = originalFiles.size(); FileSet flattenedFiles = new FileSet(originalFiles.getBaseFolder()); for(int i=0; i<nbFiles; i++) recurseOnFolder(originalFiles.elementAt(i), flattenedFiles); return flattenedFiles; } /** * Adds the given file to the FileSet if it's not a folder, recurses otherwise. */ private void recurseOnFolder(AbstractFile file, FileSet flattenedFiles) throws IOException { if(file.isDirectory() && !file.isSymlink()) { AbstractFile children[] = file.ls(); for (AbstractFile child : children) recurseOnFolder(child, flattenedFiles); } else { flattenedFiles.add(file); } } //////////////////////////// // ActionListener methods // //////////////////////////// public void actionPerformed(ActionEvent e) { Object source = e.getSource(); // OK Button if (source==okButton) { String to = toField.getText().trim(); String subject = subjectField.getText(); String body = bodyArea.getText(); if(!to.equals("")) { lastTo = to; lastSubject = subject; lastBody = body; // Starts by disposing the dialog dispose(); // Creates new FileSet with files that have been selected FileSet filesToSend = new FileSet(flattenedFiles.getBaseFolder()); int nbFiles = fileCheckboxes.length; for(int i=0; i<nbFiles; i++) if(fileCheckboxes[i].isSelected()) filesToSend.add(flattenedFiles.elementAt(i)); // Starts sending files ProgressDialog progressDialog = new ProgressDialog(mainFrame, Translator.get("email_dialog.sending")); SendMailJob mailJob = new SendMailJob(progressDialog, mainFrame, filesToSend, to, subject, body); progressDialog.start(mailJob); } } // Cancel button else if (source==cancelButton) { dispose(); } } ////////////////////////// // ItemListener methods // ////////////////////////// /** * Updates label text whenever a checkbox has been checked or unchecked. */ public void itemStateChanged(ItemEvent e) { updateInfoLabel(); } }