See Changelog.

Monotone-Parent: ec27e211a136eb2c027f25a8a76edcf5638731f5
Monotone-Revision: ed9155f6c31847d4a5dcf861ed08dfb9bb7b112a

Monotone-Author: flachapelle@inverse.ca
Monotone-Date: 2010-10-13T15:02:39
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Francis Lachapelle 2010-10-13 15:02:39 +00:00
parent 28f8f5a36a
commit bb18132951
8 changed files with 182 additions and 107 deletions

View File

@ -1,3 +1,19 @@
2010-10-13 Francis Lachapelle <flachapelle@inverse.ca>
* UI/Scheduler/NSArray+Scheduler.h: added index constants for
events fields.
(compareEventsCalendarNameAscending): new method to sort by
calendar name.
* UI/Scheduler/UIxCalListingActions.m: now uses the above
mentioned constants.
(+initialize): added calendar name to events fields.
(eventsListAction): added sort by calendar name.
* UI/WebServerResources/SchedulerUI.js (eventsListCallback): added
calendar name column.
(onCalendarSelectEvent): improved list selection.
2010-10-13 Wolfgang Sourdeau <wsourdeau@inverse.ca> 2010-10-13 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* SoObjects/Mailer/SOGoMailBaseObject.m (-imap4Connection): split * SoObjects/Mailer/SOGoMailBaseObject.m (-imap4Connection): split

View File

@ -1,6 +1,6 @@
/* NSArray+Scheduler.m - this file is part of SOGo /* NSArray+Scheduler.m - this file is part of SOGo
* *
* Copyright (C) 2007 Inverse inc. * Copyright (C) 2007-2010 Inverse inc.
* *
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca> * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
@ -25,12 +25,36 @@
#import <Foundation/NSArray.h> #import <Foundation/NSArray.h>
// See [UIxCalListingActions initialize]
#define eventNameIndex 0
#define eventFolderIndex 1
#define eventCalendarNameIndex 2
#define eventStatusIndex 3
#define eventTitleIndex 4
#define eventStartDateIndex 5
#define eventEndDateIndex 6
#define eventLocationIndex 7
#define eventIsAllDayIndex 8
#define eventClassificationIndex 9
#define eventCategoryIndex 10
#define eventPartMailsIndex 11
#define eventPartStatesIndex 12
#define eventOwnerIndex 13
#define eventIsCycleIndex 14
#define eventNextAlarmIndex 15
#define eventRecurrenceIdIndex 16
#define eventIsExceptionIndex 17
#define eventEditableIndex 18
#define eventErasableIndex 19
#define eventOwnerIsOrganizerIndex 20
@interface NSArray (SOGoEventComparison) @interface NSArray (SOGoEventComparison)
- (NSComparisonResult) compareEventsStartDateAscending: (NSArray *) otherEvent; - (NSComparisonResult) compareEventsStartDateAscending: (NSArray *) otherEvent;
- (NSComparisonResult) compareEventsEndDateAscending: (NSArray *) otherEvent; - (NSComparisonResult) compareEventsEndDateAscending: (NSArray *) otherEvent;
- (NSComparisonResult) compareEventsTitleAscending: (NSArray *) otherEvent; - (NSComparisonResult) compareEventsTitleAscending: (NSArray *) otherEvent;
- (NSComparisonResult) compareEventsLocationAscending: (NSArray *) otherEvent; - (NSComparisonResult) compareEventsLocationAscending: (NSArray *) otherEvent;
- (NSComparisonResult) compareEventsCalendarNameAscending: (NSArray *) otherEvent;
- (NSComparisonResult) compareTasksAscending: (NSArray *) otherTask; - (NSComparisonResult) compareTasksAscending: (NSArray *) otherTask;
- (NSArray *) reversedArray; - (NSArray *) reversedArray;

View File

@ -55,8 +55,8 @@
NSComparisonResult result; NSComparisonResult result;
unsigned int selfTime, otherTime; unsigned int selfTime, otherTime;
selfTime = [[self objectAtIndex: 4] intValue]; selfTime = [[self objectAtIndex: eventStartDateIndex] intValue];
otherTime = [[otherEvent objectAtIndex: 4] intValue]; otherTime = [[otherEvent objectAtIndex: eventStartDateIndex] intValue];
if (selfTime > otherTime) if (selfTime > otherTime)
result = NSOrderedDescending; result = NSOrderedDescending;
else if (selfTime < otherTime) else if (selfTime < otherTime)
@ -72,8 +72,8 @@
NSComparisonResult result; NSComparisonResult result;
unsigned int selfTime, otherTime; unsigned int selfTime, otherTime;
selfTime = [[self objectAtIndex: 5] intValue]; selfTime = [[self objectAtIndex: eventEndDateIndex] intValue];
otherTime = [[otherEvent objectAtIndex: 5] intValue]; otherTime = [[otherEvent objectAtIndex: eventEndDateIndex] intValue];
if (selfTime > otherTime) if (selfTime > otherTime)
result = NSOrderedDescending; result = NSOrderedDescending;
else if (selfTime < otherTime) else if (selfTime < otherTime)
@ -88,8 +88,8 @@
{ {
NSString *selfTitle, *otherTitle; NSString *selfTitle, *otherTitle;
selfTitle = [self objectAtIndex: 3]; selfTitle = [self objectAtIndex: eventTitleIndex];
otherTitle = [otherEvent objectAtIndex: 3]; otherTitle = [otherEvent objectAtIndex: eventTitleIndex];
return [selfTitle caseInsensitiveCompare: otherTitle]; return [selfTitle caseInsensitiveCompare: otherTitle];
} }
@ -98,12 +98,22 @@
{ {
NSString *selfTitle, *otherTitle; NSString *selfTitle, *otherTitle;
selfTitle = [self objectAtIndex: 6]; selfTitle = [self objectAtIndex: eventLocationIndex];
otherTitle = [otherEvent objectAtIndex: 6]; otherTitle = [otherEvent objectAtIndex: eventLocationIndex];
return [selfTitle caseInsensitiveCompare: otherTitle]; return [selfTitle caseInsensitiveCompare: otherTitle];
} }
- (NSComparisonResult) compareEventsCalendarNameAscending: (NSArray *) otherEvent
{
NSString *selfCalendarName, *otherCalendarName;
selfCalendarName = [self objectAtIndex: eventCalendarNameIndex];
otherCalendarName = [otherEvent objectAtIndex: eventCalendarNameIndex];
return [selfCalendarName caseInsensitiveCompare: otherCalendarName];
}
- (NSComparisonResult) compareTasksAscending: (NSArray *) otherTask - (NSComparisonResult) compareTasksAscending: (NSArray *) otherTask
{ {
NSComparisonResult result; NSComparisonResult result;

View File

@ -80,6 +80,7 @@ static NSArray *tasksFields = nil;
if (!eventsFields) if (!eventsFields)
{ {
eventsFields = [NSArray arrayWithObjects: @"c_name", @"c_folder", eventsFields = [NSArray arrayWithObjects: @"c_name", @"c_folder",
@"calendarName",
@"c_status", @"c_title", @"c_startdate", @"c_status", @"c_title", @"c_startdate",
@"c_enddate", @"c_location", @"c_isallday", @"c_enddate", @"c_location", @"c_isallday",
@"c_classification", @"c_category", @"c_classification", @"c_category",
@ -368,6 +369,8 @@ static NSArray *tasksFields = nil;
forKey: @"c_folder"]; forKey: @"c_folder"];
[newInfo setObject: [currentFolder ownerInContext: context] [newInfo setObject: [currentFolder ownerInContext: context]
forKey: @"c_owner"]; forKey: @"c_owner"];
[newInfo setObject: [currentFolder displayName]
forKey: @"calendarName"];
if (![[newInfo objectForKey: @"c_title"] length]) if (![[newInfo objectForKey: @"c_title"] length])
[self _fixComponentTitle: newInfo withType: component]; [self _fixComponentTitle: newInfo withType: component];
// Possible improvement: only call _fixDates if event is recurrent // Possible improvement: only call _fixDates if event is recurrent
@ -510,13 +513,13 @@ static NSArray *tasksFields = nil;
while ((oldEvent = [events nextObject])) while ((oldEvent = [events nextObject]))
{ {
newEvent = [NSMutableArray arrayWithArray: oldEvent]; newEvent = [NSMutableArray arrayWithArray: oldEvent];
isAllDay = [[oldEvent objectAtIndex: 7] boolValue]; isAllDay = [[oldEvent objectAtIndex: eventIsAllDayIndex] boolValue];
interval = [[oldEvent objectAtIndex: 4] intValue]; interval = [[oldEvent objectAtIndex: eventStartDateIndex] intValue];
[newEvent addObject: [self _formattedDateForSeconds: interval [newEvent addObject: [self _formattedDateForSeconds: interval
forAllDay: isAllDay]]; forAllDay: isAllDay]];
interval = [[oldEvent objectAtIndex: 5] intValue]; interval = [[oldEvent objectAtIndex: eventEndDateIndex] intValue];
[newEvent addObject: [self _formattedDateForSeconds: interval [newEvent addObject: [self _formattedDateForSeconds: interval
forAllDay: isAllDay]]; forAllDay: isAllDay]];
[newEvents addObject: newEvent]; [newEvents addObject: newEvent];
} }
@ -527,6 +530,8 @@ static NSArray *tasksFields = nil;
[newEvents sortUsingSelector: @selector (compareEventsEndDateAscending:)]; [newEvents sortUsingSelector: @selector (compareEventsEndDateAscending:)];
else if ([sort isEqualToString: @"location"]) else if ([sort isEqualToString: @"location"])
[newEvents sortUsingSelector: @selector (compareEventsLocationAscending:)]; [newEvents sortUsingSelector: @selector (compareEventsLocationAscending:)];
else if ([sort isEqualToString: @"calendar"])
[newEvents sortUsingSelector: @selector (compareEventsCalendarNameAscending:)];
else else
[newEvents sortUsingSelector: @selector (compareEventsStartDateAscending:)]; [newEvents sortUsingSelector: @selector (compareEventsStartDateAscending:)];
@ -616,8 +621,8 @@ _userStateInEvent (NSArray *event)
participants = nil; participants = nil;
state = iCalPersonPartStatOther; state = iCalPersonPartStatOther;
partList = [event objectAtIndex: 10]; partList = [event objectAtIndex: eventPartMailsIndex];
stateList = [event objectAtIndex: 11]; stateList = [event objectAtIndex: eventPartStatesIndex];
if ([partList length] && [stateList length]) if ([partList length] && [stateList length])
{ {
participants = [partList componentsSeparatedByString: @"\n"]; participants = [partList componentsSeparatedByString: @"\n"];
@ -626,7 +631,7 @@ _userStateInEvent (NSArray *event)
max = [participants count]; max = [participants count];
while (state == iCalPersonPartStatOther && count < max) while (state == iCalPersonPartStatOther && count < max)
{ {
user = [SOGoUser userWithLogin: [event objectAtIndex: 12] user = [SOGoUser userWithLogin: [event objectAtIndex: eventOwnerIndex]
roles: nil]; roles: nil];
if ([user hasEmail: [participants objectAtIndex: count]]) if ([user hasEmail: [participants objectAtIndex: count]])
state = [[states objectAtIndex: count] intValue]; state = [[states objectAtIndex: count] intValue];
@ -648,16 +653,16 @@ _userStateInEvent (NSArray *event)
NSMutableDictionary *eventBlock; NSMutableDictionary *eventBlock;
iCalPersonPartStat userState; iCalPersonPartStat userState;
eventStart = [[event objectAtIndex: 4] intValue]; eventStart = [[event objectAtIndex: eventStartDateIndex] intValue];
if (eventStart < 0) if (eventStart < 0)
[self errorWithFormat: @"event '%@' has negative start: %d (skipped)", [self errorWithFormat: @"event '%@' has negative start: %d (skipped)",
[event objectAtIndex: 0], eventStart]; [event objectAtIndex: eventNameIndex], eventStart];
else else
{ {
eventEnd = [[event objectAtIndex: 5] intValue]; eventEnd = [[event objectAtIndex: eventEndDateIndex] intValue];
if (eventEnd < 0) if (eventEnd < 0)
[self errorWithFormat: @"event '%@' has negative end: %d (skipped)", [self errorWithFormat: @"event '%@' has negative end: %d (skipped)",
[event objectAtIndex: 0], eventEnd]; [event objectAtIndex: eventNameIndex], eventEnd];
else else
{ {
if (eventEnd < eventStart) if (eventEnd < eventStart)
@ -666,14 +671,14 @@ _userStateInEvent (NSArray *event)
eventStart = eventEnd; eventStart = eventEnd;
eventEnd = swap; eventEnd = swap;
[self warnWithFormat: @"event '%@' has end < start: %d < %d", [self warnWithFormat: @"event '%@' has end < start: %d < %d",
[event objectAtIndex: 0], eventEnd, eventStart]; [event objectAtIndex: eventNameIndex], eventEnd, eventStart];
} }
startSecs = (unsigned int) [startDate timeIntervalSince1970]; startSecs = (unsigned int) [startDate timeIntervalSince1970];
endsSecs = (unsigned int) [endDate timeIntervalSince1970]; endsSecs = (unsigned int) [endDate timeIntervalSince1970];
if ([[event objectAtIndex: 13] boolValue]) // c_iscycle if ([[event objectAtIndex: eventIsCycleIndex] boolValue])
recurrenceTime = [[event objectAtIndex: 15] unsignedIntValue]; // c_recurrence_id recurrenceTime = [[event objectAtIndex: eventRecurrenceIdIndex] unsignedIntValue];
else else
recurrenceTime = 0; recurrenceTime = 0;
@ -689,7 +694,7 @@ _userStateInEvent (NSArray *event)
if (offset >= [blocks count]) if (offset >= [blocks count])
[self errorWithFormat: "event '%@' has a computed offset that" [self errorWithFormat: "event '%@' has a computed offset that"
@" overflows the amount of blocks (skipped)", @" overflows the amount of blocks (skipped)",
[event objectAtIndex: 0]]; [event objectAtIndex: eventNameIndex]];
else else
{ {
currentDay = [blocks objectAtIndex: offset]; currentDay = [blocks objectAtIndex: offset];
@ -955,7 +960,7 @@ _computeBlocksPosition (NSArray *blocks)
{ {
event = [events objectAtIndex: count]; event = [events objectAtIndex: count];
eventNbr = [NSNumber numberWithUnsignedInt: count]; eventNbr = [NSNumber numberWithUnsignedInt: count];
isAllDay = [[event objectAtIndex: 7] boolValue]; isAllDay = [[event objectAtIndex: eventIsAllDayIndex] boolValue];
if (dayBasedView && isAllDay) if (dayBasedView && isAllDay)
[self _fillBlocks: allDayBlocks withEvent: event withNumber: eventNbr]; [self _fillBlocks: allDayBlocks withEvent: event withNumber: eventNbr];
else else

View File

@ -168,6 +168,7 @@
<td id="startHeader" class="headerCell headerDateTime sortableTableHeader"><var:string label:value="Start"/></td> <td id="startHeader" class="headerCell headerDateTime sortableTableHeader"><var:string label:value="Start"/></td>
<td id="endHeader" class="headerCell headerDateTime sortableTableHeader"><var:string label:value="End"/></td> <td id="endHeader" class="headerCell headerDateTime sortableTableHeader"><var:string label:value="End"/></td>
<td id="locationHeader" class="headerCell headerLocation sortableTableHeader"><var:string label:value="Location"/></td> <td id="locationHeader" class="headerCell headerLocation sortableTableHeader"><var:string label:value="Location"/></td>
<td id="calendarNameHeader" class="headerCell headerCalendarName sortableTableHeader"><var:string label:value="Calendar"/></td>
</tr> </tr>
</thead> </thead>
<tbody><!-- events list --></tbody> <tbody><!-- events list --></tbody>

View File

@ -1318,7 +1318,7 @@ DIV.gradient > IMG
min-height: 15px; /* for 15-minute events */ min-height: 15px; /* for 15-minute events */
width: 100%; } width: 100%; }
DIV.text SPAN DIV.text SPAN.icons
{ float: right; } { float: right; }
DIV.text SPAN IMG DIV.text SPAN IMG

View File

@ -218,7 +218,7 @@ function deleteEvent() {
var sortedNodes = []; var sortedNodes = [];
var calendars = []; var calendars = [];
for (var i = 0; i < nodes.length; i++) { for (var i = 0; i < nodes.length; i++) {
canDelete = nodes[i].erasable || IsSuperUser; canDelete = nodes[i].erasable;
if (canDelete) { if (canDelete) {
var calendar = nodes[i].calendar; var calendar = nodes[i].calendar;
if (!sortedNodes[calendar]) { if (!sortedNodes[calendar]) {
@ -254,7 +254,7 @@ function deleteEvent() {
var sortedNodes = []; var sortedNodes = [];
var calendars = []; var calendars = [];
for (var i = 0; i < selectedCalendarCell.length; i++) { for (var i = 0; i < selectedCalendarCell.length; i++) {
canDelete = selectedCalendarCell[i].erasable || IsSuperUser; canDelete = selectedCalendarCell[i].erasable;
if (canDelete) { if (canDelete) {
var calendar = selectedCalendarCell[i].calendar; var calendar = selectedCalendarCell[i].calendar;
if (!sortedNodes[calendar]) { if (!sortedNodes[calendar]) {
@ -865,7 +865,7 @@ function eventsListCallback(http) {
var row = createElement("tr"); var row = createElement("tr");
table.tBodies[0].appendChild(row); table.tBodies[0].appendChild(row);
row.addClassName("eventRow"); row.addClassName("eventRow");
var rTime = data[i][15]; var rTime = data[i][16];
var id = escape(data[i][1] + "-" + data[i][0]); var id = escape(data[i][1] + "-" + data[i][0]);
if (rTime) if (rTime)
id += "-" + escape(rTime); id += "-" + escape(rTime);
@ -874,17 +874,17 @@ function eventsListCallback(http) {
row.calendar = escape(data[i][1]); row.calendar = escape(data[i][1]);
if (rTime) if (rTime)
row.recurrenceTime = escape(rTime); row.recurrenceTime = escape(rTime);
row.isException = data[i][16]; row.isException = data[i][17];
row.editable = data[i][17]; row.editable = data[i][18];
row.erasable = data[i][18]; row.erasable = data[i][19] || IsSuperUser;
var startDate = new Date(); var startDate = new Date();
startDate.setTime(data[i][4] * 1000); startDate.setTime(data[i][5] * 1000);
row.day = startDate.getDayString(); row.day = startDate.getDayString();
if (!data[i][7]) if (!data[i][8])
row.hour = startDate.getHourString(); // event is not all day row.hour = startDate.getHourString(); // event is not all day
row.observe("mousedown", onRowClick); row.observe("mousedown", onRowClick);
row.observe("selectstart", listRowMouseDownHandler); row.observe("selectstart", listRowMouseDownHandler);
if (data[i][2] != null) if (data[i][3] != null)
// Status is defined -- event is readable // Status is defined -- event is readable
row.observe("dblclick", editDoubleClickedEvent); row.observe("dblclick", editDoubleClickedEvent);
row.attachMenu("eventsListMenu"); row.attachMenu("eventsListMenu");
@ -892,26 +892,31 @@ function eventsListCallback(http) {
var td = createElement("td"); var td = createElement("td");
row.appendChild(td); row.appendChild(td);
td.observe("mousedown", listRowMouseDownHandler, true); td.observe("mousedown", listRowMouseDownHandler, true);
td.appendChild(document.createTextNode(data[i][3])); // title td.appendChild(document.createTextNode(data[i][4])); // title
td = createElement("td"); td = createElement("td");
row.appendChild(td); row.appendChild(td);
td.observe("mousedown", listRowMouseDownHandler, true); td.observe("mousedown", listRowMouseDownHandler, true);
td.appendChild(document.createTextNode(data[i][20])); // start date td.appendChild(document.createTextNode(data[i][21])); // start date
td = createElement("td"); td = createElement("td");
row.appendChild(td); row.appendChild(td);
td.observe("mousedown", listRowMouseDownHandler, true); td.observe("mousedown", listRowMouseDownHandler, true);
td.appendChild(document.createTextNode(data[i][21])); // end date td.appendChild(document.createTextNode(data[i][22])); // end date
td = createElement("td"); td = createElement("td");
row.appendChild(td); row.appendChild(td);
td.observe("mousedown", listRowMouseDownHandler, true); td.observe("mousedown", listRowMouseDownHandler, true);
if (data[i][6]) if (data[i][7])
td.appendChild(document.createTextNode(data[i][6])); // location td.appendChild(document.createTextNode(data[i][7])); // location
td = createElement("td");
row.appendChild(td);
td.observe("mousedown", listRowMouseDownHandler, true);
td.appendChild(document.createTextNode(data[i][2])); // calendar
} }
if (sorting["attribute"] && sorting["attribute"].length > 0) { if (sorting["attribute"] && sorting["attribute"].length > 0) { log ("sort " + sorting["attribute"]);
var sortHeader = $(sorting["attribute"] + "Header"); var sortHeader = $(sorting["attribute"] + "Header");
if (sortHeader) { if (sortHeader) {
@ -964,7 +969,7 @@ function tasksListCallback(http) {
listItem.calendar = calendar; listItem.calendar = calendar;
listItem.addClassName("calendarFolder" + calendar); listItem.addClassName("calendarFolder" + calendar);
listItem.cname = cname; listItem.cname = cname;
listItem.erasable = data[i][7]; listItem.erasable = data[i][7] || IsSuperUser;
var input = createElement("input"); var input = createElement("input");
input.setAttribute("type", "checkbox"); input.setAttribute("type", "checkbox");
if (parseInt(data[i][6]) == 0) // editable? if (parseInt(data[i][6]) == 0) // editable?
@ -1179,21 +1184,23 @@ function scrollDayView(scrollEvent) {
var contentView; var contentView;
var eventRow = $(scrollEvent); var eventRow = $(scrollEvent);
var eventBlocks = selectCalendarEvent(eventRow.calendar, eventRow.cname, eventRow.recurrenceTime); var eventBlocks = selectCalendarEvent(eventRow.calendar, eventRow.cname, eventRow.recurrenceTime);
var firstEvent = eventBlocks.first(); if (eventBlocks) {
var firstEvent = eventBlocks.first();
if (currentView == "monthview") if (currentView == "monthview")
contentView = firstEvent.up("DIV.day"); contentView = firstEvent.up("DIV.day");
else else
contentView = $("daysView"); contentView = $("daysView");
// Don't scroll to an all-day event // Don't scroll to an all-day event
if (typeof eventRow.hour != "undefined") { if (typeof eventRow.hour != "undefined") {
var top = firstEvent.cumulativeOffset()[1] - contentView.scrollTop; var top = firstEvent.cumulativeOffset()[1] - contentView.scrollTop;
// Don't scroll if the event is visible to the user // Don't scroll if the event is visible to the user
if (top < contentView.cumulativeOffset()[1]) if (top < contentView.cumulativeOffset()[1])
contentView.scrollTop = firstEvent.cumulativeOffset()[1] - contentView.cumulativeOffset()[1]; contentView.scrollTop = firstEvent.cumulativeOffset()[1] - contentView.cumulativeOffset()[1];
else if (top > contentView.cumulativeOffset()[1] + contentView.getHeight() - firstEvent.getHeight()) else if (top > contentView.cumulativeOffset()[1] + contentView.getHeight() - firstEvent.getHeight())
contentView.scrollTop = firstEvent.cumulativeOffset()[1] - contentView.cumulativeOffset()[1]; contentView.scrollTop = firstEvent.cumulativeOffset()[1] - contentView.cumulativeOffset()[1];
}
} }
} }
else if (currentView != "monthview") { else if (currentView != "monthview") {
@ -1379,24 +1386,25 @@ function resetCategoriesStyles() {
function newBaseEventDIV(eventRep, event, eventText) { function newBaseEventDIV(eventRep, event, eventText) {
// log ("0 cname = " + event[0]); // log ("0 cname = " + event[0]);
// log ("1 calendar = " + event[1]); // log ("1 calendar = " + event[1]);
// log ("2 status = " + event[2]); // log ("2 calendar name = " + event[2]);
// log ("3 title = " + event[3]); // log ("3 status = " + event[3]);
// log ("4 start = " + event[4]); // log ("4 title = " + event[4]);
// log ("5 end = " + event[5]); // log ("5 start = " + event[5]);
// log ("6 location = " + event[6]); // log ("6 end = " + event[6]);
// log ("7 isallday = " + event[7]); // log ("7 location = " + event[7]);
// log ("8 classification = " + event[8]); // 0 = public, 1 = private, 2 = confidential // log ("8 isallday = " + event[8]);
// log ("9 category = " + event[9]); // log ("9 classification = " + event[9]); // 0 = public, 1 = private, 2 = confidential
// log ("10 participants emails = " + event[10]); // log ("10 category = " + event[10]);
// log ("11 participants states = " + event[11]); // log ("11 participants emails = " + event[11]);
// log ("12 owner = " + event[12]); // log ("12 participants states = " + event[12]);
// log ("13 iscycle = " + event[13]); // log ("13 owner = " + event[13]);
// log ("14 nextalarm = " + event[14]); // log ("14 iscycle = " + event[14]);
// log ("15 recurrenceid = " + event[15]); // log ("15 nextalarm = " + event[15]);
// log ("16 isexception = " + event[16]); // log ("16 recurrenceid = " + event[16]);
// log ("17 editable = " + event[17]); // log ("17 isexception = " + event[17]);
// log ("18 erasable = " + event[18]); // log ("18 editable = " + event[18]);
// log ("19 ownerisorganizer = " + event[19]); // log ("19 erasable = " + event[19]);
// log ("20 ownerisorganizer = " + event[20]);
var eventCell = createElement("div"); var eventCell = createElement("div");
eventCell.cname = event[0]; eventCell.cname = event[0];
@ -1408,10 +1416,10 @@ function newBaseEventDIV(eventRep, event, eventText) {
if (eventRep.recurrenceTime) if (eventRep.recurrenceTime)
eventCell.recurrenceTime = eventRep.recurrenceTime; eventCell.recurrenceTime = eventRep.recurrenceTime;
//eventCell.owner = event[12]; //eventCell.owner = event[12];
eventCell.isException = event[16]; eventCell.isException = event[17];
eventCell.editable = event[17]; eventCell.editable = event[18];
eventCell.erasable = event[18]; eventCell.erasable = event[19] || IsSuperUser;
eventCell.ownerIsOrganizer = event[19]; eventCell.ownerIsOrganizer = event[20];
eventCell.addClassName("event"); eventCell.addClassName("event");
// if (event[14] > 0) // if (event[14] > 0)
// eventCell.addClassName("alarm"); // eventCell.addClassName("alarm");
@ -1434,29 +1442,29 @@ function newBaseEventDIV(eventRep, event, eventText) {
var textDiv = createElement("div"); var textDiv = createElement("div");
innerDiv.appendChild(textDiv); innerDiv.appendChild(textDiv);
textDiv.addClassName("text"); textDiv.addClassName("text");
var iconSpan = createElement("span"); var iconSpan = createElement("span", null, "icons");
textDiv.appendChild(iconSpan); textDiv.appendChild(iconSpan);
textDiv.appendChild(document.createTextNode(eventText.replace(/(\\r)?\\n/g, "<BR/>"))); textDiv.appendChild(document.createTextNode(eventText.replace(/(\\r)?\\n/g, "<BR/>")));
// Add alarm and classification icons // Add alarm and classification icons
if (event[8] == 1) if (event[9] == 1)
createElement("img", null, null, {src: ResourcesURL + "/private.png"}, null, iconSpan); createElement("img", null, null, {src: ResourcesURL + "/private.png"}, null, iconSpan);
else if (event[8] == 2) else if (event[9] == 2)
createElement("img", null, null, {src: ResourcesURL + "/confidential.png"}, null, iconSpan); createElement("img", null, null, {src: ResourcesURL + "/confidential.png"}, null, iconSpan);
if (event[14] > 0) if (event[15] > 0)
createElement("img", null, null, {src: ResourcesURL + "/alarm.png"}, null, iconSpan); createElement("img", null, null, {src: ResourcesURL + "/alarm.png"}, null, iconSpan);
if (event[9] != null) { if (event[10] != null) {
var categoryStyle = categoriesStyles.get(event[9]); var categoryStyle = categoriesStyles.get(event[10]);
if (!categoryStyle) { if (!categoryStyle) {
categoryStyle = 'category_' + categoriesStyles.keys().length; categoryStyle = 'category_' + categoriesStyles.keys().length;
categoriesStyles.set([event[9]], categoryStyle); categoriesStyles.set([event[10]], categoryStyle);
} }
innerDiv.addClassName(categoryStyle); innerDiv.addClassName(categoryStyle);
} }
eventCell.observe("contextmenu", onMenuCurrentView); eventCell.observe("contextmenu", onMenuCurrentView);
if (event[2] == null) { if (event[3] == null) {
// Status field is not defined -- user can't read event // Status field is not defined -- user can't read event
eventCell.observe("selectstart", listRowMouseDownHandler); eventCell.observe("selectstart", listRowMouseDownHandler);
eventCell.observe("click", onCalendarSelectEvent); eventCell.observe("click", onCalendarSelectEvent);
@ -1493,7 +1501,7 @@ function _drawCalendarAllDayEvents(events, eventsData) {
function newAllDayEventDIV(eventRep, event) { function newAllDayEventDIV(eventRep, event) {
// cname, calendar, starts, lasts, // cname, calendar, starts, lasts,
// startHour, endHour, title) { // startHour, endHour, title) {
var eventCell = newBaseEventDIV(eventRep, event, event[3]); var eventCell = newBaseEventDIV(eventRep, event, event[4]);
return eventCell; return eventCell;
} }
@ -1519,7 +1527,7 @@ function _drawCalendarEvents(events, eventsData) {
} }
function newEventDIV(eventRep, event) { function newEventDIV(eventRep, event) {
var eventCell = newBaseEventDIV(eventRep, event, event[3]); var eventCell = newBaseEventDIV(eventRep, event, event[4]);
var pc = 100 / eventRep.siblings; var pc = 100 / eventRep.siblings;
var left = Math.floor(eventRep.position * pc); var left = Math.floor(eventRep.position * pc);
@ -1529,12 +1537,12 @@ function newEventDIV(eventRep, event) {
eventCell.addClassName("starts" + eventRep.start); eventCell.addClassName("starts" + eventRep.start);
eventCell.addClassName("lasts" + eventRep.length); eventCell.addClassName("lasts" + eventRep.length);
if (event[6]) { if (event[7]) {
var inside = eventCell.childNodesWithTag("div")[0]; var inside = eventCell.childNodesWithTag("div")[0];
var textDiv = inside.childNodesWithTag("div")[1]; var textDiv = inside.childNodesWithTag("div")[1];
textDiv.appendChild(createElement("br")); textDiv.appendChild(createElement("br"));
var span = createElement("span", null, "location"); var span = createElement("span", null, "location");
var text = _("Location:") + " " + event[6]; var text = _("Location:") + " " + event[7];
span.appendChild(document.createTextNode(text)); span.appendChild(document.createTextNode(text));
textDiv.appendChild(span); textDiv.appendChild(span);
} }
@ -1558,8 +1566,8 @@ function _drawMonthCalendarEvents(events, eventsData) {
function newMonthEventDIV(eventRep, event) { function newMonthEventDIV(eventRep, event) {
var eventText; var eventText;
if (event[7]) // all-day event if (event[8]) // all-day event
eventText = event[3]; eventText = event[4];
else else
eventText = eventRep.starthour + " - " + event[3]; eventText = eventRep.starthour + " - " + event[3];
@ -1745,9 +1753,11 @@ function popupCalendar(node) {
function onEventsSelectionChange() { function onEventsSelectionChange() {
listOfSelection = this; listOfSelection = this;
this.removeClassName("_unfocused"); this.removeClassName("_unfocused");
$("tasksList").addClassName("_unfocused");
deselectAll(true); var tasksList = $("tasksList");
tasksList.addClassName("_unfocused");
deselectAll(tasksList);
var rows = $(this.tBodies[0]).getSelectedNodes(); var rows = $(this.tBodies[0]).getSelectedNodes();
if (rows.length == 1) { if (rows.length == 1) {
var row = rows[0]; var row = rows[0];
@ -1767,7 +1777,9 @@ function onEventsSelectionChange() {
function onTasksSelectionChange() { function onTasksSelectionChange() {
listOfSelection = this; listOfSelection = this;
this.removeClassName("_unfocused"); this.removeClassName("_unfocused");
$("eventsList").addClassName("_unfocused"); var eventsList = $("eventsList");
eventsList.addClassName("_unfocused");
deselectAll(eventsList);
} }
function _loadEventHref(href) { function _loadEventHref(href) {
@ -1812,6 +1824,8 @@ function onHeaderClick(event) {
newSortAttribute = "end"; newSortAttribute = "end";
else if (headerId == "locationHeader") else if (headerId == "locationHeader")
newSortAttribute = "location"; newSortAttribute = "location";
else if (headerId == "calendarNameHeader")
newSortAttribute = "calendar";
else else
newSortAttribute = "start"; newSortAttribute = "start";
@ -1940,7 +1954,7 @@ function _eventBlocksMatching(calendar, cname, recurrenceTime) {
if (recurrenceTime) { if (recurrenceTime) {
for (var i = 0; i < occurences.length; i++) { for (var i = 0; i < occurences.length; i++) {
var occurence = occurences[i]; var occurence = occurences[i];
if (occurence[15] == recurrenceTime) if (occurence[16] == recurrenceTime)
blocks = occurence.blocks; blocks = occurence.blocks;
} }
} }
@ -1957,8 +1971,8 @@ function _eventBlocksMatching(calendar, cname, recurrenceTime) {
return blocks; return blocks;
} }
/** Select event in calendar view */
function selectCalendarEvent(calendar, cname, recurrenceTime) { function selectCalendarEvent(calendar, cname, recurrenceTime) {
// Select event in calendar view
var selection = _eventBlocksMatching(calendar, cname, recurrenceTime); var selection = _eventBlocksMatching(calendar, cname, recurrenceTime);
if (selection) { if (selection) {
for (var i = 0; i < selection.length; i++) for (var i = 0; i < selection.length; i++)
@ -1996,9 +2010,13 @@ function onSelectAll(event) {
return false; return false;
} }
function deselectAll(cellsOnly) { function deselectAll(list) {
if (!cellsOnly && listOfSelection) { if (list) {
listOfSelection.deselectAll(); list.deselectAll();
}
else {
$("eventsList").deselectAll();
$("tasksList").deselectAll();
} }
if (selectedCalendarCell) { if (selectedCalendarCell) {
for (var i = 0; i < selectedCalendarCell.length; i++) for (var i = 0; i < selectedCalendarCell.length; i++)
@ -2007,6 +2025,7 @@ function deselectAll(cellsOnly) {
} }
} }
/** Click on an event in the calendar view */
function onCalendarSelectEvent(event, willShowContextualMenu) { function onCalendarSelectEvent(event, willShowContextualMenu) {
var alreadySelected = false; var alreadySelected = false;
@ -2042,8 +2061,8 @@ function onCalendarSelectEvent(event, willShowContextualMenu) {
// Unselect entries in events list and calendar view, unless : // Unselect entries in events list and calendar view, unless :
// - Shift key is pressed; // - Shift key is pressed;
// - Or right button is clicked and event is already selected. // - Or right button is clicked and event is already selected.
listOfSelection = null;
deselectAll(); deselectAll();
listOfSelection = $("eventsList");
this.selectElement(); this.selectElement();
if (alreadySelected) if (alreadySelected)
selectedCalendarCell = [this]; selectedCalendarCell = [this];
@ -2077,14 +2096,12 @@ function onCalendarSelectDay(event) {
// Target is not an event -- unselect all events. // Target is not an event -- unselect all events.
listOfSelection = $("eventsList"); listOfSelection = $("eventsList");
deselectAll(); deselectAll();
listOfSelection = null;
preventDefault(event); preventDefault(event);
return false; return false;
} }
if (listOfSelection) { if (listOfSelection) {
listOfSelection.addClassName("_unfocused"); listOfSelection.addClassName("_unfocused");
listOfSelection = null;
} }
changeCalendarDisplay( { "day": currentDay } ); changeCalendarDisplay( { "day": currentDay } );

View File

@ -380,10 +380,12 @@ TD.headerDateTime
{ min-width: 30em; } { min-width: 30em; }
TD.headerTitle TD.headerTitle
{ width: 30%; } { width: 20%; }
TD.headerLocation TD.headerLocation,
{ min-width: 20em; } TD.headerCalendarName
{ min-width: 15em;
width: 15em; }
td img.tbtv_sortcell td img.tbtv_sortcell
{ float: right; { float: right;