001: //The contents of this file are subject to the Mozilla Public License Version 1.1
002: //(the "License"); you may not use this file except in compliance with the
003: //License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
004: //
005: //Software distributed under the License is distributed on an "AS IS" basis,
006: //WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
007: //for the specific language governing rights and
008: //limitations under the License.
009: //
010: //The Original Code is "The Columba Project"
011: //
012: //The Initial Developers of the Original Code are Frederik Dietz and Timo Stich.
013: //Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
014: //
015: //All Rights Reserved.
016: package org.columba.mail.gui.composer;
017:
018: import java.awt.event.ActionListener;
019: import java.awt.event.KeyEvent;
020: import java.awt.event.KeyListener;
021: import java.awt.event.MouseAdapter;
022: import java.awt.event.MouseEvent;
023: import java.io.File;
024: import java.io.IOException;
025: import java.util.logging.Logger;
026:
027: import javax.swing.JComponent;
028: import javax.swing.JFileChooser;
029: import javax.swing.event.ListSelectionEvent;
030: import javax.swing.event.ListSelectionListener;
031:
032: import org.columba.core.desktop.ColumbaDesktop;
033: import org.columba.mail.util.MailResourceLoader;
034: import org.columba.ristretto.io.FileSource;
035: import org.columba.ristretto.message.LocalMimePart;
036: import org.columba.ristretto.message.MimeHeader;
037: import org.columba.ristretto.message.StreamableMimePart;
038:
039: /**
040: * Controller for the attachment view.
041: *
042: * @author frdietz
043: * @author redsolo
044: */
045: public class AttachmentController implements KeyListener,
046: ListSelectionListener {
047:
048: private static final Logger LOG = Logger
049: .getLogger("org.columba.mail.gui.composer");
050:
051: private AttachmentView view;
052:
053: private ComposerController composerController;
054:
055: private AttachmentActionListener actionListener;
056:
057: private AttachmentMenu menu;
058:
059: private JFileChooser fileChooser;
060:
061: /**
062: * Creates the attachment controller.
063: *
064: * @param controller
065: * the main composer controller.
066: */
067: public AttachmentController(ComposerController controller) {
068: this .composerController = controller;
069:
070: view = new AttachmentView(this );
071:
072: actionListener = new AttachmentActionListener(this );
073:
074: menu = new AttachmentMenu(this );
075:
076: view.addPopupListener(new PopupListener());
077:
078: // register Component as FocusOwner
079: // FocusManager.getInstance().registerComponent(this);
080:
081: fileChooser = new JFileChooser();
082:
083: installListener();
084:
085: // view.addListSelectionListener(this);
086: }
087:
088: /**
089: * Returns the action listener for this attachment controller.
090: *
091: * @return the action listener for this attachment controller.
092: */
093: public ActionListener getActionListener() {
094: return actionListener;
095: }
096:
097: /**
098: * Installs this object as a listener to the view.
099: */
100: public void installListener() {
101: view.installListener(this );
102: }
103:
104: /**
105: * Synchronizes model and view.
106: *
107: * @param b
108: * If true, model data is transferred to the view. If false, view
109: * data is saved in the model.
110: */
111: public void updateComponents(boolean b) {
112: if (b) {
113: // transfer attachments from model to view
114:
115: /*
116: * clear existing attachments from the view *20031105, karlpeder*
117: * Added to avoid dupplicating attachments when switching btw. html
118: * and plain text.
119: */
120: view.clear();
121:
122: // add attachments (mimeparts) from model to the view
123: for (int i = 0; i < composerController.getModel()
124: .getAttachments().size(); i++) {
125: StreamableMimePart p = (StreamableMimePart) composerController
126: .getModel().getAttachments().get(i);
127: view.add(p);
128: }
129: } else {
130: // transfer attachments from view to model
131: // clear existing attachments from the model
132: composerController.getModel().getAttachments().clear();
133:
134: // add attachments (mimeparts) from view to the model
135: for (int i = 0; i < view.count(); i++) {
136: StreamableMimePart mp = (StreamableMimePart) view
137: .get(i);
138: composerController.getModel().getAttachments().add(mp);
139: }
140: }
141: }
142:
143: /**
144: * Removes the current selected attachments.
145: */
146: public void removeSelected() {
147: view.removeSelected();
148:
149: // hide/show attachment panel
150: composerController.showAttachmentPanel();
151: }
152:
153: /**
154: * Opens up a file chooser and lets the user select the files to import.
155: */
156: public void addFileAttachment() {
157: int returnValue;
158: File[] files;
159:
160: fileChooser.setDialogTitle(MailResourceLoader.getString(
161: "menu", "composer", "menu_message_attachFile")); //$NON-NLS-1$
162: fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
163: fileChooser.setMultiSelectionEnabled(true);
164: returnValue = fileChooser.showOpenDialog(view);
165:
166: if (returnValue == JFileChooser.APPROVE_OPTION) {
167: files = fileChooser.getSelectedFiles();
168:
169: for (int i = 0; i < files.length; i++) {
170: addFileAttachment(files[i]);
171: }
172: }
173:
174: // show attachment panel
175: composerController.showAttachmentPanel();
176: }
177:
178: /**
179: * Attaches a file to the email as an attachment. This method accepts only
180: * files and not directories.
181: *
182: * @param file
183: * the file to attach to the email.
184: */
185: public void addFileAttachment(File file) {
186: if (file.isFile()) {
187:
188: String mimetype = ColumbaDesktop.getInstance().getMimeType(
189: file);
190:
191: MimeHeader header = new MimeHeader(mimetype.substring(0,
192: mimetype.indexOf('/')), mimetype.substring(mimetype
193: .indexOf('/') + 1));
194: header.putContentParameter("name", file.getName());
195: header.setContentDisposition("attachment");
196: header.putDispositionParameter("filename", file.getName());
197: header.setContentTransferEncoding("base64");
198:
199: try {
200: LocalMimePart mimePart = new LocalMimePart(header,
201: new FileSource(file));
202:
203: view.add(mimePart);
204: } catch (IOException e) {
205: LOG.warning("Could not add the file '" + file
206: + "' to the attachment list, due to:" + e);
207: }
208: }
209: }
210:
211: public AttachmentView getView() {
212: return view;
213: }
214:
215: /** ***************** KeyListener *************************** */
216:
217: /** {@inheritDoc} */
218: public void keyPressed(KeyEvent k) {
219: switch (k.getKeyCode()) {
220: case (KeyEvent.VK_DELETE):
221: delete();
222:
223: break;
224: }
225: }
226:
227: /** {@inheritDoc} */
228: public void keyReleased(KeyEvent k) {
229: }
230:
231: /** {@inheritDoc} */
232: public void keyTyped(KeyEvent k) {
233: }
234:
235: /** ******************** FocusOwner implementation ****************** */
236:
237: /** {@inheritDoc} */
238: public void copy() {
239: // attachment controller doesn't support copy-operation
240: }
241:
242: /** {@inheritDoc} */
243: public void cut() {
244: if (view.count() > 0) {
245: removeSelected();
246: }
247: }
248:
249: /** {@inheritDoc} */
250: public void delete() {
251: if (view.count() > 0) {
252: removeSelected();
253: }
254: }
255:
256: /** {@inheritDoc} */
257: public JComponent getComponent() {
258: return view;
259: }
260:
261: /** {@inheritDoc} */
262: public boolean isCopyActionEnabled() {
263: // attachment controller doesn't support copy actions
264: return false;
265: }
266:
267: /** {@inheritDoc} */
268: public boolean isCutActionEnabled() {
269: return (view.getSelectedValues().length > 0);
270: }
271:
272: /** {@inheritDoc} */
273: public boolean isDeleteActionEnabled() {
274: return (view.getSelectedValues().length > 0);
275: }
276:
277: /** {@inheritDoc} */
278: public boolean isPasteActionEnabled() {
279: // attachment controller doesn't support paste actions
280: return false;
281: }
282:
283: /** {@inheritDoc} */
284: public boolean isSelectAllActionEnabled() {
285: return (view.count() > 0);
286: }
287:
288: /** {@inheritDoc} */
289: public void paste() {
290: // attachment controller doesn't support paste actions
291: }
292:
293: /** {@inheritDoc} */
294: public boolean isRedoActionEnabled() {
295: // attachment controller doesn't support redo operation
296: return false;
297: }
298:
299: /** {@inheritDoc} */
300: public boolean isUndoActionEnabled() {
301: // attachment controller doesn't support undo operation
302: return false;
303: }
304:
305: /** {@inheritDoc} */
306: public void redo() {
307: // attachment controller doesn't support redo operation
308: }
309:
310: /** {@inheritDoc} */
311: public void selectAll() {
312: // view.setSelectionInterval(0, view.count() - 1);
313: }
314:
315: /** {@inheritDoc} */
316: public void undo() {
317: // attachment controller doesn't support undo operation
318: }
319:
320: /**
321: * ******************* ListSelectionListener interface
322: * **********************
323: */
324:
325: /** {@inheritDoc} */
326: public void valueChanged(ListSelectionEvent arg0) {
327: // FocusManager.getInstance().updateActions();
328: }
329:
330: /** ******************** MouseListener **************************** */
331: class PopupListener extends MouseAdapter {
332:
333: /** {@inheritDoc} */
334: public void mousePressed(MouseEvent e) {
335: maybeShowPopup(e);
336: }
337:
338: /** {@inheritDoc} */
339: public void mouseReleased(MouseEvent e) {
340: maybeShowPopup(e);
341: }
342:
343: /**
344: * Shows the popup menu.
345: *
346: * @param e
347: * the mouse event used to get the selected attachment.
348: */
349: private void maybeShowPopup(MouseEvent e) {
350: if (e.isPopupTrigger()) {
351: Object[] values = view.getSelectedValues();
352:
353: if (values.length == 0) {
354: view.fixSelection(e.getX(), e.getY());
355: }
356:
357: menu.show(e.getComponent(), e.getX(), e.getY());
358: }
359: }
360: }
361: }
|