Fix bug 404900 - Add Accept/Decline to Calendar item's context menu. r=nomisvai
--HG-- extra : rebase_source : 3cac4e9ff5faccf93fa76b2191d7d78edd909882
This commit is contained in:
Родитель
fe079f7571
Коммит
34118039b9
|
@ -99,6 +99,8 @@ var calendarController = {
|
||||||
"calendar_general-progress_command": true,
|
"calendar_general-progress_command": true,
|
||||||
"calendar_task_category_command": true,
|
"calendar_task_category_command": true,
|
||||||
|
|
||||||
|
"calendar_attendance_command": true,
|
||||||
|
|
||||||
// Pseudo commands
|
// Pseudo commands
|
||||||
"calendar_in_foreground": true,
|
"calendar_in_foreground": true,
|
||||||
"calendar_in_background": true,
|
"calendar_in_background": true,
|
||||||
|
@ -185,6 +187,13 @@ var calendarController = {
|
||||||
case "calendar_reload_remote_calendar":
|
case "calendar_reload_remote_calendar":
|
||||||
return !this.no_network_calendars && !this.offline;
|
return !this.no_network_calendars && !this.offline;
|
||||||
|
|
||||||
|
case "calendar_attendance_command":
|
||||||
|
// Small hack, we want to hide instead of disable.
|
||||||
|
let attendSel = this.item_selected && this.selected_events_invitation;
|
||||||
|
setBooleanAttribute("calendar_attendance_command", "hidden", !attendSel);
|
||||||
|
return attendSel;
|
||||||
|
break;
|
||||||
|
|
||||||
// The following commands all just need the calendar in foreground,
|
// The following commands all just need the calendar in foreground,
|
||||||
// make sure you take care when changing things here.
|
// make sure you take care when changing things here.
|
||||||
case "calendar_view_next_command":
|
case "calendar_view_next_command":
|
||||||
|
@ -387,6 +396,9 @@ var calendarController = {
|
||||||
case "calendar_month-view_command":
|
case "calendar_month-view_command":
|
||||||
switchCalendarView("month", true);
|
switchCalendarView("month", true);
|
||||||
break;
|
break;
|
||||||
|
case "calendar_attendance_command":
|
||||||
|
// This command is actually handled inline, since it takes a value
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (this.defaultController && !this.isCalendarInForeground()) {
|
if (this.defaultController && !this.isCalendarInForeground()) {
|
||||||
|
@ -425,9 +437,11 @@ var calendarController = {
|
||||||
var selectedItems = aEvent.detail;
|
var selectedItems = aEvent.detail;
|
||||||
calendarController.item_selected = selectedItems && (selectedItems.length > 0);
|
calendarController.item_selected = selectedItems && (selectedItems.length > 0);
|
||||||
|
|
||||||
var selLength = (selectedItems === undefined ? 0 : selectedItems.length);
|
let selLength = (selectedItems === undefined ? 0 : selectedItems.length);
|
||||||
var selected_events_readonly = 0;
|
let selected_events_readonly = 0;
|
||||||
var selected_events_requires_network = 0;
|
let selected_events_requires_network = 0;
|
||||||
|
let selected_events_invitation = 0;
|
||||||
|
|
||||||
if (selLength > 0) {
|
if (selLength > 0) {
|
||||||
for each (var item in selectedItems) {
|
for each (var item in selectedItems) {
|
||||||
if (item.calendar.readOnly) {
|
if (item.calendar.readOnly) {
|
||||||
|
@ -436,6 +450,17 @@ var calendarController = {
|
||||||
if (item.calendar.getProperty("requiresNetwork")) {
|
if (item.calendar.getProperty("requiresNetwork")) {
|
||||||
selected_events_requires_network++;
|
selected_events_requires_network++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cal.isInvitation(item)) {
|
||||||
|
selected_events_invitation++;
|
||||||
|
} else if (item.organizer) {
|
||||||
|
// If we are the organizer and there are attendees, then
|
||||||
|
// this is likely also an invitation.
|
||||||
|
let calOrgId = item.calendar.getProperty("organizerId");
|
||||||
|
if (item.organizer.id == calOrgId && item.getAttendees({}).length) {
|
||||||
|
selected_events_invitation++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,6 +469,9 @@ var calendarController = {
|
||||||
|
|
||||||
calendarController.selected_events_requires_network =
|
calendarController.selected_events_requires_network =
|
||||||
(selected_events_requires_network == selLength);
|
(selected_events_requires_network == selLength);
|
||||||
|
calendarController.selected_events_invitation =
|
||||||
|
(selected_events_invitation == selLength);
|
||||||
|
|
||||||
calendarController.updateCommands();
|
calendarController.updateCommands();
|
||||||
calendarController2.updateCommands();
|
calendarController2.updateCommands();
|
||||||
if(!isSunbird()) {
|
if(!isSunbird()) {
|
||||||
|
@ -459,6 +487,7 @@ var calendarController = {
|
||||||
item_selected: false,
|
item_selected: false,
|
||||||
selected_events_readonly: false,
|
selected_events_readonly: false,
|
||||||
selected_events_requires_network: false,
|
selected_events_requires_network: false,
|
||||||
|
selected_events_invitation: false,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a boolean indicating if its possible to write items to any
|
* Returns a boolean indicating if its possible to write items to any
|
||||||
|
@ -782,6 +811,40 @@ function setupContextItemType(event, items) {
|
||||||
event.target.removeAttribute("type");
|
event.target.removeAttribute("type");
|
||||||
adaptModificationMenuItem("calendar-item-context-menu-delete-menuitem", "Item");
|
adaptModificationMenuItem("calendar-item-context-menu-delete-menuitem", "Item");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let menu = document.getElementById("calendar-item-context-menu-attendance-menu");
|
||||||
|
let allSingle = items.every(function(x) !x.recurrenceId);
|
||||||
|
setElementValue(menu, allSingle ? "single" : "recurring", "itemType");
|
||||||
|
|
||||||
|
// Set up the attendance menu
|
||||||
|
function getInvStat(item) {
|
||||||
|
let attendee = null;
|
||||||
|
if (cal.isInvitation(item)) {
|
||||||
|
attendee = cal.getInvitedAttendee(item);
|
||||||
|
} else if (item.organizer) {
|
||||||
|
let calOrgId = item.calendar.getProperty("organizerId");
|
||||||
|
if (calOrgId == item.organizer.id && item.getAttendees({}).length) {
|
||||||
|
attendee = item.organizer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return attendee && attendee.participationStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
let firstStatusOccurrences = items.length && getInvStat(items[0]);
|
||||||
|
let firstStatusParents = items.length && getInvStat(items[0].parentItem);
|
||||||
|
let sameStatusOccurrences = items.every(function (x) getInvStat(x) == firstStatusOccurrences);
|
||||||
|
let sameStatusParents = items.every(function (x) getInvStat(x.parentItem) == firstStatusParents)
|
||||||
|
|
||||||
|
let occurrenceChildren = menu.getElementsByAttribute("value", firstStatusOccurrences);
|
||||||
|
let parentsChildren = menu.getElementsByAttribute("value", firstStatusParents);
|
||||||
|
if (sameStatusOccurrences && occurrenceChildren[0]) {
|
||||||
|
occurrenceChildren[0].setAttribute("checked", "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sameStatusParents && parentsChildren[1]) {
|
||||||
|
parentsChildren[1].setAttribute("checked", "true");
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,8 @@
|
||||||
<!-- These commands are enabled when in calendar or task mode, respectively -->
|
<!-- These commands are enabled when in calendar or task mode, respectively -->
|
||||||
<command id="calendar_mode_calendar"/>
|
<command id="calendar_mode_calendar"/>
|
||||||
<command id="calendar_mode_task"/>
|
<command id="calendar_mode_task"/>
|
||||||
|
|
||||||
|
<command id="calendar_attendance_command"/>
|
||||||
</commandset>
|
</commandset>
|
||||||
|
|
||||||
<keyset id="calendar-keys">
|
<keyset id="calendar-keys">
|
||||||
|
@ -240,6 +242,62 @@
|
||||||
<menuitem id="calendar-item-context-menu-delete-menuitem"
|
<menuitem id="calendar-item-context-menu-delete-menuitem"
|
||||||
key="calendar-delete-item-key"
|
key="calendar-delete-item-key"
|
||||||
observes="calendar_delete_event_command"/>
|
observes="calendar_delete_event_command"/>
|
||||||
|
<menu id="calendar-item-context-menu-attendance-menu"
|
||||||
|
label="&calendar.context.attendance.menu.label;"
|
||||||
|
accesskey="&calendar.context.attendance.menu.accesskey;"
|
||||||
|
oncommand="setContextPartstat(event.target.value, event.target.getAttribute('scope'), currentView().getSelectedItems({}))"
|
||||||
|
observes="calendar_attendance_command">
|
||||||
|
<menupopup id="calendar-item-context-menu-attendance-menupopup">
|
||||||
|
<label id="calendar-item-context-attendance-thisoccurrence-label"
|
||||||
|
class="calendar-context-heading-label"
|
||||||
|
scope="all-occurrences"
|
||||||
|
value="&calendar.context.attendance.occurrence.label;"/>
|
||||||
|
<menuitem id="calendar-item-context-menu-attend-accept-menuitem"
|
||||||
|
type="radio"
|
||||||
|
scope="this-occurrence"
|
||||||
|
name="calendar-item-context-attendance"
|
||||||
|
label="&read.only.accept.label;" value="ACCEPTED"/>
|
||||||
|
<menuitem id="calendar-item-context-menu-attend-tentative-menuitem"
|
||||||
|
type="radio"
|
||||||
|
scope="this-occurrence"
|
||||||
|
name="calendar-item-context-attendance"
|
||||||
|
label="&read.only.tentative.label;" value="TENTATIVE"/>
|
||||||
|
<menuitem id="calendar-item-context-menu-attend-declined-menuitem"
|
||||||
|
type="radio"
|
||||||
|
scope="this-occurrence"
|
||||||
|
name="calendar-item-context-attendance"
|
||||||
|
label="&read.only.decline.label;" value="DECLINED"/>
|
||||||
|
<menuitem id="calendar-item-context-menu-attend-needsaction-menuitem"
|
||||||
|
type="radio"
|
||||||
|
scope="this-occurrence"
|
||||||
|
name="calendar-item-context-attendance"
|
||||||
|
label="&read.only.needs.action.label;" value="NEEDS-ACTION"/>
|
||||||
|
<label id="calendar-item-context-attendance-alloccurrence-label"
|
||||||
|
class="calendar-context-heading-label"
|
||||||
|
scope="all-occurrences"
|
||||||
|
value="&calendar.context.attendance.all.label;"/>
|
||||||
|
<menuitem id="calendar-item-context-menu-attend-accept-all-menuitem"
|
||||||
|
type="radio"
|
||||||
|
scope="all-occurrences"
|
||||||
|
name="calendar-item-context-attendance-all"
|
||||||
|
label="&read.only.accept.label;" value="ACCEPTED"/>
|
||||||
|
<menuitem id="calendar-item-context-menu-attend-tentative-all-menuitem"
|
||||||
|
type="radio"
|
||||||
|
scope="all-occurrences"
|
||||||
|
name="calendar-item-context-attendance-all"
|
||||||
|
label="&read.only.tentative.label;" value="TENTATIVE"/>
|
||||||
|
<menuitem id="calendar-item-context-menu-attend-declined-all-menuitem"
|
||||||
|
type="radio"
|
||||||
|
scope="all-occurrences"
|
||||||
|
name="calendar-item-context-attendance-all"
|
||||||
|
label="&read.only.decline.label;" value="DECLINED"/>
|
||||||
|
<menuitem id="calendar-item-context-menu-attend-needsaction-all-menuitem"
|
||||||
|
type="radio"
|
||||||
|
scope="all-occurrences"
|
||||||
|
name="calendar-item-context-attendance-all"
|
||||||
|
label="&read.only.needs.action.label;" value="NEEDS-ACTION"/>
|
||||||
|
</menupopup>
|
||||||
|
</menu>
|
||||||
</menupopup>
|
</menupopup>
|
||||||
|
|
||||||
<!-- CALENDAR VIEW CONTEXT MENU -->
|
<!-- CALENDAR VIEW CONTEXT MENU -->
|
||||||
|
|
|
@ -491,3 +491,44 @@ function updateUndoRedoMenu() {
|
||||||
goUpdateCommand("cmd_undo");
|
goUpdateCommand("cmd_undo");
|
||||||
goUpdateCommand("cmd_redo");
|
goUpdateCommand("cmd_redo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setContextPartstat(value, scope, items) {
|
||||||
|
startBatchTransaction();
|
||||||
|
try {
|
||||||
|
for each (let oldItem in items) {
|
||||||
|
if (scope == "all-occurrences") {
|
||||||
|
oldItem = oldItem.parentItem;
|
||||||
|
}
|
||||||
|
let attendee = null;
|
||||||
|
if (cal.isInvitation(oldItem)) {
|
||||||
|
// Check for the invited attendee first, this is more important
|
||||||
|
attendee = cal.getInvitedAttendee(oldItem);
|
||||||
|
} else if (oldItem.organizer && oldItem.getAttendees({}).length) {
|
||||||
|
// Now check the organizer. This should be done last.
|
||||||
|
let calOrgId = oldItem.calendar.getProperty("organizerId");
|
||||||
|
if (calOrgId == oldItem.organizer.id) {
|
||||||
|
attendee = oldItem.organizer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attendee) {
|
||||||
|
let newItem = oldItem.clone();
|
||||||
|
let newAttendee = attendee.clone();
|
||||||
|
|
||||||
|
newAttendee.participationStatus = value;
|
||||||
|
if (newAttendee.isOrganizer) {
|
||||||
|
newItem.organizer = newAttendee;
|
||||||
|
} else {
|
||||||
|
newItem.removeAttendee(attendee);
|
||||||
|
newItem.addAttendee(newAttendee);
|
||||||
|
}
|
||||||
|
|
||||||
|
doTransaction('modify', newItem, newItem.calendar, oldItem, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
cal.ERROR("Error settinge partstat: " + e);
|
||||||
|
} finally {
|
||||||
|
endBatchTransaction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1142,7 +1142,9 @@
|
||||||
<handlers>
|
<handlers>
|
||||||
<handler event="select"><![CDATA[
|
<handler event="select"><![CDATA[
|
||||||
this.mTreeView.onSelect(event);
|
this.mTreeView.onSelect(event);
|
||||||
|
if (calendarController.todo_tasktree_focused) {
|
||||||
calendarController.onSelectionChanged({detail:this.selectedTasks});
|
calendarController.onSelectionChanged({detail:this.selectedTasks});
|
||||||
|
}
|
||||||
]]></handler>
|
]]></handler>
|
||||||
<handler event="dblclick" button="0"><![CDATA[
|
<handler event="dblclick" button="0"><![CDATA[
|
||||||
this.mTreeView.onDoubleClick(event);
|
this.mTreeView.onDoubleClick(event);
|
||||||
|
|
|
@ -650,6 +650,14 @@ description.tooltipBody {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#calendar-item-context-menu-attendance-menu[itemType="single"] > menupopup > *[scope="all-occurrences"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-context-heading-label {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
calendar-event-box,
|
calendar-event-box,
|
||||||
calendar-editable-item,
|
calendar-editable-item,
|
||||||
calendar-month-day-box-item {
|
calendar-month-day-box-item {
|
||||||
|
|
|
@ -650,6 +650,14 @@ description.tooltipBody {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#calendar-item-context-menu-attendance-menu[itemType="single"] > menupopup > *[scope="all-occurrences"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-context-heading-label {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
calendar-event-box,
|
calendar-event-box,
|
||||||
calendar-editable-item,
|
calendar-editable-item,
|
||||||
calendar-month-day-box-item {
|
calendar-month-day-box-item {
|
||||||
|
|
|
@ -203,6 +203,10 @@
|
||||||
<!ENTITY calendar.context.pasteevent.accesskey "P">
|
<!ENTITY calendar.context.pasteevent.accesskey "P">
|
||||||
<!ENTITY calendar.context.button.label "Today Pane" >
|
<!ENTITY calendar.context.button.label "Today Pane" >
|
||||||
<!ENTITY calendar.context.button.accesskey "T" >
|
<!ENTITY calendar.context.button.accesskey "T" >
|
||||||
|
<!ENTITY calendar.context.attendance.menu.label "Attendance" >
|
||||||
|
<!ENTITY calendar.context.attendance.menu.accesskey "d" >
|
||||||
|
<!ENTITY calendar.context.attendance.occurrence.label "This Occurrence" >
|
||||||
|
<!ENTITY calendar.context.attendance.all.label "All Occurrences" >
|
||||||
|
|
||||||
<!-- Task Context Menu -->
|
<!-- Task Context Menu -->
|
||||||
<!ENTITY calendar.context.progress.label "Progress">
|
<!ENTITY calendar.context.progress.label "Progress">
|
||||||
|
|
Загрузка…
Ссылка в новой задаче