diff --git a/AUTHORS b/AUTHORS
index 4030bf81..2c964c1d 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -12,6 +12,7 @@ Inactive/former developers:
Patches (in no special order):
* Lukas Mai
+ * Guido Van Hoecke
* Daniel Trstenjak (various things with hints)
* M.Terada (suggest engines)
* Muthu Kannan (ctrl-v support)
diff --git a/Donators b/Donators
index 517856f2..2251e26a 100644
--- a/Donators
+++ b/Donators
@@ -2,6 +2,7 @@
Note: If you don't wish to appear on this list when making a donation, please tell me.
2008:
+* Dotan Cohen
* Daniel Schaffrath
* Sam Griffin
* Ivan Pantuyev
diff --git a/content/completion.js b/content/completion.js
index dc29a52a..053a2364 100644
--- a/content/completion.js
+++ b/content/completion.js
@@ -362,6 +362,24 @@ liberator.Completion = function () //{{{
return [0, buildLongestStartingSubstring(completions, filter)];
},
+ mail: function (filter)
+ {
+ var completions = [];
+ var folders = liberator.mail.getFolders();
+ for (var folder in folders)
+ {
+ completions.push([folders[folder].server.prettyName + ": "
+ + folders[folder].name,
+ "Unread: " + folders[folder].getNumUnread(false)]);
+ }
+ if (!filter)
+ return [0, completions];
+ var mapped = completions.map(function (node) {
+ return [[node[0]], node[1]];
+ });
+ return [0, buildLongestCommonSubstring(mapped, filter)];
+ },
+
option: function (filter, special, unfiltered)
{
substrings = [];
diff --git a/content/mail.js b/content/mail.js
index 243d7a04..0e7c42f6 100644
--- a/content/mail.js
+++ b/content/mail.js
@@ -145,6 +145,58 @@ liberator.Mail = function () //{{{
return parent;
}
+ function selectUnreadFolder(backwards, count)
+ {
+ count = (count > 0 ) ? count : 1;
+ var direction = backwards ? -1 : 1;
+ var tree = GetFolderTree();
+ var c = tree.currentIndex;
+ var i = direction;
+ var folder;
+ while (count > 0 && (c + i) < tree.view.rowCount && (c + i) >= 0)
+ {
+ var resource = GetFolderResource(tree, (c + i)).QueryInterface(Components.interfaces.nsIMsgFolder);
+ if (!resource.isServer && resource.getNumUnread(false))
+ {
+ count -= 1;
+ folder = i;
+ }
+ i += direction;
+ }
+ if (!folder || count > 0)
+ liberator.beep();
+ else
+ tree.view.selection.timedSelect(c + folder, tree._selectDelay);
+ }
+
+ function composeNewMail(args) {
+ var params = Components.classes["@mozilla.org/messengercompose/composeparams;1"]
+ .createInstance(Components.interfaces.nsIMsgComposeParams);
+ params.composeFields = Components.classes["@mozilla.org/messengercompose/composefields;1"]
+ .createInstance(Components.interfaces.nsIMsgCompFields);
+
+ if (args) {
+ if (args.originalMsg)
+ params.originalMsgURI = args.originalMsg;
+ if (args.to)
+ params.composeFields.to = args.to;
+ if (args.cc)
+ params.composeFields.cc = args.cc;
+ if (args.bcc)
+ params.composeFields.bcc = args.bcc;
+ if (args.newsgroups)
+ params.composeFields.newsgroups = args.newsgroups;
+ if (args.subject)
+ params.composeFields.subject = args.subject;
+ }
+
+ params.type = Components.interfaces.nsIMsgCompType.New
+
+ var msgComposeService = Components.classes["@mozilla.org/messengercompose;1"].getService();
+ msgComposeService = msgComposeService.QueryInterface(Components.interfaces.nsIMsgComposeService);
+ msgComposeService.OpenComposeWindowWithParams(null, params);
+ }
+
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// OPTIONS /////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
@@ -198,6 +250,7 @@ liberator.Mail = function () //{{{
function () { return true; },
{ flags: liberator.Mappings.flags.ALLOW_EVENT_ROUTING });
+ // TODO: change to "t" probably
liberator.mappings.add(modes, ["x"],
"Select thread",
function () { gDBView.ExpandAndSelectThreadByIndex(GetThreadTree().currentIndex, false) });
@@ -266,7 +319,20 @@ liberator.Mail = function () //{{{
// SENDING MESSAGES
liberator.mappings.add(modes, ["m"],
"Compose a new message",
- function () { goOpenNewMessage(); });
+ function () { composeNewMail(); });
+
+ liberator.mappings.add(modes, ["M"],
+ "Compose a new message to the sender of selected mail",
+ function ()
+ {
+ try
+ {
+ var args = new Object();
+ args.to = gDBView.hdrForFirstSelectedMessage.mime2DecodedAuthor;
+ composeNewMail(args);
+ }
+ catch (e) { liberator.beep(); }
+ });
liberator.mappings.add(modes, ["r"],
"Reply to sender",
@@ -396,6 +462,14 @@ liberator.Mail = function () //{{{
},
{ flags: liberator.Mappings.flags.COUNT });
+ liberator.mappings.add(modes, [""],
+ "Go to next mailbox with unread messages",
+ function (count)
+ {
+ selectUnreadFolder(false, count)
+ },
+ { flags: liberator.Mappings.flags.COUNT });
+
liberator.mappings.add(modes, [""],
"Select previous folder",
function (count)
@@ -412,6 +486,14 @@ liberator.Mail = function () //{{{
},
{ flags: liberator.Mappings.flags.COUNT });
+ liberator.mappings.add(modes, [""],
+ "Go to previous mailbox with unread messages",
+ function (count)
+ {
+ selectUnreadFolder(true, count)
+ },
+ { flags: liberator.Mappings.flags.COUNT });
+
// THREADING
liberator.mappings.add(modes, ["za"],
"Toggle thread collapsed/expanded",
@@ -526,15 +608,24 @@ liberator.Mail = function () //{{{
liberator.echoerr("Folder \"" + args + "\" does not exist");
else
SelectFolder(folder.URI);
+ },
+ {
+ completer: function (filter) { return liberator.completion.mail(filter); }
});
liberator.commands.add(["copy[to]"],
"Copy selected messages",
- function (args, special) { moveOrCopy(true, args); });
+ function (args, special) { moveOrCopy(true, args); },
+ {
+ completer: function (filter) { return liberator.completion.mail(filter); }
+ });
liberator.commands.add(["move[to]"],
"Move selected messages",
- function (args, special) { moveOrCopy(false, args); });
+ function (args, special) { moveOrCopy(false, args); },
+ {
+ completer: function (filter) { return liberator.completion.mail(filter); }
+ });
liberator.commands.add(["empty[trash]"],
"Empty trash of the current account",
@@ -565,8 +656,8 @@ liberator.Mail = function () //{{{
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
-
- return {
+
+ return {
get currentAccount() { return this.currentFolder.rootFolder; },
@@ -594,8 +685,12 @@ liberator.Mail = function () //{{{
if ((resource.isServer && !includeServers) || (!resource.isServer && !includeMsgFolders))
continue;
+ var folderString = resource.server.prettyName + ": " + resource.name;
+
if (resource.prettiestName.toLowerCase().indexOf(filter.toLowerCase()) >= 0)
folders.push(resource);
+ else if (folderString.toLowerCase().indexOf(filter.toLowerCase()) >= 0)
+ folders.push(resource);
}
return folders;
},