bug 373380 Adding initial iTIP invitation support r=lilmatt

This commit is contained in:
ctalbert.moz%gmail.com 2007-03-09 21:59:22 +00:00
Родитель d126ebd815
Коммит 701e2b05d2
4 изменённых файлов: 160 добавлений и 17 удалений

Просмотреть файл

@ -45,6 +45,7 @@ function createEventWithDialog(calendar, startDate, endDate, summary, event)
var onNewEvent = function(event, calendar, originalEvent) { var onNewEvent = function(event, calendar, originalEvent) {
doTransaction('add', event, calendar, null, null); doTransaction('add', event, calendar, null, null);
checkForAttendees(event, originalEvent);
} }
if (event) { if (event) {
@ -105,6 +106,7 @@ function createTodoWithDialog(calendar, dueDate, summary, todo)
var onNewItem = function(item, calendar, originalItem) { var onNewItem = function(item, calendar, originalItem) {
doTransaction('add', item, calendar, null, null); doTransaction('add', item, calendar, null, null);
checkForAttendees(item, originalItem);
} }
if (todo) { if (todo) {
@ -129,6 +131,7 @@ function createTodoWithDialog(calendar, dueDate, summary, todo)
var onNewItem = function(item, calendar, originalItem) { var onNewItem = function(item, calendar, originalItem) {
calendar.addItem(item, null); calendar.addItem(item, null);
checkForAttendees(item, originalItem);
} }
setDefaultAlarmValues(todo); setDefaultAlarmValues(todo);
@ -149,6 +152,7 @@ function modifyEventWithDialog(item, job)
else { else {
doTransaction('move', item, calendar, originalItem, null); doTransaction('move', item, calendar, originalItem, null);
} }
checkForAttendees(item, originalItem);
} }
if (item) { if (item) {
@ -418,3 +422,114 @@ calTransaction.prototype = {
return false; return false;
} }
} }
/**
* checkForAttendees
* Checks to see if the attendees were added or changed between the original
* and new item. If there is a change, it launches the calIITipTransport
* service and sends the invitations
*/
function checkForAttendees(aItem, aOriginalItem)
{
// iTIP is only supported in Lightning right now
if (!gDataMigrator.isLightning) {
return;
}
var sendInvite = false;
var itemAtt = aItem.getAttendees({});
if (itemAtt.length > 0) {
var originalAtt = aOriginalItem.getAttendees({});
if ( (originalAtt.length > 0) &&
(originalAtt.length == itemAtt.length) )
{
for (var i=0; i < itemAtt.length; i++) {
if (originalAtt[i].id != itemAtt[i].id) {
sendInvite = true;
break;
}
}
} else {
// We have attendees on item, not on original, attendees were
// added.
sendInvite = true;
}
}
// XXX Until we rethink attendee support and until such support
// is worked into the event dialog (which has been done in the prototype
// dialog to a degree) then we are going to simply hack in some attendee
// support so that we can round-trip iTIP invitations.
if (sendInvite) {
// Since there is no way to determine the type of transport an
// attendee requires, we default to email
var emlSvc = Components.classes["@mozilla.org/calendar/itip-transport;1?type=email"]
.createInstance(Components.interfaces.calIItipTransport);
var itipItem = Components.classes["@mozilla.org/calendar/itip-item;1"]
.createInstance(Components.interfaces.calIItipItem);
var sbs = Components.classes["@mozilla.org/intl/stringbundle;1"]
.getService(Components.interfaces.nsIStringBundleService);
var sb = sbs.createBundle("chrome://lightning/locale/lightning.properties");
var recipients = [];
// We have to modify our item a little, so we clone it.
var item = aItem.clone();
// Fix up our attendees for invitations using some good defaults
item.removeAllAttendees();
for each (var attendee in itemAtt) {
attendee.role = "REQ-PARTICIPANT";
attendee.participationStatus = "NEEDS-ACTION";
attendee.rsvp = true;
item.addAttendee(attendee);
recipients.push(attendee);
}
// XXX The event dialog has no means to set us as the organizer
// since we defaulted to email above, we know we need to prepend
// mailto when we convert it to an attendee
var organizer = Components.classes["@mozilla.org/calendar/attendee;1"]
.createInstance(Components.interfaces.calIAttendee);
organizer.id = "mailto:" + emlSvc.defaultIdentity;
organizer.role = "REQ-PARTICIPANT";
organizer.participationStatus = "ACCEPTED";
organizer.isOrganizer = true;
// Add our organizer to the item. Again, the event dialog really doesn't
// have a mechanism for creating an item with a method, so let's add
// that too while we're at it. We'll also fake Sequence ID support.
item.organizer = organizer;
item.setProperty("METHOD", "REQUEST");
item.setProperty("SEQUENCE", "1");
var summary
if (item.getProperty("SUMMARY")) {
summary = item.getProperty("SUMMARY");
} else {
summary = "";
}
// Initialize and set our properties on the item
itipItem.init(item.icalString);
itipItem.isSend = true;
itipItem.receivedMethod = "REQUEST";
itipItem.responseMethod = "REQUEST";
itipItem.autoResponse = Components.interfaces.calIItipItem.USER;
// Get ourselves some default text - when we handle organizer properly
// We'll need a way to configure the Common Name attribute and we should
// use it here rather than the email address
var subject = sb.formatStringFromName("itipRequestSubject",
[summary], 1);
var body = sb.formatStringFromName("itipRequestBody",
[emlSvc.defaultIdentity, summary],
2);
// Send it!
emlSvc.sendItems(recipients.length, recipients, subject, body, itipItem);
}
}

Просмотреть файл

@ -67,7 +67,7 @@
&lightning.imipbar.description; &lightning.imipbar.description;
</description> </description>
<spacer flex="1"/> <spacer flex="1"/>
<button id="imip-button1" align="center" pack="end"/> <button id="imip-button1" align="center" pack="end" hidden="true"/>
<button id="imip-button2" align="center" pack="end" hidden="true"/> <button id="imip-button2" align="center" pack="end" hidden="true"/>
</hbox> </hbox>
</hbox> </hbox>

Просмотреть файл

@ -59,7 +59,7 @@ function checkForItipItem()
var sinkProps = msgWindow.msgHeaderSink.properties; var sinkProps = msgWindow.msgHeaderSink.properties;
// This property was set by LightningTextCalendarConverter.js // This property was set by LightningTextCalendarConverter.js
itipItem = sinkProps.getPropertyAsInterface("itipItem", itipItem = sinkProps.getPropertyAsInterface("itipItem",
Components.interfaces.calIItipItem) Components.interfaces.calIItipItem);
} catch (e) { } catch (e) {
// This will throw on every message viewed that doesn't have the // This will throw on every message viewed that doesn't have the
// itipItem property set on it. So we eat the errors and move on. // itipItem property set on it. So we eat the errors and move on.
@ -77,10 +77,14 @@ function checkForItipItem()
itipItem.targetCalendar = getTargetCalendar(); itipItem.targetCalendar = getTargetCalendar();
var imipMethod = getMsgImipMethod(); var imipMethod = getMsgImipMethod();
if (imipMethod.length) { if (imipMethod &&
imipMethod.length != 0 &&
imipMethod.toLowerCase() != "nomethod")
{
itipItem.receivedMethod = imipMethod; itipItem.receivedMethod = imipMethod;
} else { } else {
// Thunderbird 1.5 case, we cannot get the imipMethod // There is no METHOD in the content-type header (spec violation).
// Fall back to using the one from the itipItem's ICS.
imipMethod = itipItem.receivedMethod; imipMethod = itipItem.receivedMethod;
} }
@ -127,6 +131,8 @@ function onImipStartHeaders()
{ {
var imipBar = document.getElementById("imip-bar"); var imipBar = document.getElementById("imip-bar");
imipBar.setAttribute("collapsed", "true"); imipBar.setAttribute("collapsed", "true");
document.getElementById("imip-button1").setAttribute("hidden", "true");
document.getElementById("imip-button2").setAttribute("hidden", "true");
// A new message is starting. // A new message is starting.
// Clear our iMIP/iTIP stuff so it doesn't contain stale information. // Clear our iMIP/iTIP stuff so it doesn't contain stale information.
@ -152,9 +158,12 @@ function setupBar(imipMethod)
var description = document.getElementById("imip-description"); var description = document.getElementById("imip-description");
// Bug 348666: here is where we would check if this event was already // Bug 348666: here is where we would check if this event was already
// added to calendar or not and display correct information here // added to calendar or not and display correct information
if (imipMethod == "REQUEST") {
if (description.firstChild.data) { if (description.firstChild.data) {
description.firstChild.data = ltnGetString("lightning","imipBarText"); description.firstChild.data = ltnGetString("lightning",
"imipBarRequestText");
} }
var button = document.getElementById("imip-button1"); var button = document.getElementById("imip-button1");
@ -164,14 +173,29 @@ function setupBar(imipMethod)
button.setAttribute("oncommand", button.setAttribute("oncommand",
"setAttendeeResponse('ACCEPTED', 'CONFIRMED');"); "setAttendeeResponse('ACCEPTED', 'CONFIRMED');");
if (imipMethod == "REQUEST") { // Create a DECLINE button
// Then create a DECLINE button
button = document.getElementById("imip-button2"); button = document.getElementById("imip-button2");
button.removeAttribute("hidden"); button.removeAttribute("hidden");
button.setAttribute("label", ltnGetString("lightning", button.setAttribute("label", ltnGetString("lightning",
"imipDeclineInvitation.label")); "imipDeclineInvitation.label"));
button.setAttribute("oncommand", button.setAttribute("oncommand",
"setAttendeeResponse('DECLINED', 'CONFIRMED');"); "setAttendeeResponse('DECLINED', 'CONFIRMED');");
} else if (imipMethod == "REPLY") {
// Bug xxxx we currently cannot process REPLY messages so just let
// the user know what this is, and don't give them any options.
if (description.firstChild.data) {
description.firstChild.data = ltnGetString("lightning",
"imipBarReplyText");
}
} else {
// Bug xxxx TBD: Something went wrong or we found a message we don't
// support yet. We can show a "This method is not supported in this
// version" or simply hide the iMIP bar at this point
if (description.firstChild.data) {
description.firstChild.data = ltnGetString("lightning",
"imipBarUnsupportedText");
}
Components.utils.reportError("Unknown imipMethod: " + imipMethod);
} }
} }

Просмотреть файл

@ -55,10 +55,14 @@ imipHtml.description=Description:
imipAddToCalendar.label=Add To Calendar imipAddToCalendar.label=Add To Calendar
imipAddedItemToCal=Event Added to Calendar imipAddedItemToCal=Event Added to Calendar
imipBarText=This message contains an invitation to an event. imipBarRequestText=This message contains an invitation to an event.
imipBarReplyText=This message contains a reply to an invitation.
imipBarUnsupportedText=This message contains an event that this version of Lightning cannot process.
imipAcceptInvitation.label=Accept imipAcceptInvitation.label=Accept
imipDeclineInvitation.label=Decline imipDeclineInvitation.label=Decline
itipReplySubject=Event Invitation Reply: %1$S itipReplySubject=Event Invitation Reply: %1$S
itipReplyBodyAccept=%1$S has accepted your event invitation. itipReplyBodyAccept=%1$S has accepted your event invitation.
itipReplyBodyDecline=%1$S has declined your event invitation. itipReplyBodyDecline=%1$S has declined your event invitation.
itipRequestSubject=Event Invitation: %1$S
itipRequestBody=%1$S has invited you to %2$S