diff --git a/content/addressbook.js b/content/addressbook.js new file mode 100644 index 00000000..d6a8cbe0 --- /dev/null +++ b/content/addressbook.js @@ -0,0 +1,233 @@ +/***** BEGIN LICENSE BLOCK ***** {{{ +Version: MPL 1.1/GPL 2.0/LGPL 2.1 + +The contents of this file are subject to the Mozilla Public License Version +1.1 (the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +for the specific language governing rights and limitations under the +License. + +(c) 2008: Christian Dietrich + +Alternatively, the contents of this file may be used under the terms of +either the GNU General Public License Version 2 or later (the "GPL"), or +the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +in which case the provisions of the GPL or the LGPL are applicable instead +of those above. If you wish to allow use of your version of this file only +under the terms of either the GPL or the LGPL, and not to allow others to +use your version of this file under the terms of the MPL, indicate your +decision by deleting the provisions above and replace them with the notice +and other provisions required by the GPL or the LGPL. If you do not delete +the provisions above, a recipient may use your version of this file under +the terms of any one of the MPL, the GPL or the LGPL. +}}} ***** END LICENSE BLOCK *****/ + +liberator.Addressbook = function () //{{{ +{ + //////////////////////////////////////////////////////////////////////////////// + ////////////////////// PRIVATE SECTION ///////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////{{{ + + const abManager = Components.classes["@mozilla.org/abmanager;1"] + .getService(Components.interfaces.nsIAbManager); + const rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"] + .getService(Components.interfaces.nsIRDFService); + + const kPersonalAddressbookURI = "moz-abmdbdirectory://abook.mab"; + + function load() + { + } + + // TODO: add option for a format specifier, like: + // :set displayname=%l, %f + function generateDisplayName(firstName, lastName) + { + if (firstName && lastName) + return lastName + ", " + firstName; + else if (firstName) + return firstName; + else if (lastName) + return lastName; + else + return ""; + } + + function getDirectoryFromURI(uri) + { + return rdf.GetResource(uri).QueryInterface(Components.interfaces.nsIAbDirectory); + } + + /////////////////////////////////////////////////////////////////////////////}}} + ////////////////////// OPTIONS ///////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////{{{ + + + /////////////////////////////////////////////////////////////////////////////}}} + ////////////////////// MAPPINGS //////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////{{{ + + var modes = liberator.config.mailModes || [liberator.modes.NORMAL]; + + liberator.mappings.add(modes, ["a"], + "Open a prompt to save a new addressbook entry for the sender of the selected message", + function () + { + var to; + try + { + to = gDBView.hdrForFirstSelectedMessage.mime2DecodedAuthor; + } + catch (e) { liberator.echoerr("Exxx: No message is selected");} + + if (!to) + return; + + var address = to.substring(to.indexOf("<") + 1, to.indexOf(">")); + + var displayName = to.substr(0, to.indexOf("<") - 1); + if (/^\S+\s+\S+\s*$/.test(displayName)) + { + var names = displayName.split(/\s+/); + displayName = "-firstname=" + names[0] + " -lastname=" + names[1]; + } + else + { + displayName = "-name=\"" + displayName.replace(/"/g, "") + "\""; + } + + liberator.commandline.open(":", "contact " + address + " " + displayName, liberator.modes.EX); + }); + + /////////////////////////////////////////////////////////////////////////////}}} + ////////////////////// COMMANDS //////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////{{{ + + liberator.commands.add(["con[tact]"], + "Add an address book entry", + function (args) + { + var res = liberator.commands.parseArgs(args, this.args); + if (!res) + return; + + if (res.args.length == 0) + { + liberator.echoerr("E474: Invalid argument") + return; + } + + var mailAddr = res.args[0]; // TODO: support more than one email address + var firstName = liberator.commands.getOption(res.opts, "-firstname", null); + var lastName = liberator.commands.getOption(res.opts, "-lastname", null); + var displayName = liberator.commands.getOption(res.opts, "-name", null); + if (!displayName) + displayName = generateDisplayName(firstName, lastName); + + if (liberator.addressbook.add(mailAddr, firstName, lastName, displayName)) + liberator.echo("Added address: " + displayName + " <" + mailAddr + ">", liberator.commandline.FORCE_SINGLELINE); + else + liberator.echoerr("Exxx: Could not add bookmark `" + mailAddr + "'", liberator.commandline.FORCE_SINGLELINE); + + }, + { + args: [[["-firstname", "-f"], liberator.commands.OPTION_STRING], + [["-lastname", "-l"], liberator.commands.OPTION_STRING], + [["-name", "-n"], liberator.commands.OPTION_STRING]] + }); + + liberator.commands.add(["contacts", "abook"], + "List or open multiple addresses", + function (args, special) { liberator.addressbook.list(args, special); }); + + /////////////////////////////////////////////////////////////////////////////}}} + ////////////////////// PUBLIC SECTION ////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////{{{ + + return { + + add: function(address, firstname, lastname, displayName) + { + var directory = getDirectoryFromURI(kPersonalAddressbookURI); + var card = Components.classes["@mozilla.org/addressbook/cardproperty;1"] + .createInstance(Components.interfaces.nsIAbCard); + + if (!address || !directory || !card) + return false; + + card.primaryEmail = address; + card.firstName = firstname; + card.lastName = lastname; + card.displayName = displayName; + + return directory.addCard(card); + }, + + // TODO: add telephone number support + list: function(filter, newMail) + { + var addresses = []; + var dirs = abManager.directories; + filter = filter.toLowerCase(); + + while (dirs.hasMoreElements()) + { + var addrbook = dirs.getNext().QueryInterface(Components.interfaces.nsIAbDirectory); + var cards = addrbook.childCards; + while(cards.hasMoreElements()) + { + var card = cards.getNext().QueryInterface(Components.interfaces.nsIAbCard); + var mail = card.primaryEmail || ""; + var displayName = card.displayName; + if (!displayName) + displayName = generateDisplayName(card.firstName, card.lastName); + + if (displayName.toLowerCase().indexOf(filter) > -1 + || card.primaryEmail.toLowerCase().indexOf(filter) > -1) + addresses.push([displayName, card.primaryEmail]); + } + } + if (addresses.length < 1) + { + liberator.echoerr("E94: No matching contact for " + args, liberator.commandline.FORCE_SINGLELINE); + return false; + } + + if (newMail) + { + // Now we have to create a new message + var args = new Object(); + args.to = addresses.map(function(address) + { + return "\"" + address[0].replace(/"/g, "") + " <" + address[1] + ">\""; + }).join(", "); + + liberator.mail.composeNewMail(args); + } + else + { + var list = ":" + liberator.util.escapeHTML(liberator.commandline.getCommand()) + "
" + + ""; + for (var i = 0; i < addresses.length; i++) + { + var displayName = liberator.util.escapeHTML(addresses[i][0]); + if (displayName.length > 50) + displayName = displayName.substr(0, 47) + "..."; + var mailAddr = liberator.util.escapeHTML(addresses[i][1]); + list += ""; + } + list += "
NameAddress
" + displayName + "" + mailAddr + "
"; + + liberator.commandline.echo(list, liberator.commandline.HL_NORMAL, liberator.commandline.FORCE_MULTILINE); + } + return true; + } + } + +}; //}}} + +// vim: set fdm=marker sw=4 ts=4 et: diff --git a/content/liberator.js b/content/liberator.js index 04c384b8..c2b84b54 100644 --- a/content/liberator.js +++ b/content/liberator.js @@ -824,6 +824,7 @@ const liberator = (function () //{{{ if (liberator.has("marks")) { log("marks"); liberator.marks = liberator.Marks(); } if (liberator.has("quickmarks")) { log("quickmarks"); liberator.quickmarks = liberator.QuickMarks(); } if (liberator.has("hints")) { log("hints"); liberator.hints = liberator.Hints(); } + if (liberator.has("addressbook") && liberator.Addressbook) { log("addressbook"); liberator.addressbook = liberator.Addressbook(); } liberator.log("All modules loaded", 3); diff --git a/content/mail.js b/content/mail.js index c49cb582..b59fb58b 100644 --- a/content/mail.js +++ b/content/mail.js @@ -175,60 +175,6 @@ liberator.Mail = function () //{{{ recipient = recipient.replace(/"/g, ""); return "\"" + recipient + "\""; } - - 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; - if (args.body) - params.composeFields.body = args.body; - while (args.attachments.length > 0) - { - var url = args.attachments.pop(); - - // Check if the file really exists - var file = Components.classes["@mozilla.org/file/local;1"] - .createInstance(Components.interfaces.nsILocalFile); - file.initWithPath(url); - - if (!file.exists()) - { - liberator.echoerr("Exxx: Could attach file `" + url + "'", liberator.commandline.FORCE_SINGLELINE); - continue; - } - attachment = Components.classes["@mozilla.org/messengercompose/attachment;1"] - .createInstance(Components.interfaces.nsIMsgAttachment); - attachment.url = "file://" + url; - params.composeFields.addAttachment(attachment); - } - - } - - - 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 ///////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////{{{ @@ -679,7 +625,7 @@ liberator.Mail = function () //{{{ mailargs.to = res.args.join(", "); } - composeNewMail(mailargs); + liberator.mail.composeNewMail(mailargs); }, { args: [[["-subject", "-s"], liberator.commands.OPTION_STRING], @@ -743,6 +689,62 @@ liberator.Mail = function () //{{{ QueryInterface(Components.interfaces.nsIMsgFolder); }, + composeNewMail: function (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; + if (args.body) + params.composeFields.body = args.body; + + if (args.attachments) + { + while (args.attachments.length > 0) + { + var url = args.attachments.pop(); + + // Check if the file really exists + var file = Components.classes["@mozilla.org/file/local;1"] + .createInstance(Components.interfaces.nsILocalFile); + file.initWithPath(url); + + if (!file.exists()) + { + liberator.echoerr("Exxx: Could attach file `" + url + "'", liberator.commandline.FORCE_SINGLELINE); + continue; + } + attachment = Components.classes["@mozilla.org/messengercompose/attachment;1"] + .createInstance(Components.interfaces.nsIMsgAttachment); + attachment.url = "file://" + url; + params.composeFields.addAttachment(attachment); + } + } + } + + 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); + }, + + getFolders: function (filter, includeServers, includeMsgFolders) { var folders = []; diff --git a/content/muttator.js b/content/muttator.js index c8cd04f7..6c976b07 100644 --- a/content/muttator.js +++ b/content/muttator.js @@ -32,7 +32,7 @@ liberator.config = { hostApplication: "Thunderbird", // TODO: can this be found out otherwise? gBrandBundle.getString("brandShortName"); /*** optional options, there are checked for existance and a fallback provided ***/ - features: ["hints", "mail", "marks"], + features: ["hints", "mail", "marks", "addressbook"], guioptions: { m: ["mail-toolbar-menubar2"], T: ["mail-bar2"], f: ["folderPaneBox", "folderpane_splitter"], F: ["folderPaneHeader"] }, get browserModes() { return [liberator.modes.MESSAGE]; }, diff --git a/content/muttator.xul b/content/muttator.xul index f041c1be..b503b624 100644 --- a/content/muttator.xul +++ b/content/muttator.xul @@ -40,6 +40,7 @@ the terms of any one of the MPL, the GPL or the LGPL.