001: /*
002: * ImapMessageBuffer.java
003: *
004: * Copyright (C) 2000-2002 Peter Graves
005: * $Id: ImapMessageBuffer.java,v 1.4 2002/10/11 18:28:42 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j.mail;
023:
024: import javax.swing.SwingUtilities;
025: import org.armedbear.j.BackgroundProcess;
026: import org.armedbear.j.Debug;
027: import org.armedbear.j.Editor;
028: import org.armedbear.j.FastStringBuffer;
029: import org.armedbear.j.Headers;
030: import org.armedbear.j.Log;
031: import org.armedbear.j.MessageDialog;
032: import org.armedbear.j.ProgressNotifier;
033: import org.armedbear.j.StatusBarProgressNotifier;
034:
035: public final class ImapMessageBuffer extends MessageBuffer {
036: private boolean cancelled;
037:
038: /*package*/ImapMessageBuffer(ImapMailbox mailbox,
039: ImapMailboxEntry entry) {
040: super ();
041: // Mailbox is locked in ImapMailbox.readMessage() before this
042: // constructor is called.
043: Debug.assertTrue(mailbox.isLocked());
044: init(mailbox, entry);
045: }
046:
047: /*package*/ImapMessageBuffer(ImapMailbox mailbox,
048: ImapMailboxEntry entry, String rawText) {
049: super ();
050: init(mailbox, entry);
051: message = new Message(rawText);
052: parseMessage();
053: title = message.getHeaderValue(Headers.SUBJECT);
054: if (title == null)
055: title = "";
056: allHeaders = message.getAllHeaders();
057: defaultHeaders = getDefaultHeaders(allHeaders);
058: rawBody = message.getRawBody();
059: setText();
060: unmodified();
061: renumber();
062: formatter.parseBuffer();
063: setLoaded(true);
064: }
065:
066: private void init(ImapMailbox mailbox, ImapMailboxEntry entry) {
067: this .mailbox = mailbox;
068: showRawText = mailbox.showRawText;
069: showFullHeaders = mailbox.showFullHeaders;
070: setEntry(entry);
071: initializeUndo();
072: type = TYPE_NORMAL;
073: lineSeparator = "\n";
074: mode = MessageMode.getMode();
075: setFormatter(mode.getFormatter(this ));
076: readOnly = true;
077: }
078:
079: public int load() {
080: if (isLoaded())
081: return LOAD_COMPLETED;
082: if (!mailbox.isLocked()) {
083: Debug.bug();
084: setText("");
085: return LOAD_FAILED;
086: }
087: setBusy(true);
088: new Thread(loadProcess).start();
089: return LOAD_PENDING;
090: }
091:
092: private BackgroundProcess loadProcess = new BackgroundProcess() {
093: private ProgressNotifier progressNotifier;
094:
095: public void run() {
096: // Mailbox is locked in ImapMailbox.readMessage() before calling
097: // ImapMessageBuffer constructor.
098: if (!mailbox.isLocked()) {
099: Debug.bug();
100: return;
101: }
102: try {
103: setBackgroundProcess(this );
104: progressNotifier = new StatusBarProgressNotifier(
105: ImapMessageBuffer.this );
106: progressNotifier.progressStart();
107: loadMessage(progressNotifier);
108: progressNotifier.setText("");
109: progressNotifier.progressStop();
110: setBackgroundProcess(null);
111: setBusy(false);
112: } finally {
113: mailbox.unlock();
114: mailbox.setBusy(false);
115: Editor.updateDisplayLater(mailbox);
116: }
117: }
118:
119: public void cancel() {
120: Log.debug("loadProcess.cancel cancelled!");
121: cancelled = true;
122: progressNotifier.cancel();
123: setBusy(false);
124: Log.debug("loadProcess.cancel calling kill");
125: kill();
126: Log.debug("loadProcess.cancel back from kill");
127: }
128: };
129:
130: public void deleteMessage() {
131: storeFlagsInternal(ACTION_DELETE);
132: }
133:
134: public void flagMessage() {
135: storeFlagsInternal(ACTION_FLAG);
136: }
137:
138: private static final int ACTION_DELETE = 0;
139: private static final int ACTION_FLAG = 1;
140:
141: private void storeFlagsInternal(final int action) {
142: final Editor editor = Editor.currentEditor();
143: if (!mailbox.lock()) {
144: editor.status("Mailbox is locked");
145: return;
146: }
147: final int uid = ((ImapMailboxEntry) entry).getUid();
148: Runnable deleteMessageRunnable = new Runnable() {
149: public void run() {
150: try {
151: ImapSession session = ((ImapMailbox) mailbox)
152: .getSession();
153: String folderName = ((ImapMailbox) mailbox)
154: .getFolderName();
155: if (session.verifyConnected()
156: && session.verifySelected(folderName)) {
157: if (session.isReadOnly()) {
158: Log
159: .debug("deleteMessage - read-only - reselecting...");
160: session.reselect(folderName);
161: if (session.isReadOnly()) {
162: ((ImapMailbox) mailbox).readOnlyError();
163: return;
164: }
165: }
166: session.setEcho(true);
167: switch (action) {
168: case ACTION_DELETE:
169: session.uidStore(uid,
170: "+flags.silent (\\deleted)");
171: break;
172: case ACTION_FLAG:
173: // Toggle.
174: if (entry.isFlagged())
175: session.uidStore(uid,
176: "-flags.silent (\\flagged)");
177: else
178: session.uidStore(uid,
179: "+flags.silent (\\flagged)");
180: break;
181: default:
182: Debug.assertTrue(false);
183: break;
184: }
185: if (session.getResponse() == ImapSession.OK) {
186: switch (action) {
187: case ACTION_DELETE:
188: entry.setFlags(entry.getFlags()
189: | MailboxEntry.DELETED);
190: break;
191: case ACTION_FLAG:
192: entry.toggleFlag();
193: break;
194: default:
195: Debug.assertTrue(false);
196: break;
197: }
198: mailbox.updateEntry(entry);
199: }
200: session.setEcho(false);
201: MailboxEntry nextEntry = mailbox
202: .getNextUndeleted(entry);
203: if (nextEntry != null) {
204: mailbox.setDotEntry(nextEntry);
205: setEntry(nextEntry);
206: loadMessage(null);
207: } else {
208: Runnable messageIndexRunnable = new Runnable() {
209: public void run() {
210: MailCommands.messageIndex(editor);
211: editor
212: .status("Last undeleted message");
213: }
214: };
215: SwingUtilities
216: .invokeLater(messageIndexRunnable);
217: }
218: setBusy(false);
219: editor.updateDisplayLater();
220: }
221: } finally {
222: setBusy(false);
223: mailbox.unlock();
224: }
225: }
226: };
227: setBusy(true);
228: new Thread(deleteMessageRunnable).start();
229: }
230:
231: public void moveMessage() {
232: final Editor editor = Editor.currentEditor();
233: final ImapMailboxEntry toBeMoved = (ImapMailboxEntry) entry;
234: String title = "Move Message to Folder";
235: String s = ChooseFolderDialog.chooseFolder(editor, title);
236: if (s == null)
237: return;
238: if (!s.startsWith("mailbox:")) {
239: // Not local. Extract folder name from URL.
240: s = ((ImapMailbox) mailbox).extractFolderName(s);
241: if (s == null) {
242: MessageDialog.showMessageDialog(editor,
243: "Invalid destination", "Error");
244: return;
245: }
246: }
247: if (!mailbox.lock()) {
248: editor.status("Mailbox is locked");
249: return;
250: }
251: final String destination = s;
252: Runnable moveMessageRunnable = new Runnable() {
253: public void run() {
254: try {
255: ImapSession session = ((ImapMailbox) mailbox)
256: .getSession();
257: String folderName = ((ImapMailbox) mailbox)
258: .getFolderName();
259: if (session.verifyConnected()
260: && session.verifySelected(folderName)) {
261: if (session.isReadOnly()) {
262: Log
263: .debug("moveMessage - read-only - reselecting...");
264: session.reselect(folderName);
265: if (session.isReadOnly()) {
266: ((ImapMailbox) mailbox).readOnlyError();
267: return;
268: }
269: }
270: session.setEcho(true);
271: boolean succeeded = false;
272: if (destination.startsWith("mailbox:")) {
273: succeeded = Mail.writeFcc(message,
274: destination, toBeMoved.getFlags()
275: & ~MailboxEntry.TAGGED);
276: } else {
277: session.writeTagged("uid copy "
278: + toBeMoved.getUid() + " "
279: + destination);
280: succeeded = session.getResponse() == ImapSession.OK;
281: }
282: if (succeeded) {
283: session.writeTagged("uid store "
284: + toBeMoved.getUid()
285: + " +flags.silent (\\deleted)");
286: if (session.getResponse() == ImapSession.OK) {
287: toBeMoved.setFlags(toBeMoved.getFlags()
288: | MailboxEntry.DELETED);
289: mailbox.updateEntry(toBeMoved);
290: } else
291: succeeded = false;
292: }
293: session.setEcho(false);
294: if (succeeded) {
295: MailboxEntry nextEntry = mailbox
296: .getNextUndeleted(entry);
297: if (nextEntry != null) {
298: mailbox.setDotEntry(nextEntry);
299: setEntry(nextEntry);
300: loadMessage(null);
301: } else {
302: Runnable messageIndexRunnable = new Runnable() {
303: public void run() {
304: MailCommands
305: .messageIndex(editor);
306: editor
307: .status("Last undeleted message");
308: }
309: };
310: SwingUtilities
311: .invokeLater(messageIndexRunnable);
312: }
313: setBusy(false);
314: editor.updateDisplayLater();
315: } else {
316: setBusy(false);
317: Runnable reportError = new Runnable() {
318: public void run() {
319: editor.updateDisplay();
320: MessageDialog.showMessageDialog(
321: editor, "Operation failed",
322: "Error");
323: }
324: };
325: SwingUtilities.invokeLater(reportError);
326: }
327: }
328: } finally {
329: setBusy(false);
330: mailbox.unlock();
331: }
332: }
333: };
334: setBusy(true);
335: new Thread(moveMessageRunnable).start();
336: }
337: }
|