Monotone-Parent: 95b1c285d67a034685e2ef30e56e10e7c253438d
Monotone-Revision: 2609687767884b123c1ff765253fde7c75ef81b3 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2008-07-16T02:12:18 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
8078250b1a
commit
7512f5d512
18
ChangeLog
18
ChangeLog
|
@ -1,3 +1,21 @@
|
||||||
|
2008-07-15 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
|
||||||
|
* UI/Scheduler/NSDictionary+Scheduler.m: new category module that
|
||||||
|
implement helper methods for the Scheduler module.
|
||||||
|
([NSDictionary -compareEventByStart:otherEvent]): new method that
|
||||||
|
compares event block dictionaries based on their value for
|
||||||
|
"start".
|
||||||
|
|
||||||
|
* UI/Scheduler/UIxCalListingActions.m ([UIxCalListingActions
|
||||||
|
-eventsBlocksAction]): new web method that returns the list of
|
||||||
|
events as well as the precomputed blocks of events, whether "all
|
||||||
|
day" or not.
|
||||||
|
|
||||||
|
* SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||||
|
([SOGoAppointmentFolder
|
||||||
|
-fetchCoreInfosFrom:_startDateto:_endDatetitle:titlecomponent:_componentadditionalFilters:filters]):
|
||||||
|
requests "c_iscycle".
|
||||||
|
|
||||||
2008-07-14 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
2008-07-14 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
|
||||||
* SoObjects/SOGo/SOGoContentObject.m ([SOGoContentObject
|
* SoObjects/SOGo/SOGoContentObject.m ([SOGoContentObject
|
||||||
|
|
|
@ -1399,7 +1399,6 @@ static Class sogoAppointmentFolderKlass = Nil;
|
||||||
|
|
||||||
- (NSString *) davCalendarOrder
|
- (NSString *) davCalendarOrder
|
||||||
{
|
{
|
||||||
NSArray *siblings;
|
|
||||||
unsigned int order;
|
unsigned int order;
|
||||||
|
|
||||||
order = [[container subFolders] indexOfObject: self];
|
order = [[container subFolders] indexOfObject: self];
|
||||||
|
@ -1409,8 +1408,6 @@ static Class sogoAppointmentFolderKlass = Nil;
|
||||||
|
|
||||||
- (NSException *) setDavCalendarOrder: (NSString *) newColor
|
- (NSException *) setDavCalendarOrder: (NSString *) newColor
|
||||||
{
|
{
|
||||||
NSException *error;
|
|
||||||
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2218,7 +2215,7 @@ static Class sogoAppointmentFolderKlass = Nil;
|
||||||
@"c_classification", @"c_isallday",
|
@"c_classification", @"c_isallday",
|
||||||
@"c_isopaque", @"c_participants", @"c_partmails",
|
@"c_isopaque", @"c_participants", @"c_partmails",
|
||||||
@"c_partstates", @"c_sequence", @"c_priority",
|
@"c_partstates", @"c_sequence", @"c_priority",
|
||||||
@"c_cycleinfo", nil];
|
@"c_cycleinfo", @"c_iscycle", nil];
|
||||||
|
|
||||||
return [self fetchFields: infos from: _startDate to: _endDate title: title
|
return [self fetchFields: infos from: _startDate to: _endDate title: title
|
||||||
component: _component
|
component: _component
|
||||||
|
|
|
@ -11,6 +11,7 @@ SchedulerUI_LANGUAGES = Dutch English French German Italian Spanish
|
||||||
SchedulerUI_OBJC_FILES = \
|
SchedulerUI_OBJC_FILES = \
|
||||||
SchedulerUIProduct.m \
|
SchedulerUIProduct.m \
|
||||||
NSArray+Scheduler.m \
|
NSArray+Scheduler.m \
|
||||||
|
NSDictionary+Scheduler.m \
|
||||||
\
|
\
|
||||||
UIxCalMainView.m \
|
UIxCalMainView.m \
|
||||||
UIxCalendarProperties.m \
|
UIxCalendarProperties.m \
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/* NSDictionary+Scheduler.h - this file is part of SOGo
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Inverse groupe conseil
|
||||||
|
*
|
||||||
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
*
|
||||||
|
* This file is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This file is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/NSDictionary.h>
|
||||||
|
|
||||||
|
@interface NSDictionary (SOGoEventComparison)
|
||||||
|
|
||||||
|
- (NSComparisonResult) compareEventByStart: (NSDictionary *) otherEvent;
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,35 @@
|
||||||
|
/* NSDictionary+Scheduler.m - this file is part of SOGo
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Inverse groupe conseil
|
||||||
|
*
|
||||||
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
*
|
||||||
|
* This file is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This file is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/NSString.h>
|
||||||
|
|
||||||
|
#import "NSDictionary+Scheduler.h"
|
||||||
|
|
||||||
|
@implementation NSDictionary (SOGoEventComparison)
|
||||||
|
|
||||||
|
- (NSComparisonResult) compareEventByStart: (NSDictionary *) otherEvent
|
||||||
|
{
|
||||||
|
return [[self objectForKey: @"start"]
|
||||||
|
compare: [otherEvent objectForKey: @"start"]];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -42,6 +42,7 @@
|
||||||
NSCalendarDate *endDate;
|
NSCalendarDate *endDate;
|
||||||
NSString *title;
|
NSString *title;
|
||||||
NSString *userLogin;
|
NSString *userLogin;
|
||||||
|
BOOL dayBasedView;
|
||||||
WORequest *request;
|
WORequest *request;
|
||||||
SOGoDateFormatter *dateFormatter;
|
SOGoDateFormatter *dateFormatter;
|
||||||
NSTimeZone *userTimeZone;
|
NSTimeZone *userTimeZone;
|
||||||
|
|
|
@ -49,8 +49,34 @@
|
||||||
|
|
||||||
#import "UIxCalListingActions.h"
|
#import "UIxCalListingActions.h"
|
||||||
|
|
||||||
|
static NSArray *eventsFields = nil;
|
||||||
|
static NSArray *tasksFields = nil;
|
||||||
|
|
||||||
|
#define dayLength 86400
|
||||||
|
#define quarterLength 900
|
||||||
|
|
||||||
@implementation UIxCalListingActions
|
@implementation UIxCalListingActions
|
||||||
|
|
||||||
|
+ (void) initialize
|
||||||
|
{
|
||||||
|
if (!eventsFields)
|
||||||
|
{
|
||||||
|
eventsFields = [NSArray arrayWithObjects: @"c_name", @"c_folder",
|
||||||
|
@"c_status", @"c_title", @"c_startdate",
|
||||||
|
@"c_enddate", @"c_location", @"c_isallday",
|
||||||
|
@"c_classification", @"c_partmails",
|
||||||
|
@"c_partstates", @"c_owner", @"c_iscycle", nil];
|
||||||
|
[eventsFields retain];
|
||||||
|
}
|
||||||
|
if (!tasksFields)
|
||||||
|
{
|
||||||
|
tasksFields = [NSArray arrayWithObjects: @"c_name", @"c_folder",
|
||||||
|
@"c_status", @"c_title", @"c_enddate",
|
||||||
|
@"c_classification", nil];
|
||||||
|
[tasksFields retain];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (id) initWithRequest: (WORequest *) newRequest
|
- (id) initWithRequest: (WORequest *) newRequest
|
||||||
{
|
{
|
||||||
SOGoUser *user;
|
SOGoUser *user;
|
||||||
|
@ -64,6 +90,7 @@
|
||||||
user = [[self context] activeUser];
|
user = [[self context] activeUser];
|
||||||
dateFormatter = [user dateFormatterInContext: context];
|
dateFormatter = [user dateFormatterInContext: context];
|
||||||
ASSIGN (userTimeZone, [user timeZone]);
|
ASSIGN (userTimeZone, [user timeZone]);
|
||||||
|
dayBasedView = NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -161,7 +188,7 @@
|
||||||
userTZ = [user timeZone];
|
userTZ = [user timeZone];
|
||||||
|
|
||||||
param = [request formValueForKey: @"filterpopup"];
|
param = [request formValueForKey: @"filterpopup"];
|
||||||
if ([param length] > 0)
|
if ([param length])
|
||||||
{
|
{
|
||||||
[self _setupDatesWithPopup: param andUserTZ: userTZ];
|
[self _setupDatesWithPopup: param andUserTZ: userTZ];
|
||||||
title = [request formValueForKey: @"search"];
|
title = [request formValueForKey: @"search"];
|
||||||
|
@ -175,7 +202,7 @@
|
||||||
inTimeZone: userTZ] beginOfDay];
|
inTimeZone: userTZ] beginOfDay];
|
||||||
else
|
else
|
||||||
startDate = nil;
|
startDate = nil;
|
||||||
|
|
||||||
param = [request formValueForKey: @"ed"];
|
param = [request formValueForKey: @"ed"];
|
||||||
if ([param length] > 0)
|
if ([param length] > 0)
|
||||||
endDate = [[NSCalendarDate dateFromShortDateString: param
|
endDate = [[NSCalendarDate dateFromShortDateString: param
|
||||||
|
@ -183,6 +210,9 @@
|
||||||
inTimeZone: userTZ] endOfDay];
|
inTimeZone: userTZ] endOfDay];
|
||||||
else
|
else
|
||||||
endDate = nil;
|
endDate = nil;
|
||||||
|
|
||||||
|
param = [request formValueForKey: @"view"];
|
||||||
|
dayBasedView = ![param isEqualToString: @"monthview"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,27 +321,9 @@
|
||||||
return formattedDate;
|
return formattedDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) _adjustedDateForSeconds: (unsigned int) seconds
|
|
||||||
forAllDay: (BOOL) forAllDay
|
|
||||||
{
|
|
||||||
NSCalendarDate *date;
|
|
||||||
unsigned int newSeconds, offset;
|
|
||||||
|
|
||||||
date = [NSCalendarDate dateWithTimeIntervalSince1970: seconds];
|
|
||||||
[date setTimeZone: userTimeZone];
|
|
||||||
|
|
||||||
offset = [userTimeZone secondsFromGMTForDate: date];
|
|
||||||
if (forAllDay)
|
|
||||||
newSeconds = seconds + [userTimeZone secondsFromGMT] - offset;
|
|
||||||
else
|
|
||||||
newSeconds = seconds + offset;
|
|
||||||
|
|
||||||
return [NSString stringWithFormat: @"%u", newSeconds];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (WOResponse *) eventsListAction
|
- (WOResponse *) eventsListAction
|
||||||
{
|
{
|
||||||
NSArray *fields, *oldEvent, *participants, *states;
|
NSArray *oldEvent, *participants, *states;
|
||||||
NSEnumerator *events;
|
NSEnumerator *events;
|
||||||
NSMutableArray *newEvents, *newEvent;
|
NSMutableArray *newEvents, *newEvent;
|
||||||
unsigned int interval, i;
|
unsigned int interval, i;
|
||||||
|
@ -322,27 +334,16 @@
|
||||||
[self _setupContext];
|
[self _setupContext];
|
||||||
|
|
||||||
newEvents = [NSMutableArray array];
|
newEvents = [NSMutableArray array];
|
||||||
fields = [NSArray arrayWithObjects: @"c_name", @"c_folder", @"c_status",
|
events = [[self _fetchFields: eventsFields
|
||||||
@"c_title", @"c_startdate", @"c_enddate", @"c_location",
|
|
||||||
@"c_isallday", @"c_classification", @"c_partmails", @"c_partstates",
|
|
||||||
@"c_owner", nil];
|
|
||||||
events = [[self _fetchFields: fields
|
|
||||||
forComponentOfType: @"vevent"] objectEnumerator];
|
forComponentOfType: @"vevent"] objectEnumerator];
|
||||||
oldEvent = [events nextObject];
|
while ((oldEvent = [events nextObject]))
|
||||||
while (oldEvent)
|
|
||||||
{
|
{
|
||||||
newEvent = [NSMutableArray arrayWithArray: oldEvent];
|
newEvent = [NSMutableArray arrayWithArray: oldEvent];
|
||||||
isAllDay = [[oldEvent objectAtIndex: 7] boolValue];
|
isAllDay = [[oldEvent objectAtIndex: 7] boolValue];
|
||||||
interval = [[oldEvent objectAtIndex: 4] intValue];
|
interval = [[oldEvent objectAtIndex: 4] intValue];
|
||||||
[newEvent replaceObjectAtIndex: 4
|
|
||||||
withObject: [self _adjustedDateForSeconds: interval
|
|
||||||
forAllDay: isAllDay]];
|
|
||||||
[newEvent addObject: [self _formattedDateForSeconds: interval
|
[newEvent addObject: [self _formattedDateForSeconds: interval
|
||||||
forAllDay: isAllDay]];
|
forAllDay: isAllDay]];
|
||||||
interval = [[oldEvent objectAtIndex: 5] intValue];
|
interval = [[oldEvent objectAtIndex: 5] intValue];
|
||||||
[newEvent replaceObjectAtIndex: 5
|
|
||||||
withObject: [self _adjustedDateForSeconds: interval
|
|
||||||
forAllDay: isAllDay]];
|
|
||||||
[newEvent addObject: [self _formattedDateForSeconds: interval
|
[newEvent addObject: [self _formattedDateForSeconds: interval
|
||||||
forAllDay: isAllDay]];
|
forAllDay: isAllDay]];
|
||||||
|
|
||||||
|
@ -380,8 +381,6 @@
|
||||||
[newEvent removeObjectAtIndex: 10];
|
[newEvent removeObjectAtIndex: 10];
|
||||||
|
|
||||||
[newEvents addObject: newEvent];
|
[newEvents addObject: newEvent];
|
||||||
|
|
||||||
oldEvent = [events nextObject];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sort = [[context request] formValueForKey: @"sort"];
|
sort = [[context request] formValueForKey: @"sort"];
|
||||||
|
@ -393,7 +392,7 @@
|
||||||
[newEvents sortUsingSelector: @selector (compareEventsLocationAscending:)];
|
[newEvents sortUsingSelector: @selector (compareEventsLocationAscending:)];
|
||||||
else
|
else
|
||||||
[newEvents sortUsingSelector: @selector (compareEventsStartDateAscending:)];
|
[newEvents sortUsingSelector: @selector (compareEventsStartDateAscending:)];
|
||||||
|
|
||||||
ascending = [[context request] formValueForKey: @"asc"];
|
ascending = [[context request] formValueForKey: @"asc"];
|
||||||
if (![ascending boolValue])
|
if (![ascending boolValue])
|
||||||
[newEvents reverseArray];
|
[newEvents reverseArray];
|
||||||
|
@ -401,6 +400,361 @@
|
||||||
return [self _responseWithData: newEvents];
|
return [self _responseWithData: newEvents];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_feedBlockWithDayBasedData(NSMutableDictionary *block, unsigned int start,
|
||||||
|
unsigned int end, unsigned int dayStart)
|
||||||
|
{
|
||||||
|
unsigned int delta, quarterStart, length;
|
||||||
|
|
||||||
|
quarterStart = (start - dayStart) / quarterLength;
|
||||||
|
delta = end - dayStart;
|
||||||
|
if ((delta % quarterLength))
|
||||||
|
delta += quarterLength;
|
||||||
|
length = (delta / quarterLength) - quarterStart;
|
||||||
|
if (!length)
|
||||||
|
length = 1;
|
||||||
|
[block setObject: [NSNumber numberWithUnsignedInt: quarterStart]
|
||||||
|
forKey: @"start"];
|
||||||
|
[block setObject: [NSNumber numberWithUnsignedInt: length]
|
||||||
|
forKey: @"length"];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_feedBlockWithMonthBasedData(NSMutableDictionary *block, unsigned int start,
|
||||||
|
NSTimeZone *userTimeZone,
|
||||||
|
SOGoDateFormatter *dateFormatter)
|
||||||
|
{
|
||||||
|
NSCalendarDate *eventStartDate;
|
||||||
|
NSString *startHour;
|
||||||
|
|
||||||
|
eventStartDate = [NSCalendarDate dateWithTimeIntervalSince1970: start];
|
||||||
|
[eventStartDate setTimeZone: userTimeZone];
|
||||||
|
startHour = [dateFormatter formattedTime: eventStartDate];
|
||||||
|
[block setObject: startHour forKey: @"starthour"];
|
||||||
|
[block setObject: [NSNumber numberWithUnsignedInt: start]
|
||||||
|
forKey: @"start"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSMutableDictionary *) _eventBlockWithStart: (unsigned int) start
|
||||||
|
end: (unsigned int) end
|
||||||
|
cname: (NSString *) cName
|
||||||
|
onDay: (unsigned int) dayStart
|
||||||
|
recurrence: (BOOL) recurrence
|
||||||
|
{
|
||||||
|
NSMutableDictionary *block;
|
||||||
|
|
||||||
|
block = [NSMutableDictionary dictionary];
|
||||||
|
|
||||||
|
if (dayBasedView)
|
||||||
|
_feedBlockWithDayBasedData (block, start, end, dayStart);
|
||||||
|
else
|
||||||
|
_feedBlockWithMonthBasedData (block, start, userTimeZone, dateFormatter);
|
||||||
|
[block setObject: cName forKey: @"cname"];
|
||||||
|
if (recurrence)
|
||||||
|
[block setObject: @"1" forKey: @"recurrence"];
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) _fillBlocks: (NSArray *) blocks
|
||||||
|
withEvent: (NSArray *) event
|
||||||
|
{
|
||||||
|
unsigned int currentDayStart, startSecs, endsSecs, currentStart, eventStart,
|
||||||
|
eventEnd, offset;
|
||||||
|
NSMutableArray *currentDay;
|
||||||
|
NSMutableDictionary *eventBlock;
|
||||||
|
NSString *eventCName;
|
||||||
|
BOOL recurrence;
|
||||||
|
|
||||||
|
startSecs = (unsigned int) [startDate timeIntervalSince1970];
|
||||||
|
endsSecs = (unsigned int) [endDate timeIntervalSince1970];
|
||||||
|
eventStart = [[event objectAtIndex: 4] unsignedIntValue];
|
||||||
|
eventEnd = [[event objectAtIndex: 5] unsignedIntValue];
|
||||||
|
|
||||||
|
recurrence = [[event objectAtIndex: 12] boolValue];
|
||||||
|
|
||||||
|
currentStart = eventStart;
|
||||||
|
if (currentStart < startSecs)
|
||||||
|
{
|
||||||
|
currentStart = startSecs;
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
offset = ((currentStart - startSecs)
|
||||||
|
/ dayLength);
|
||||||
|
currentDay = [blocks objectAtIndex: offset];
|
||||||
|
currentDayStart = startSecs + dayLength * offset;
|
||||||
|
|
||||||
|
if (eventEnd > endsSecs)
|
||||||
|
eventEnd = endsSecs;
|
||||||
|
|
||||||
|
eventCName = [event objectAtIndex: 0];
|
||||||
|
while (currentStart + dayLength < eventEnd)
|
||||||
|
{
|
||||||
|
eventBlock = [self _eventBlockWithStart: currentStart
|
||||||
|
end: currentDayStart + 86399
|
||||||
|
cname: eventCName
|
||||||
|
onDay: currentDayStart
|
||||||
|
recurrence: recurrence];
|
||||||
|
[currentDay addObject: eventBlock];
|
||||||
|
currentDayStart += dayLength;
|
||||||
|
currentStart = currentDayStart;
|
||||||
|
offset++;
|
||||||
|
currentDay = [blocks objectAtIndex: offset];
|
||||||
|
}
|
||||||
|
eventBlock = [self _eventBlockWithStart: currentStart
|
||||||
|
end: eventEnd
|
||||||
|
cname: eventCName
|
||||||
|
onDay: currentDayStart
|
||||||
|
recurrence: recurrence];
|
||||||
|
[currentDay addObject: eventBlock];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) _prepareEventBlocks: (NSMutableArray **) blocks
|
||||||
|
withAllDays: (NSMutableArray **) allDayBlocks
|
||||||
|
{
|
||||||
|
unsigned int count, nbrDays;
|
||||||
|
int seconds;
|
||||||
|
|
||||||
|
seconds = [endDate timeIntervalSinceDate: startDate];
|
||||||
|
if (seconds > 0)
|
||||||
|
{
|
||||||
|
nbrDays = 1 + (unsigned int) (seconds / dayLength);
|
||||||
|
*blocks = [NSMutableArray arrayWithCapacity: nbrDays];
|
||||||
|
*allDayBlocks = [NSMutableArray arrayWithCapacity: nbrDays];
|
||||||
|
for (count = 0; count < nbrDays; count++)
|
||||||
|
{
|
||||||
|
[*blocks addObject: [NSMutableArray array]];
|
||||||
|
[*allDayBlocks addObject: [NSMutableArray array]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*blocks = nil;
|
||||||
|
*allDayBlocks = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *) _horizontalBlocks: (NSMutableArray *) day
|
||||||
|
{
|
||||||
|
NSMutableArray *quarters[96];
|
||||||
|
NSMutableArray *currentBlock, *blocks;
|
||||||
|
NSDictionary *currentEvent;
|
||||||
|
unsigned int count, max, qCount, qMax, qOffset;
|
||||||
|
|
||||||
|
blocks = [NSMutableArray array];
|
||||||
|
|
||||||
|
bzero (quarters, 96 * sizeof (NSMutableArray *));
|
||||||
|
|
||||||
|
max = [day count];
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
{
|
||||||
|
currentEvent = [day objectAtIndex: count];
|
||||||
|
qMax = [[currentEvent objectForKey: @"length"] unsignedIntValue];
|
||||||
|
qOffset = [[currentEvent objectForKey: @"start"] unsignedIntValue];
|
||||||
|
for (qCount = 0; qCount < qMax; qCount++)
|
||||||
|
{
|
||||||
|
currentBlock = quarters[qCount + qOffset];
|
||||||
|
if (!currentBlock)
|
||||||
|
{
|
||||||
|
currentBlock = [NSMutableArray array];
|
||||||
|
quarters[qCount + qOffset] = currentBlock;
|
||||||
|
[blocks addObject: currentBlock];
|
||||||
|
}
|
||||||
|
[currentBlock addObject: currentEvent];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned int
|
||||||
|
_computeMaxBlockSiblings (NSArray *block)
|
||||||
|
{
|
||||||
|
unsigned int count, max, maxSiblings, siblings;
|
||||||
|
NSNumber *nbrEvents;
|
||||||
|
|
||||||
|
max = [block count];
|
||||||
|
maxSiblings = max;
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
{
|
||||||
|
nbrEvents = [[block objectAtIndex: count] objectForKey: @"siblings"];
|
||||||
|
if (nbrEvents)
|
||||||
|
{
|
||||||
|
siblings = [nbrEvents unsignedIntValue];
|
||||||
|
if (siblings > maxSiblings)
|
||||||
|
maxSiblings = siblings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxSiblings;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_propagateBlockSiblings (NSArray *block, NSNumber *maxSiblings)
|
||||||
|
{
|
||||||
|
unsigned int count, max;
|
||||||
|
NSMutableDictionary *event;
|
||||||
|
NSNumber *realSiblings;
|
||||||
|
|
||||||
|
max = [block count];
|
||||||
|
realSiblings = [NSNumber numberWithUnsignedInt: max];
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
{
|
||||||
|
event = [block objectAtIndex: count];
|
||||||
|
[event setObject: maxSiblings forKey: @"siblings"];
|
||||||
|
[event setObject: realSiblings forKey: @"realSiblings"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this requires two vertical passes */
|
||||||
|
static inline void
|
||||||
|
_computeBlocksSiblings (NSArray *blocks)
|
||||||
|
{
|
||||||
|
NSArray *currentBlock;
|
||||||
|
unsigned int count, max, maxSiblings;
|
||||||
|
|
||||||
|
max = [blocks count];
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
{
|
||||||
|
currentBlock = [blocks objectAtIndex: count];
|
||||||
|
maxSiblings = _computeMaxBlockSiblings (currentBlock);
|
||||||
|
_propagateBlockSiblings (currentBlock,
|
||||||
|
[NSNumber numberWithUnsignedInt: maxSiblings]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_computeBlockPosition (NSArray *block)
|
||||||
|
{
|
||||||
|
unsigned int count, max, j, siblings;
|
||||||
|
NSNumber *position;
|
||||||
|
NSMutableDictionary *event;
|
||||||
|
NSMutableDictionary **positions;
|
||||||
|
|
||||||
|
max = [block count];
|
||||||
|
event = [block objectAtIndex: 0];
|
||||||
|
siblings = [[event objectForKey: @"siblings"] unsignedIntValue];
|
||||||
|
positions = calloc (siblings, sizeof (NSMutableDictionary *));
|
||||||
|
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
{
|
||||||
|
event = [block objectAtIndex: count];
|
||||||
|
position = [event objectForKey: @"position"];
|
||||||
|
if (position)
|
||||||
|
*(positions + [position unsignedIntValue]) = event;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
j = 0;
|
||||||
|
while (j < max && *(positions + j))
|
||||||
|
j++;
|
||||||
|
*(positions + j) = event;
|
||||||
|
[event setObject: [NSNumber numberWithUnsignedInt: j]
|
||||||
|
forKey: @"position"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free (positions);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static inline void
|
||||||
|
// _addBlockMultipliers (NSArray *block, NSMutableDictionary **positions)
|
||||||
|
// {
|
||||||
|
// unsigned int count, max, limit, multiplier;
|
||||||
|
// NSMutableDictionary *currentEvent, *event;
|
||||||
|
|
||||||
|
// max = [block count];
|
||||||
|
// event = [block objectAtIndex: 0];
|
||||||
|
// limit = [[event objectForKey: @"siblings"] unsignedIntValue];
|
||||||
|
|
||||||
|
// if (max < limit)
|
||||||
|
// {
|
||||||
|
// currentEvent = nil;
|
||||||
|
// for (count = 0; count < limit; count++)
|
||||||
|
// {
|
||||||
|
// multiplier = 1;
|
||||||
|
// event = positions[count];
|
||||||
|
// if ([[event objectForKey: @"realSiblings"] unsignedIntValue]
|
||||||
|
// < limit)
|
||||||
|
// {
|
||||||
|
// if (event)
|
||||||
|
// {
|
||||||
|
// if (currentEvent && multiplier > 1)
|
||||||
|
// [currentEvent setObject: [NSNumber numberWithUnsignedInt: multiplier]
|
||||||
|
// forKey: @"multiplier"];
|
||||||
|
// currentEvent = event;
|
||||||
|
// multiplier = 1;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// multiplier++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_computeBlocksPosition (NSArray *blocks)
|
||||||
|
{
|
||||||
|
NSArray *block;
|
||||||
|
unsigned int count, max;
|
||||||
|
// NSMutableDictionary **positions;
|
||||||
|
|
||||||
|
max = [blocks count];
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
{
|
||||||
|
block = [blocks objectAtIndex: count];
|
||||||
|
_computeBlockPosition (block);
|
||||||
|
// _addBlockMultipliers (block, positions);
|
||||||
|
// free (positions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) _addBlocksWidth: (NSMutableArray *) day
|
||||||
|
{
|
||||||
|
NSArray *blocks;
|
||||||
|
|
||||||
|
blocks = [self _horizontalBlocks: day];
|
||||||
|
_computeBlocksSiblings (blocks);
|
||||||
|
_computeBlocksSiblings (blocks);
|
||||||
|
_computeBlocksPosition (blocks);
|
||||||
|
/* ... _computeBlocksMultiplier() ... */
|
||||||
|
}
|
||||||
|
|
||||||
|
- (WOResponse *) eventsBlocksAction
|
||||||
|
{
|
||||||
|
int count, max;
|
||||||
|
NSArray *events, *event, *eventsBlocks;
|
||||||
|
NSMutableArray *allDayBlocks, *blocks, *currentDay;
|
||||||
|
|
||||||
|
[self _setupContext];
|
||||||
|
|
||||||
|
[self _prepareEventBlocks: &blocks withAllDays: &allDayBlocks];
|
||||||
|
events = [self _fetchFields: eventsFields
|
||||||
|
forComponentOfType: @"vevent"];
|
||||||
|
eventsBlocks
|
||||||
|
= [NSArray arrayWithObjects: events, allDayBlocks, blocks, nil];
|
||||||
|
max = [events count];
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
{
|
||||||
|
event = [events objectAtIndex: count];
|
||||||
|
if (dayBasedView && [[event objectAtIndex: 7] boolValue])
|
||||||
|
[self _fillBlocks: allDayBlocks withEvent: event];
|
||||||
|
else
|
||||||
|
[self _fillBlocks: blocks withEvent: event];
|
||||||
|
}
|
||||||
|
|
||||||
|
max = [blocks count];
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
{
|
||||||
|
currentDay = [blocks objectAtIndex: count];
|
||||||
|
[currentDay sortUsingSelector: @selector (compareEventByStart:)];
|
||||||
|
[self _addBlocksWidth: currentDay];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [self _responseWithData: eventsBlocks];
|
||||||
|
// timeIntervalSinceDate:
|
||||||
|
}
|
||||||
|
|
||||||
- (NSString *) _getStatusClassForStatusCode: (int) statusCode
|
- (NSString *) _getStatusClassForStatusCode: (int) statusCode
|
||||||
andEndDateStamp: (unsigned int) endDateStamp
|
andEndDateStamp: (unsigned int) endDateStamp
|
||||||
{
|
{
|
||||||
|
@ -438,7 +792,7 @@
|
||||||
NSEnumerator *tasks;
|
NSEnumerator *tasks;
|
||||||
NSMutableArray *filteredTasks, *filteredTask;
|
NSMutableArray *filteredTasks, *filteredTask;
|
||||||
BOOL showCompleted;
|
BOOL showCompleted;
|
||||||
NSArray *fields, *task;
|
NSArray *task;
|
||||||
int statusCode;
|
int statusCode;
|
||||||
unsigned int endDateStamp;
|
unsigned int endDateStamp;
|
||||||
NSString *statusFlag;
|
NSString *statusFlag;
|
||||||
|
@ -447,10 +801,7 @@
|
||||||
|
|
||||||
[self _setupContext];
|
[self _setupContext];
|
||||||
|
|
||||||
fields = [NSArray arrayWithObjects: @"c_name", @"c_folder", @"c_status",
|
tasks = [[self _fetchFields: tasksFields
|
||||||
@"c_title", @"c_enddate", @"c_classification", nil];
|
|
||||||
|
|
||||||
tasks = [[self _fetchFields: fields
|
|
||||||
forComponentOfType: @"vtodo"] objectEnumerator];
|
forComponentOfType: @"vtodo"] objectEnumerator];
|
||||||
showCompleted = [[request formValueForKey: @"show-completed"] intValue];
|
showCompleted = [[request formValueForKey: @"show-completed"] intValue];
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,11 @@
|
||||||
actionClass = "UIxCalListingActions";
|
actionClass = "UIxCalListingActions";
|
||||||
actionName = "eventsList";
|
actionName = "eventsList";
|
||||||
};
|
};
|
||||||
|
eventsblocks = {
|
||||||
|
protectedBy = "View";
|
||||||
|
actionClass = "UIxCalListingActions";
|
||||||
|
actionName = "eventsBlocks";
|
||||||
|
};
|
||||||
taskslist = {
|
taskslist = {
|
||||||
protectedBy = "View";
|
protectedBy = "View";
|
||||||
actionClass = "UIxCalListingActions";
|
actionClass = "UIxCalListingActions";
|
||||||
|
|
|
@ -42,20 +42,6 @@
|
||||||
var:day="currentTableDay.shortDateString"
|
var:day="currentTableDay.shortDateString"
|
||||||
var:hour="currentAppointmentHour">
|
var:hour="currentAppointmentHour">
|
||||||
</div></var:foreach>
|
</div></var:foreach>
|
||||||
<!-- <var:foreach list="appointmentsForCurrentDay" item="currentAppointment"
|
|
||||||
><var:component className="UIxCalInlineAptView"
|
|
||||||
dayStartHour="dayStartHour"
|
|
||||||
dayEndHour="dayEndHour"
|
|
||||||
appointment="currentAppointment"
|
|
||||||
formatter="aptFormatter"
|
|
||||||
tooltipFormatter="aptTooltipFormatter"
|
|
||||||
url="appointmentViewURL"
|
|
||||||
const:style="dayoverview"
|
|
||||||
queryDictionary="currentDateQueryParameters"
|
|
||||||
referenceDate="selectedDate"
|
|
||||||
canAccess="canAccessApt"
|
|
||||||
/></var:foreach
|
|
||||||
> -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</var:foreach>
|
</var:foreach>
|
||||||
|
|
|
@ -47,89 +47,15 @@
|
||||||
><var:string value="labelForCurrentDayToDisplay"
|
><var:string value="labelForCurrentDayToDisplay"
|
||||||
/></div></var:foreach>
|
/></div></var:foreach>
|
||||||
<div class="days" const:id="monthDaysView"
|
<div class="days" const:id="monthDaysView"
|
||||||
><var:foreach list="daysToDisplay" item="currentTableColumn">
|
><var:foreach list="daysToDisplay" item="currentTableColumn"
|
||||||
<var:foreach list="currentTableColumn" item="currentTableDay">
|
><var:foreach list="currentTableColumn" item="currentTableDay"
|
||||||
<div var:class="dayCellClasses"
|
><div var:class="dayCellClasses"
|
||||||
var:day="currentTableDay.shortDateString">
|
var:day="currentTableDay.shortDateString">
|
||||||
<div class="dayHeader"><var:string value="dayHeaderNumber"/></div>
|
<div class="dayHeader"><var:string value="dayHeaderNumber"/></div
|
||||||
<!-- var:foreach
|
></div>
|
||||||
list="aptsForCurrentDate"
|
|
||||||
item="appointment"
|
|
||||||
var:component className="UIxCalInlineMdsadsadsaonthAptView"
|
|
||||||
appointment="appointment"
|
|
||||||
formatter="monthAptFormatter"
|
|
||||||
tooltipFormatter="aptTooltipFormatter"
|
|
||||||
url="appointmentViewURL"
|
|
||||||
const:style="dayoverview"
|
|
||||||
queryDictionary="currentDayQueryParameters"
|
|
||||||
referenceDate="currentTableDay"
|
|
||||||
canAccess="canAccessApt"
|
|
||||||
var:foreach -->
|
|
||||||
</div>
|
|
||||||
</var:foreach>
|
</var:foreach>
|
||||||
</var:foreach>
|
</var:foreach>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</container>
|
</container>
|
||||||
|
|
||||||
<!-- <table class="monthOverview">
|
|
||||||
<tr>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<var:if condition="hasHolidayInfo">
|
|
||||||
<tr>
|
|
||||||
<td class="hourOfDay" colspan="2">
|
|
||||||
<b><var:string value="holidayInfo.title" /></b>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</var:if> -->
|
|
||||||
|
|
||||||
<!-- <var:foreach list="allDayApts" item="appointment">
|
|
||||||
<tr>
|
|
||||||
<td class="hourOfDay">
|
|
||||||
<var:entity name="nbsp" />
|
|
||||||
</td>
|
|
||||||
<td class="day" width="90%">
|
|
||||||
<var:foreach list="allDayApts" item="appointment">
|
|
||||||
<var:component className="UIxCaaaaalInlineAptView"
|
|
||||||
appointment="appointment"
|
|
||||||
formatter="aptFormatter"
|
|
||||||
tooltipFormatter="aptTooltipFormatter"
|
|
||||||
url="appointmentViewURL"
|
|
||||||
const:style="dayoverview"
|
|
||||||
queryDictionary="currentDateQueryParameters"
|
|
||||||
referenceDate="selectedDate"
|
|
||||||
canAccess="canAccessApt"
|
|
||||||
/>
|
|
||||||
</var:foreach>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</var:foreach> -->
|
|
||||||
|
|
||||||
<!-- <var:foreach list="rangesOf7Days" item="currentRangeOf7Days">
|
|
||||||
<tr>
|
|
||||||
<var:foreach list="currentRangeOf7Days" item="currentTableDay"
|
|
||||||
><td var:class="dayCellClasses"
|
|
||||||
var:day="currentTableDay.shortDateString"
|
|
||||||
const:hour="0800"
|
|
||||||
><div class="dayContent"><span class="dayCellLabel"
|
|
||||||
><var:string value="labelForCurrentDayCell" /></span
|
|
||||||
><br /><var:foreach
|
|
||||||
list="aptsForCurrentDate"
|
|
||||||
item="appointment"
|
|
||||||
><var:component className="UIxCalInlineAptxxxxView"
|
|
||||||
appointment="appointment"
|
|
||||||
formatter="monthAptFormatter"
|
|
||||||
tooltipFormatter="aptTooltipFormatter"
|
|
||||||
url="appointmentViewURL"
|
|
||||||
const:style="dayoverview"
|
|
||||||
queryDictionary="currentDayQueryParameters"
|
|
||||||
referenceDate="currentTableDay"
|
|
||||||
canAccess="canAccessApt"
|
|
||||||
/>
|
|
||||||
</var:foreach></div></td>
|
|
||||||
</var:foreach>
|
|
||||||
</tr>
|
|
||||||
</var:foreach>
|
|
||||||
</table> -->
|
|
||||||
|
|
|
@ -10,16 +10,19 @@ var showCompletedTasks = 0;
|
||||||
var currentDay = '';
|
var currentDay = '';
|
||||||
var currentView = "weekview";
|
var currentView = "weekview";
|
||||||
|
|
||||||
var cachedDateSelectors = new Array();
|
var cachedDateSelectors = [];
|
||||||
|
|
||||||
var contactSelectorAction = 'calendars-contacts';
|
var contactSelectorAction = 'calendars-contacts';
|
||||||
|
|
||||||
var eventsToDelete = new Array();
|
var eventsToDelete = [];
|
||||||
var calendarsOfEventsToDelete = new Array();
|
var calendarsOfEventsToDelete = [];
|
||||||
|
|
||||||
var usersRightsWindowHeight = 250;
|
var usersRightsWindowHeight = 250;
|
||||||
var usersRightsWindowWidth = 502;
|
var usersRightsWindowWidth = 502;
|
||||||
|
|
||||||
|
var eventsBlocks;
|
||||||
|
var calendarEvents = null;
|
||||||
|
|
||||||
function newEvent(sender, type) {
|
function newEvent(sender, type) {
|
||||||
var day = $(sender).readAttribute("day");
|
var day = $(sender).readAttribute("day");
|
||||||
if (!day)
|
if (!day)
|
||||||
|
@ -34,7 +37,7 @@ function newEvent(sender, type) {
|
||||||
folderID = "/personal";
|
folderID = "/personal";
|
||||||
}
|
}
|
||||||
var urlstr = ApplicationBaseURL + folderID + "/new" + type;
|
var urlstr = ApplicationBaseURL + folderID + "/new" + type;
|
||||||
var params = new Array();
|
var params = [];
|
||||||
if (day)
|
if (day)
|
||||||
params.push("day=" + day);
|
params.push("day=" + day);
|
||||||
if (hour)
|
if (hour)
|
||||||
|
@ -67,7 +70,7 @@ function onMenuNewTaskClick(event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function _editEventId(id, calendar) {
|
function _editEventId(id, calendar) {
|
||||||
var urlstr = ApplicationBaseURL + "/" + calendar + "/" + id + "/edit";
|
var urlstr = ApplicationBaseURL + calendar + "/" + id + "/edit";
|
||||||
var targetname = "SOGo_edit_" + id;
|
var targetname = "SOGo_edit_" + id;
|
||||||
var win = window.open(urlstr, "_blank",
|
var win = window.open(urlstr, "_blank",
|
||||||
"width=490,height=470,resizable=0");
|
"width=490,height=470,resizable=0");
|
||||||
|
@ -100,7 +103,7 @@ function editEvent() {
|
||||||
function _batchDeleteEvents() {
|
function _batchDeleteEvents() {
|
||||||
var events = eventsToDelete.shift();
|
var events = eventsToDelete.shift();
|
||||||
var calendar = calendarsOfEventsToDelete.shift();
|
var calendar = calendarsOfEventsToDelete.shift();
|
||||||
var urlstr = (ApplicationBaseURL + "/" + calendar
|
var urlstr = (ApplicationBaseURL + calendar
|
||||||
+ "/batchDelete?ids=" + events.join('/'));
|
+ "/batchDelete?ids=" + events.join('/'));
|
||||||
document.deleteEventAjaxRequest = triggerAjaxRequest(urlstr,
|
document.deleteEventAjaxRequest = triggerAjaxRequest(urlstr,
|
||||||
deleteEventCallback,
|
deleteEventCallback,
|
||||||
|
@ -123,13 +126,13 @@ function deleteEvent() {
|
||||||
document.deleteEventAjaxRequest.aborted = true;
|
document.deleteEventAjaxRequest.aborted = true;
|
||||||
document.deleteEventAjaxRequest.abort();
|
document.deleteEventAjaxRequest.abort();
|
||||||
}
|
}
|
||||||
var sortedNodes = new Array();
|
var sortedNodes = [];
|
||||||
var calendars = new Array();
|
var calendars = [];
|
||||||
|
|
||||||
for (var i = 0; i < nodes.length; i++) {
|
for (var i = 0; i < nodes.length; i++) {
|
||||||
var calendar = nodes[i].calendar;
|
var calendar = nodes[i].calendar;
|
||||||
if (!sortedNodes[calendar]) {
|
if (!sortedNodes[calendar]) {
|
||||||
sortedNodes[calendar] = new Array();
|
sortedNodes[calendar] = [];
|
||||||
calendars.push(calendar);
|
calendars.push(calendar);
|
||||||
}
|
}
|
||||||
sortedNodes[calendar].push(nodes[i].cname);
|
sortedNodes[calendar].push(nodes[i].cname);
|
||||||
|
@ -228,19 +231,41 @@ function deleteEventCallback(http) {
|
||||||
_batchDeleteEvents();
|
_batchDeleteEvents();
|
||||||
else {
|
else {
|
||||||
document.deleteEventAjaxRequest = null;
|
document.deleteEventAjaxRequest = null;
|
||||||
if (isTask)
|
|
||||||
refreshTasks();
|
|
||||||
else {
|
|
||||||
refreshEvents();
|
|
||||||
changeCalendarDisplay();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (isTask)
|
||||||
|
deleteTasksFromViews(nodes);
|
||||||
|
else
|
||||||
|
deleteEventsFromViews(nodes)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
log ("deleteEventCallback Ajax error");
|
log ("deleteEventCallback Ajax error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteTasksFromViews(tasks) {
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteEventsFromViews(events) {
|
||||||
|
if (calendarEvents) {
|
||||||
|
for (var i = 0; i < events.length; i++) {
|
||||||
|
var cname = events[i];
|
||||||
|
var event = calendarEvents[cname];
|
||||||
|
if (event) {
|
||||||
|
if (event.siblings) {
|
||||||
|
for (var j = 0; j < event.siblings.length; j++) {
|
||||||
|
var eventDiv = event.siblings[j];
|
||||||
|
eventDiv.parentNode.removeChild(eventDiv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete calendarEvents[cname]
|
||||||
|
}
|
||||||
|
var row = $(cname);
|
||||||
|
if (row)
|
||||||
|
row.parentNode.removeChild(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function editDoubleClickedEvent(event) {
|
function editDoubleClickedEvent(event) {
|
||||||
_editEventId(this.cname, this.calendar);
|
_editEventId(this.cname, this.calendar);
|
||||||
|
|
||||||
|
@ -364,12 +389,12 @@ function eventsListCallback(http) {
|
||||||
td = $(document.createElement("td"));
|
td = $(document.createElement("td"));
|
||||||
row.appendChild(td);
|
row.appendChild(td);
|
||||||
td.observe("mousedown", listRowMouseDownHandler, true);
|
td.observe("mousedown", listRowMouseDownHandler, true);
|
||||||
td.appendChild(document.createTextNode(data[i][10]));
|
td.appendChild(document.createTextNode(data[i][11]));
|
||||||
|
|
||||||
td = $(document.createElement("td"));
|
td = $(document.createElement("td"));
|
||||||
row.appendChild(td);
|
row.appendChild(td);
|
||||||
td.observe("mousedown", listRowMouseDownHandler, true);
|
td.observe("mousedown", listRowMouseDownHandler, true);
|
||||||
td.appendChild(document.createTextNode(data[i][11]));
|
td.appendChild(document.createTextNode(data[i][12]));
|
||||||
|
|
||||||
td = $(document.createElement("td"));
|
td = $(document.createElement("td"));
|
||||||
row.appendChild(td);
|
row.appendChild(td);
|
||||||
|
@ -603,10 +628,8 @@ function scrollDayView(scrollEvent) {
|
||||||
var divs;
|
var divs;
|
||||||
|
|
||||||
// Select event in calendar view
|
// Select event in calendar view
|
||||||
if (scrollEvent) {
|
if (scrollEvent)
|
||||||
divs = $$("div#calendarContent div." + eventClass(scrollEvent));
|
selectCalendarEvent(scrollEvent);
|
||||||
selectCalendarEvent(divs[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't scroll if in month view
|
// Don't scroll if in month view
|
||||||
if (currentView == "monthview")
|
if (currentView == "monthview")
|
||||||
|
@ -614,22 +637,23 @@ function scrollDayView(scrollEvent) {
|
||||||
|
|
||||||
var offset = 0;
|
var offset = 0;
|
||||||
var daysView = $("daysView");
|
var daysView = $("daysView");
|
||||||
var hours =
|
var hours = $(daysView.childNodesWithTag("div")[0])
|
||||||
$(daysView.childNodesWithTag("div")[0]).childNodesWithTag("div");
|
.childNodesWithTag("div");
|
||||||
|
|
||||||
if (scrollEvent) {
|
// Scroll to 8 AM by default
|
||||||
divs = $$("div#calendarContent div." + eventClass(scrollEvent));
|
offset = hours[8].offsetTop;
|
||||||
var classes = $w(divs[0].className);
|
|
||||||
for (var i = 0; i < classes.length; i++) {
|
if (scrollEvent && calendarEvents) {
|
||||||
if (classes[i].startsWith("starts")) {
|
var event = calendarEvents[scrollEvent];
|
||||||
var starts = Math.floor(parseInt(classes[i].substr(6)) / 4);
|
if (event) {
|
||||||
offset = hours[starts].offsetTop;
|
var classes = $w(event.siblings[0].className);
|
||||||
}
|
for (var i = 0; i < classes.length; i++)
|
||||||
|
if (classes[i].startsWith("starts")) {
|
||||||
|
var starts = Math.floor(parseInt(classes[i].substr(6)) / 4);
|
||||||
|
offset = hours[starts].offsetTop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
// Scroll to 8 AM
|
|
||||||
offset = hours[8].offsetTop;
|
|
||||||
|
|
||||||
daysView.scrollTop = offset - 5;
|
daysView.scrollTop = offset - 5;
|
||||||
}
|
}
|
||||||
|
@ -684,7 +708,8 @@ function refreshCalendarEvents(scrollEvent) {
|
||||||
document.refreshCalendarEventsAjaxRequest.aborted = true;
|
document.refreshCalendarEventsAjaxRequest.aborted = true;
|
||||||
document.refreshCalendarEventsAjaxRequest.abort();
|
document.refreshCalendarEventsAjaxRequest.abort();
|
||||||
}
|
}
|
||||||
var url = ApplicationBaseURL + "eventslist?sd=" + sd + "&ed=" + ed;
|
var url = (ApplicationBaseURL + "eventsblocks?sd=" + sd + "&ed=" + ed
|
||||||
|
+ "&view=" + currentView);
|
||||||
document.refreshCalendarEventsAjaxRequest
|
document.refreshCalendarEventsAjaxRequest
|
||||||
= triggerAjaxRequest(url, refreshCalendarEventsCallback,
|
= triggerAjaxRequest(url, refreshCalendarEventsCallback,
|
||||||
{"startDate": sd, "endDate": ed,
|
{"startDate": sd, "endDate": ed,
|
||||||
|
@ -695,142 +720,13 @@ function refreshCalendarEventsCallback(http) {
|
||||||
if (http.readyState == 4
|
if (http.readyState == 4
|
||||||
&& http.status == 200) {
|
&& http.status == 200) {
|
||||||
if (http.responseText.length > 0) {
|
if (http.responseText.length > 0) {
|
||||||
var data = http.responseText.evalJSON(true);
|
var eventsBlocks = http.responseText.evalJSON(true);
|
||||||
// log("refresh calendar events: " + data.length);
|
calendarEvents = _prepareCalendarEventsCache(eventsBlocks[0]);
|
||||||
var dateTuples = new Array();
|
if (currentView == "monthview")
|
||||||
for (var i = 0; i < data.length; i++) {
|
_drawMonthCalendarEvents(eventsBlocks[2]);
|
||||||
var dates = drawCalendarEvent(data[i],
|
else {
|
||||||
http.callbackData["startDate"],
|
_drawCalendarAllDaysEvents(eventsBlocks[1]);
|
||||||
http.callbackData["endDate"]);
|
_drawCalendarEvents(eventsBlocks[2]);
|
||||||
dates.each(function(tuple) {
|
|
||||||
if (tuple[3] == 0) tuple[3] = 96;
|
|
||||||
dateTuples.push(tuple);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var c = {
|
|
||||||
div: 0,
|
|
||||||
day: 1,
|
|
||||||
start: 2,
|
|
||||||
end: 3,
|
|
||||||
siblingsCount: 4,
|
|
||||||
siblingsPosition: 5,
|
|
||||||
siblingsMaxCount: 6
|
|
||||||
};
|
|
||||||
for (var i = 0; i < dateTuples.length; i++) {
|
|
||||||
if (dateTuples[i].length < 6) {
|
|
||||||
dateTuples[i][c.siblingsCount] = 1;
|
|
||||||
dateTuples[i][c.siblingsPosition] = 0;
|
|
||||||
}
|
|
||||||
for (var j = 0; j < dateTuples.length; j++) {
|
|
||||||
if (j == i) continue;
|
|
||||||
if (dateTuples[i][c.day] == dateTuples[j][c.day]) {
|
|
||||||
// Same day
|
|
||||||
if (dateTuples[j][c.start] > dateTuples[i][c.start] &&
|
|
||||||
dateTuples[j][c.start] < dateTuples[i][c.end] ||
|
|
||||||
|
|
||||||
dateTuples[j][c.start] == dateTuples[i][c.start] &&
|
|
||||||
dateTuples[j][c.end] < dateTuples[i][c.end] ||
|
|
||||||
|
|
||||||
dateTuples[j][c.start] == dateTuples[i][c.start] &&
|
|
||||||
dateTuples[j][c.end] == dateTuples[i][c.end] &&
|
|
||||||
i < j) {
|
|
||||||
// Same period
|
|
||||||
if (dateTuples[j].length < 6) {
|
|
||||||
dateTuples[j][c.siblingsCount] = 2;
|
|
||||||
dateTuples[j][c.siblingsPosition] = dateTuples[i][c.siblingsPosition] + 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dateTuples[j][c.siblingsCount]++;
|
|
||||||
dateTuples[j][c.siblingsPosition]++;
|
|
||||||
}
|
|
||||||
dateTuples[i][c.siblingsCount]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Second loop; adjust total number of siblings for each event
|
|
||||||
for (var i = 0; i < dateTuples.length; i++) {
|
|
||||||
//log (i + " " + dateTuples[i].inspect());
|
|
||||||
var maxCount = 0;
|
|
||||||
for (var j = 0; j < dateTuples.length; j++) {
|
|
||||||
if (j == i) continue;
|
|
||||||
if (dateTuples[i][c.day] == dateTuples[j][c.day]) {
|
|
||||||
// Same day
|
|
||||||
if (dateTuples[j][c.start] > dateTuples[i][c.start] &&
|
|
||||||
dateTuples[j][c.start] < dateTuples[i][c.end] ||
|
|
||||||
|
|
||||||
dateTuples[j][c.start] == dateTuples[i][c.start] &&
|
|
||||||
dateTuples[j][c.end] < dateTuples[i][c.end] ||
|
|
||||||
|
|
||||||
dateTuples[j][c.start] == dateTuples[i][c.start] &&
|
|
||||||
dateTuples[j][c.end] == dateTuples[i][c.end] &&
|
|
||||||
i < j) {
|
|
||||||
// Same period
|
|
||||||
if (dateTuples[j][c.siblingsCount] > maxCount)
|
|
||||||
maxCount = dateTuples[j][c.siblingsCount];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (maxCount > 0) {
|
|
||||||
dateTuples[i][c.siblingsCount] = maxCount;
|
|
||||||
dateTuples[i][c.siblingsMaxCount] = maxCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Third loop; adjust position and total number of siblings for each event
|
|
||||||
for (var i = 0; i < dateTuples.length; i++) {
|
|
||||||
//log (i + " " + dateTuples[i].inspect());
|
|
||||||
for (var j = 0; j < dateTuples.length; j++) {
|
|
||||||
if (j == i) continue;
|
|
||||||
if (dateTuples[i][c.day] == dateTuples[j][c.day]) {
|
|
||||||
// Same day
|
|
||||||
if (dateTuples[j][c.start] > dateTuples[i][c.start] &&
|
|
||||||
dateTuples[j][c.start] < dateTuples[i][c.end] ||
|
|
||||||
|
|
||||||
dateTuples[j][c.start] == dateTuples[i][c.start] &&
|
|
||||||
dateTuples[j][c.end] < dateTuples[i][c.end] ||
|
|
||||||
|
|
||||||
dateTuples[j][c.start] == dateTuples[i][c.start] &&
|
|
||||||
dateTuples[j][c.end] == dateTuples[i][c.end] &&
|
|
||||||
i < j) {
|
|
||||||
// Overlapping period
|
|
||||||
if (dateTuples[j][c.siblingsPosition] == dateTuples[i][c.siblingsPosition]) {
|
|
||||||
// Same position
|
|
||||||
dateTuples[j][c.siblingsPosition]--; // not very clever
|
|
||||||
}
|
|
||||||
if (dateTuples[j].length < 7 ||
|
|
||||||
dateTuples[j][c.siblingsMaxCount] < dateTuples[i][c.siblingsMaxCount])
|
|
||||||
dateTuples[j][c.siblingsMaxCount] = dateTuples[i][c.siblingsMaxCount];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dateTuples[i].length < 7)
|
|
||||||
dateTuples[i][c.siblingsMaxCount] = dateTuples[i][c.siblingsCount];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Final loop; draw the events
|
|
||||||
//log ("[div, day, start index, end index, siblings count, siblings position, siblings max count]");
|
|
||||||
for (var i = 0; i < dateTuples.length; i++) {
|
|
||||||
//log (i + " " + dateTuples[i].inspect());
|
|
||||||
|
|
||||||
var base = dateTuples[i][c.siblingsCount] * dateTuples[i][c.siblingsMaxCount];
|
|
||||||
var length = 1;
|
|
||||||
var maxLength = 1 * dateTuples[i][c.siblingsMaxCount];
|
|
||||||
|
|
||||||
for (var j = dateTuples[i][c.siblingsCount];
|
|
||||||
j < maxLength;
|
|
||||||
j += dateTuples[i][c.siblingsCount]) { }
|
|
||||||
|
|
||||||
if (j > maxLength) {
|
|
||||||
j -= dateTuples[i][c.siblingsCount];
|
|
||||||
}
|
|
||||||
|
|
||||||
var width = 100 * j / base;
|
|
||||||
var left = width * dateTuples[i][c.siblingsPosition];
|
|
||||||
dateTuples[i][0].setStyle({ width: width + "%",
|
|
||||||
left: left + "%" });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scrollDayView(http.callbackData["scrollEvent"]);
|
scrollDayView(http.callbackData["scrollEvent"]);
|
||||||
|
@ -839,133 +735,42 @@ function refreshCalendarEventsCallback(http) {
|
||||||
log("AJAX error when refreshing calendar events");
|
log("AJAX error when refreshing calendar events");
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawCalendarEvent(eventData, sd, ed) {
|
function _prepareCalendarEventsCache(events) {
|
||||||
var dateTuples = new Array();
|
var cache = {};
|
||||||
|
|
||||||
// log ("drawCalendarEvent...");
|
for (var i = 0; i < events.length; i++) {
|
||||||
var viewStartDate = sd.asDate();
|
cache[events[i][0]] = events[i];
|
||||||
var viewEndDate = ed.asDate();
|
}
|
||||||
|
|
||||||
var startDate = new Date();
|
return cache;
|
||||||
startDate.setTime(eventData[4] * 1000);
|
}
|
||||||
var endDate = new Date();
|
|
||||||
endDate.setTime(eventData[5] * 1000);
|
|
||||||
|
|
||||||
// log ("s: " + startDate + "; e: " + endDate);
|
function _drawCalendarAllDaysEvents(events) {
|
||||||
|
var daysView = $("calendarHeader");
|
||||||
var days = startDate.daysUpTo(endDate);
|
var subdivs = daysView.childNodesWithTag("div");
|
||||||
|
var days = subdivs[1].childNodesWithTag("div");
|
||||||
var title;
|
for (var i = 0; i < events.length; i++) {
|
||||||
if (currentView == "monthview"
|
var parentDiv = days[i];
|
||||||
&& (eventData[7] == 0))
|
for (var j = 0; j < events[i].length; j++) {
|
||||||
title = startDate.getDisplayHoursString() + " " + eventData[3];
|
var eventRep = events[i][j];
|
||||||
else
|
var eventDiv = newAllDayEventDIV(eventRep);
|
||||||
title = eventData[3];
|
parentDiv.appendChild(eventDiv);
|
||||||
|
|
||||||
// log("title: " + title);
|
|
||||||
// log("viewS: " + viewStartDate);
|
|
||||||
var startHour = null;
|
|
||||||
var endHour = null;
|
|
||||||
|
|
||||||
var siblings = new Array();
|
|
||||||
for (var i = 0; i < days.length; i++)
|
|
||||||
if (days[i].earlierDate(viewStartDate) == viewStartDate
|
|
||||||
&& days[i].laterDate(viewEndDate) == viewEndDate) {
|
|
||||||
var starts;
|
|
||||||
|
|
||||||
// log("day: " + days[i]);
|
|
||||||
if (i == 0) {
|
|
||||||
var quarters = (startDate.getUTCHours() * 4
|
|
||||||
+ Math.floor(startDate.getUTCMinutes() / 15));
|
|
||||||
starts = quarters;
|
|
||||||
startHour = startDate.getDisplayHoursString();
|
|
||||||
endHour = endDate.getDisplayHoursString();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
starts = 0;
|
|
||||||
|
|
||||||
var ends;
|
|
||||||
var lasts;
|
|
||||||
if (i == days.length - 1) {
|
|
||||||
var quarters = (endDate.getUTCHours() * 4
|
|
||||||
+ Math.ceil(endDate.getUTCMinutes() / 15));
|
|
||||||
ends = quarters;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ends = 96;
|
|
||||||
lasts = ends - starts;
|
|
||||||
if (!lasts)
|
|
||||||
lasts = 1;
|
|
||||||
|
|
||||||
var eventDiv = newEventDIV(eventData[0], eventData[1], starts, lasts,
|
|
||||||
null, null, title);
|
|
||||||
siblings.push(eventDiv);
|
|
||||||
eventDiv.siblings = siblings;
|
|
||||||
if (eventData[9].length > 0)
|
|
||||||
eventDiv.addClassName(eventData[9]); // event owner status
|
|
||||||
//eventDiv.setStyle({ width: '50%' });
|
|
||||||
if (currentView != "monthview" &&
|
|
||||||
eventData[7] == 0) // not "all day"
|
|
||||||
dateTuples.push(new Array(eventDiv, days[i].getDayString(), starts, ends));
|
|
||||||
var dayString = days[i].getDayString();
|
|
||||||
// log("day: " + dayString);
|
|
||||||
var parentDiv = null;
|
|
||||||
if (currentView == "monthview") {
|
|
||||||
var dayDivs = $("monthDaysView").childNodesWithTag("div");
|
|
||||||
var j = 0;
|
|
||||||
while (!parentDiv && j < dayDivs.length) {
|
|
||||||
if (dayDivs[j].getAttribute("day") == dayString)
|
|
||||||
parentDiv = dayDivs[j];
|
|
||||||
else
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (eventData[7] == 0) {
|
|
||||||
var daysView = $("daysView");
|
|
||||||
var eventsDiv = $(daysView).childNodesWithTag("div")[1];
|
|
||||||
var dayDivs = $(eventsDiv).childNodesWithTag("div");
|
|
||||||
var j = 0;
|
|
||||||
while (!parentDiv && j < dayDivs.length) {
|
|
||||||
if (dayDivs[j].getAttribute("day") == dayString)
|
|
||||||
parentDiv = dayDivs[j].childNodesWithTag("div")[0];
|
|
||||||
else
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var header = $("calendarHeader");
|
|
||||||
var daysDiv = $(header).childNodesWithTag("div")[1];
|
|
||||||
var dayDivs = $(daysDiv).childNodesWithTag("div");
|
|
||||||
var j = 0;
|
|
||||||
while (!parentDiv && j < dayDivs.length) {
|
|
||||||
if (dayDivs[j].getAttribute("day") == dayString)
|
|
||||||
parentDiv = dayDivs[j];
|
|
||||||
else
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (parentDiv)
|
|
||||||
parentDiv.appendChild(eventDiv);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return dateTuples;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function eventClass(cname) {
|
function newAllDayEventDIV(eventRep) {
|
||||||
return escape(cname.replace(".", "-"));
|
// cname, calendar, starts, lasts,
|
||||||
}
|
// startHour, endHour, title) {
|
||||||
|
|
||||||
function newEventDIV(cname, calendar, starts, lasts,
|
|
||||||
startHour, endHour, title) {
|
|
||||||
var eventDiv = document.createElement("div");
|
var eventDiv = document.createElement("div");
|
||||||
eventDiv.cname = escape(cname);
|
var event = calendarEvents[eventRep.cname];
|
||||||
eventDiv.calendar = calendar;
|
if (!event.siblings)
|
||||||
|
event.siblings = [];
|
||||||
|
eventDiv.event = event;
|
||||||
|
eventDiv.cname = event[0];
|
||||||
|
eventDiv.calendar = event[1];
|
||||||
|
|
||||||
$(eventDiv).addClassName("event");
|
$(eventDiv).addClassName("event");
|
||||||
$(eventDiv).addClassName(eventClass(cname));
|
|
||||||
$(eventDiv).addClassName("starts" + starts);
|
|
||||||
$(eventDiv).addClassName("lasts" + lasts);
|
|
||||||
for (var i = 1; i < 5; i++) {
|
for (var i = 1; i < 5; i++) {
|
||||||
var shadowDiv = document.createElement("div");
|
var shadowDiv = document.createElement("div");
|
||||||
eventDiv.appendChild(shadowDiv);
|
eventDiv.appendChild(shadowDiv);
|
||||||
|
@ -975,7 +780,7 @@ function newEventDIV(cname, calendar, starts, lasts,
|
||||||
var innerDiv = document.createElement("div");
|
var innerDiv = document.createElement("div");
|
||||||
eventDiv.appendChild(innerDiv);
|
eventDiv.appendChild(innerDiv);
|
||||||
$(innerDiv).addClassName("eventInside");
|
$(innerDiv).addClassName("eventInside");
|
||||||
$(innerDiv).addClassName("calendarFolder" + calendar);
|
$(innerDiv).addClassName("calendarFolder" + event[1]);
|
||||||
|
|
||||||
var gradientDiv = document.createElement("div");
|
var gradientDiv = document.createElement("div");
|
||||||
innerDiv.appendChild(gradientDiv);
|
innerDiv.appendChild(gradientDiv);
|
||||||
|
@ -987,20 +792,151 @@ function newEventDIV(cname, calendar, starts, lasts,
|
||||||
var textDiv = document.createElement("div");
|
var textDiv = document.createElement("div");
|
||||||
innerDiv.appendChild(textDiv);
|
innerDiv.appendChild(textDiv);
|
||||||
$(textDiv).addClassName("text");
|
$(textDiv).addClassName("text");
|
||||||
if (startHour) {
|
textDiv.appendChild(document.createTextNode(event[3]));
|
||||||
var headerSpan = document.createElement("span");
|
|
||||||
textDiv.appendChild(headerSpan);
|
|
||||||
$(headerSpan).addClassName("eventHeader");
|
|
||||||
headerSpan.appendChild(document.createTextNode(startHour + " - "
|
|
||||||
+ endHour));
|
|
||||||
textDiv.appendChild(document.createElement("br"));
|
|
||||||
}
|
|
||||||
textDiv.appendChild(document.createTextNode(title));
|
|
||||||
|
|
||||||
eventDiv.observe("mousedown", listRowMouseDownHandler);
|
eventDiv.observe("mousedown", listRowMouseDownHandler);
|
||||||
eventDiv.observe("click", onCalendarSelectEvent);
|
eventDiv.observe("click", onCalendarSelectEvent);
|
||||||
eventDiv.observe("dblclick", editDoubleClickedEvent);
|
eventDiv.observe("dblclick", editDoubleClickedEvent);
|
||||||
|
|
||||||
|
event.siblings.push(eventDiv);
|
||||||
|
|
||||||
|
return eventDiv;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _drawCalendarEvents(events) {
|
||||||
|
var daysView = $("daysView");
|
||||||
|
var subdivs = daysView.childNodesWithTag("div");
|
||||||
|
var days = subdivs[1].childNodesWithTag("div");
|
||||||
|
for (var i = 0; i < events.length; i++) {
|
||||||
|
var parentDiv = days[i].childNodesWithTag("div")[0];
|
||||||
|
for (var j = 0; j < events[i].length; j++) {
|
||||||
|
var eventRep = events[i][j];
|
||||||
|
var eventDiv = newEventDIV(eventRep);
|
||||||
|
parentDiv.appendChild(eventDiv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function newEventDIV(eventRep) {
|
||||||
|
// cname, calendar, starts, lasts,
|
||||||
|
// startHour, endHour, title) {
|
||||||
|
var eventDiv = document.createElement("div");
|
||||||
|
var event = calendarEvents[eventRep.cname];
|
||||||
|
if (!event.siblings)
|
||||||
|
event.siblings = [];
|
||||||
|
eventDiv.event = event;
|
||||||
|
eventDiv.cname = event[0];
|
||||||
|
eventDiv.calendar = event[1];
|
||||||
|
|
||||||
|
$(eventDiv).addClassName("event");
|
||||||
|
// $(eventDiv).addClassName(eventClass(cname));
|
||||||
|
$(eventDiv).addClassName("starts" + eventRep.start);
|
||||||
|
$(eventDiv).addClassName("lasts" + eventRep.length);
|
||||||
|
for (var i = 1; i < 5; i++) {
|
||||||
|
var shadowDiv = document.createElement("div");
|
||||||
|
eventDiv.appendChild(shadowDiv);
|
||||||
|
$(shadowDiv).addClassName("shadow");
|
||||||
|
$(shadowDiv).addClassName("shadow" + i);
|
||||||
|
}
|
||||||
|
var innerDiv = document.createElement("div");
|
||||||
|
eventDiv.appendChild(innerDiv);
|
||||||
|
$(innerDiv).addClassName("eventInside");
|
||||||
|
$(innerDiv).addClassName("calendarFolder" + event[1]);
|
||||||
|
|
||||||
|
var gradientDiv = document.createElement("div");
|
||||||
|
innerDiv.appendChild(gradientDiv);
|
||||||
|
$(gradientDiv).addClassName("gradient");
|
||||||
|
var gradientImg = document.createElement("img");
|
||||||
|
gradientDiv.appendChild(gradientImg);
|
||||||
|
gradientImg.src = ResourcesURL + "/event-gradient.png";
|
||||||
|
|
||||||
|
var textDiv = document.createElement("div");
|
||||||
|
innerDiv.appendChild(textDiv);
|
||||||
|
$(textDiv).addClassName("text");
|
||||||
|
// if (startHour) {
|
||||||
|
// var headerSpan = document.createElement("span");
|
||||||
|
// textDiv.appendChild(headerSpan);
|
||||||
|
// $(headerSpan).addClassName("eventHeader");
|
||||||
|
// headerSpan.appendChild(document.createTextNode(startHour + " - "
|
||||||
|
// + endHour));
|
||||||
|
// textDiv.appendChild(document.createElement("br"));
|
||||||
|
// }
|
||||||
|
textDiv.appendChild(document.createTextNode(event[3]));
|
||||||
|
|
||||||
|
var pc = 100 / eventRep.siblings;
|
||||||
|
eventDiv.style.width = pc + "%";
|
||||||
|
var left = eventRep.position * pc;
|
||||||
|
eventDiv.style.left = left + "%";
|
||||||
|
|
||||||
|
eventDiv.observe("mousedown", listRowMouseDownHandler);
|
||||||
|
eventDiv.observe("click", onCalendarSelectEvent);
|
||||||
|
eventDiv.observe("dblclick", editDoubleClickedEvent);
|
||||||
|
|
||||||
|
event.siblings.push(eventDiv);
|
||||||
|
|
||||||
|
return eventDiv;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _drawMonthCalendarEvents(events) {
|
||||||
|
var daysView = $("monthDaysView");
|
||||||
|
var days = daysView.childNodesWithTag("div");
|
||||||
|
for (var i = 0; i < days.length; i++) {
|
||||||
|
var parentDiv = days[i];
|
||||||
|
for (var j = 0; j < events[i].length; j++) {
|
||||||
|
var eventRep = events[i][j];
|
||||||
|
var eventDiv = newMonthEventDIV(eventRep);
|
||||||
|
parentDiv.appendChild(eventDiv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function newMonthEventDIV(eventRep) {
|
||||||
|
// cname, calendar, starts, lasts,
|
||||||
|
// startHour, endHour, title) {
|
||||||
|
var eventDiv = document.createElement("div");
|
||||||
|
var event = calendarEvents[eventRep.cname];
|
||||||
|
if (!event.siblings)
|
||||||
|
event.siblings = [];
|
||||||
|
eventDiv.event = event;
|
||||||
|
eventDiv.cname = event[0];
|
||||||
|
eventDiv.calendar = event[1];
|
||||||
|
|
||||||
|
$(eventDiv).addClassName("event");
|
||||||
|
for (var i = 1; i < 5; i++) {
|
||||||
|
var shadowDiv = document.createElement("div");
|
||||||
|
eventDiv.appendChild(shadowDiv);
|
||||||
|
$(shadowDiv).addClassName("shadow");
|
||||||
|
$(shadowDiv).addClassName("shadow" + i);
|
||||||
|
}
|
||||||
|
var innerDiv = document.createElement("div");
|
||||||
|
eventDiv.appendChild(innerDiv);
|
||||||
|
$(innerDiv).addClassName("eventInside");
|
||||||
|
$(innerDiv).addClassName("calendarFolder" + event[1]);
|
||||||
|
|
||||||
|
var gradientDiv = document.createElement("div");
|
||||||
|
innerDiv.appendChild(gradientDiv);
|
||||||
|
$(gradientDiv).addClassName("gradient");
|
||||||
|
var gradientImg = document.createElement("img");
|
||||||
|
gradientDiv.appendChild(gradientImg);
|
||||||
|
gradientImg.src = ResourcesURL + "/event-gradient.png";
|
||||||
|
|
||||||
|
var textDiv = document.createElement("div");
|
||||||
|
innerDiv.appendChild(textDiv);
|
||||||
|
$(textDiv).addClassName("textw");
|
||||||
|
|
||||||
|
var eventText;
|
||||||
|
if (event[7])
|
||||||
|
eventText = event[3];
|
||||||
|
else
|
||||||
|
eventText = eventRep.starthour + " - " + event[3];
|
||||||
|
textDiv.appendChild(document.createTextNode(eventText));
|
||||||
|
|
||||||
|
eventDiv.observe("mousedown", listRowMouseDownHandler);
|
||||||
|
eventDiv.observe("click", onCalendarSelectEvent);
|
||||||
|
eventDiv.observe("dblclick", editDoubleClickedEvent);
|
||||||
|
|
||||||
|
event.siblings.push(eventDiv);
|
||||||
|
|
||||||
return eventDiv;
|
return eventDiv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1021,7 +957,7 @@ function calendarDisplayCallback(http) {
|
||||||
contentView = $("calendarContent");
|
contentView = $("calendarContent");
|
||||||
else
|
else
|
||||||
contentView = $("daysView");
|
contentView = $("daysView");
|
||||||
|
|
||||||
refreshCalendarEvents(http.callbackData.scrollEvent);
|
refreshCalendarEvents(http.callbackData.scrollEvent);
|
||||||
|
|
||||||
var days = document.getElementsByClassName("day", contentView);
|
var days = document.getElementsByClassName("day", contentView);
|
||||||
|
@ -1270,22 +1206,30 @@ function onYearMenuItemClick(event) {
|
||||||
changeDateSelectorDisplay(year + month + "01", true);
|
changeDateSelectorDisplay(year + month + "01", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectCalendarEvent(div) {
|
function selectCalendarEvent(cname) {
|
||||||
// Select event in calendar view
|
// Select event in calendar view
|
||||||
if (selectedCalendarCell)
|
if (selectedCalendarCell)
|
||||||
for (var i = 0; i < selectedCalendarCell.length; i++)
|
for (var i = 0; i < selectedCalendarCell.length; i++)
|
||||||
selectedCalendarCell[i].deselect();
|
selectedCalendarCell[i].deselect();
|
||||||
|
|
||||||
for (var i = 0; i < div.siblings.length; i++)
|
if (calendarEvents) {
|
||||||
div.siblings[i].selectElement();
|
var event = calendarEvents[cname];
|
||||||
|
// if (event) {
|
||||||
selectedCalendarCell = div.siblings;
|
// if (event[12])
|
||||||
|
// log("recurrence; date=" + event[4]);
|
||||||
|
// }
|
||||||
|
if (event && event.siblings) {
|
||||||
|
for (var i = 0; i < event.siblings.length; i++)
|
||||||
|
event.siblings[i].selectElement();
|
||||||
|
selectedCalendarCell = event.siblings;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onCalendarSelectEvent() {
|
function onCalendarSelectEvent() {
|
||||||
var list = $("eventsList");
|
var list = $("eventsList");
|
||||||
|
|
||||||
selectCalendarEvent(this);
|
selectCalendarEvent(this.cname);
|
||||||
|
|
||||||
// Select event in events list
|
// Select event in events list
|
||||||
$(list.tBodies[0]).deselectAll();
|
$(list.tBodies[0]).deselectAll();
|
||||||
|
@ -1298,11 +1242,7 @@ function onCalendarSelectEvent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function onCalendarSelectDay(event) {
|
function onCalendarSelectDay(event) {
|
||||||
var day;
|
var day = this.getAttribute("day");
|
||||||
if (currentView == "multicolumndayview")
|
|
||||||
day = this.getAttribute("day");
|
|
||||||
else
|
|
||||||
day = this.getAttribute("day");
|
|
||||||
var needRefresh = (listFilter == 'view_selectedday'
|
var needRefresh = (listFilter == 'view_selectedday'
|
||||||
&& day != currentDay);
|
&& day != currentDay);
|
||||||
|
|
||||||
|
@ -1322,22 +1262,23 @@ function onCalendarSelectDay(event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeWeekCalendarDisplayOfSelectedDay(node) {
|
function changeWeekCalendarDisplayOfSelectedDay(node) {
|
||||||
var days = document.getElementsByClassName("day", node.parentNode);
|
var daysView = $("daysView");
|
||||||
|
var daysDiv = daysView.childNodesWithTag("div");
|
||||||
|
var days = daysDiv[1].childNodesWithTag("div");
|
||||||
var headerDiv = $("calendarHeader").childNodesWithTag("div")[1];
|
var headerDiv = $("calendarHeader").childNodesWithTag("div")[1];
|
||||||
var headerDays = document.getElementsByClassName("day", headerDiv);
|
var headerDays = $(headerDiv).childNodesWithTag("div");
|
||||||
|
|
||||||
// log ("days: " + days.length + "; headerDays: " + headerDays.length);
|
for (var i = 0; i < days.length; i++) {
|
||||||
for (var i = 0; i < days.length; i++)
|
if (days[i] == node
|
||||||
if (days[i] != node) {
|
|| headerDays[i] == node) {
|
||||||
// log("unselect day : " + i);
|
|
||||||
headerDays[i].removeClassName("selectedDay");
|
|
||||||
days[i].removeClassName("selectedDay");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// log("selected day : " + i);
|
|
||||||
headerDays[i].addClassName("selectedDay");
|
headerDays[i].addClassName("selectedDay");
|
||||||
days[i].addClassName("selectedDay");
|
days[i].addClassName("selectedDay");
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
headerDays[i].removeClassName("selectedDay");
|
||||||
|
days[i].removeClassName("selectedDay");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function findMonthCalendarSelectedCell(daysContainer) {
|
function findMonthCalendarSelectedCell(daysContainer) {
|
||||||
|
@ -1400,7 +1341,7 @@ function updateTaskStatus(event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCalendarStatus(event) {
|
function updateCalendarStatus(event) {
|
||||||
var list = new Array();
|
var list = [];
|
||||||
var newStatus = (this.checked ? 1 : 0);
|
var newStatus = (this.checked ? 1 : 0);
|
||||||
|
|
||||||
if (isSafari() && !isSafari3()) {
|
if (isSafari() && !isSafari3()) {
|
||||||
|
@ -1525,12 +1466,12 @@ function onCalendarsMenuPrepareVisibility() {
|
||||||
function getMenus() {
|
function getMenus() {
|
||||||
var menus = {};
|
var menus = {};
|
||||||
|
|
||||||
var dateMenu = new Array();
|
var dateMenu = [];
|
||||||
for (var i = 0; i < 12; i++)
|
for (var i = 0; i < 12; i++)
|
||||||
dateMenu.push(onMonthMenuItemClick);
|
dateMenu.push(onMonthMenuItemClick);
|
||||||
menus["monthListMenu"] = dateMenu;
|
menus["monthListMenu"] = dateMenu;
|
||||||
|
|
||||||
dateMenu = new Array();
|
dateMenu = [];
|
||||||
for (var i = 0; i < 11; i++)
|
for (var i = 0; i < 11; i++)
|
||||||
dateMenu.push(onYearMenuItemClick);
|
dateMenu.push(onYearMenuItemClick);
|
||||||
menus["yearListMenu"] = dateMenu;
|
menus["yearListMenu"] = dateMenu;
|
||||||
|
@ -1830,7 +1771,7 @@ function initDateSelectorEvents() {
|
||||||
arrow.observe("click", onDateSelectorGotoMonth);
|
arrow.observe("click", onDateSelectorGotoMonth);
|
||||||
arrow = $("leftArrow");
|
arrow = $("leftArrow");
|
||||||
arrow.observe("click", onDateSelectorGotoMonth);
|
arrow.observe("click", onDateSelectorGotoMonth);
|
||||||
|
|
||||||
var menuButton = $("monthLabel");
|
var menuButton = $("monthLabel");
|
||||||
menuButton.observe("click", popupMonthMenu);
|
menuButton.observe("click", popupMonthMenu);
|
||||||
menuButton = $("yearLabel");
|
menuButton = $("yearLabel");
|
||||||
|
|
Loading…
Reference in New Issue