From: wolfgang Date: Tue, 12 Jun 2007 22:15:47 +0000 (+0000) Subject: git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1080 d1b88da0-ebda-0310... X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8477d0162a92327cd6f855c06f15700e6d2b97d3;p=scalable-opengroupware.org git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1080 d1b88da0-ebda-0310-925b-ed51d893ca5b --- diff --git a/ChangeLog b/ChangeLog index 6ded5d61..189cd503 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,71 @@ +2007-06-12 Wolfgang Sourdeau + + * SoObjects/Mailer/SOGoMailObject.m ([SOGoMailObject + -aclsForUser:uid]): implemented method by forwarding the request + to the container. This fixes a bug where users could no longer + read emails from shared folders. + + * SoObjects/Appointments/SOGoCalendarComponent.m + ([SOGoCalendarComponent -init]): "isNew" is no longer defined + here, but rather in its parent class. + + * UI/SOGoUI/SOGoDateFormatter.m ([SOGoDateFormatter + -stringForSecondsSinceThe70s:seconds]): new utility method. + + * UI/Scheduler/UIxCalListingActions.m ([UIxCalListingActions + -eventsListAction]): no longer reduce the end day of one day for + all day events since everything has been fixed in + OCSiCalFieldExtractor. + + * OGoContentStore/OCSiCalFieldExtractor.m ([OCSiCalFieldExtractor + -extractQuickFieldsFromEvent:_event]): reduce the seconds/70 of + the end date of all day events of 1 so that they stay on their + real last day. + +2007-06-11 Wolfgang Sourdeau + + * UI/Scheduler/UIxCalMonthView.m: no longer retrieve appointments. + + * UI/Scheduler/UIxCalView.m ([-fetchCoreAppointmentsInfos]): + removed method. + ([-fetchCoreTasksInfos]): removed method. + + * UI/Scheduler/UIxCalListingActions.m ([UIxCalListingActions + -init]): initialize an instance of SOGoDateFormatter. + ([UIxCalListingActions -eventsListAction]): the display start and + end dates are added to the listing for each event. + + * UI/Scheduler/UIxCalDayTable.m: no longer retrieve appointments. + + * UI/Scheduler/UIxAppointmentEditor.m ([UIxAppointmentEditor + -isAllDay]): returns YES if the "hm" url parameter is set to + "allday". + ([UIxAppointmentEditor -defaultAction]): if isAllDay, the enddate + is displayed one day earlier. + +2007-06-07 Wolfgang Sourdeau + + * UI/Scheduler/UIxCalListingActions.m ([UIxCalListingActions + -_setupContext]): take the range of dates specified by the popup + into account. + + * UI/Scheduler/UIxCalListingActions.[hm]: new subclass of + WODirectAction that returns WOResponse objects with the events or + todos satisfying the parameters passed in the url. + + * UI/Scheduler/UIxAppointmentEditor.m ([UIxAppointmentEditor + -takeValuesFromRequest:_rqinContext:_ctx]): take the new ivar + "isAllDay" into account and compute the amount of days to pass to + the iCalEvent. + +2007-06-06 Francis Lachapelle + + * SoObjects/SOGo/NSNumber+Utilities.m: initial import. + * SoObjects/SOGo/NSNull+Utilities.m: initial import. + * UI/Scheduler/UIxCalTasksListView.m ([WOResponse -tasksListAction]): + new method that returns a json-formatted array of the visible tasks + for the current user. + 2007-06-05 Wolfgang Sourdeau * SoObjects/Appointments/SOGoAppointmentObject.m: the owner of the diff --git a/OGoContentStore/OCSiCalFieldExtractor.m b/OGoContentStore/OCSiCalFieldExtractor.m index 264893c7..9b8678f7 100644 --- a/OGoContentStore/OCSiCalFieldExtractor.m +++ b/OGoContentStore/OCSiCalFieldExtractor.m @@ -14,7 +14,7 @@ License for more details. You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the + License along with SOGo; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ @@ -27,25 +27,24 @@ @implementation OCSiCalFieldExtractor -static OCSiCalFieldExtractor *extractor = nil; -static NSCalendarDate *distantFuture = nil; -static NSNumber *distantFutureNumber = nil; +static NSCalendarDate *distantFuture = nil; +static NSNumber *distantFutureNumber = nil; + (void) initialize { - static BOOL didInit = NO; - - if (didInit) return; - didInit = YES; - - distantFuture = [[NSCalendarDate distantFuture] retain]; - /* INT_MAX due to Postgres constraint */ - distantFutureNumber = [[NSNumber numberWithUnsignedInt:INT_MAX] retain]; + if (!distantFuture) + { + distantFuture = [[NSCalendarDate distantFuture] retain]; + /* INT_MAX due to Postgres constraint */ + distantFutureNumber = [[NSNumber numberWithUnsignedInt: INT_MAX] retain]; + } } + (id) sharedICalFieldExtractor { - if (extractor == nil) + static OCSiCalFieldExtractor *extractor = nil; + + if (!extractor) extractor = [self new]; return extractor; @@ -55,99 +54,117 @@ static NSNumber *distantFutureNumber = nil; - (NSNumber *) numberForDate: (NSCalendarDate *) _date { - if (_date == distantFuture) - return distantFutureNumber; - - return [NSNumber numberWithUnsignedInt:[_date timeIntervalSince1970]]; + return ((_date == distantFuture) + ? distantFutureNumber + : [NSNumber numberWithUnsignedInt: [_date timeIntervalSince1970]]); } - (NSMutableDictionary *) extractQuickFieldsFromEvent: (iCalEvent *) _event { NSMutableDictionary *row; - NSCalendarDate *startDate, *endDate; - NSArray *attendees; - NSString *uid, *title, *location, *status; - NSNumber *sequence; - id organizer; - id participants, partmails; - NSMutableString *partstates; - unsigned i, count; + NSCalendarDate *startDate, *endDate; + NSArray *attendees; + NSString *uid, *title, *location, *status; + NSNumber *sequence, *dateNumber; + id organizer; + id participants, partmails; + NSMutableString *partstates; + unsigned int i, count; + BOOL isAllDay; iCalAccessClass accessClass; if (_event == nil) return nil; /* extract values */ - - startDate = [_event startDate]; - endDate = [_event endDate]; - uid = [_event uid]; - title = [_event summary]; - location = [_event location]; - sequence = [_event sequence]; - accessClass = [_event symbolicAccessClass]; - status = [[_event status] uppercaseString]; - - attendees = [_event attendees]; - partmails = [attendees valueForKey:@"rfc822Email"]; - partmails = [partmails componentsJoinedByString:@"\n"]; - participants = [attendees valueForKey:@"cn"]; - participants = [participants componentsJoinedByString:@"\n"]; + + startDate = [_event startDate]; + endDate = [_event endDate]; + uid = [_event uid]; + title = [_event summary]; + location = [_event location]; + sequence = [_event sequence]; + accessClass = [_event symbolicAccessClass]; + isAllDay = [_event isAllDay]; + status = [[_event status] uppercaseString]; + + attendees = [_event attendees]; + partmails = [attendees valueForKey: @"rfc822Email"]; + partmails = [partmails componentsJoinedByString: @"\n"]; + participants = [attendees valueForKey: @"cn"]; + participants = [participants componentsJoinedByString: @"\n"]; /* build row */ row = [NSMutableDictionary dictionaryWithCapacity:8]; [row setObject: @"vevent" forKey: @"component"]; - + if ([uid isNotNull]) - [row setObject:uid forKey:@"uid"]; + [row setObject:uid forKey: @"uid"]; else - [self logWithFormat:@"WARNING: could not extract a uid from event!"]; + [self logWithFormat: @"WARNING: could not extract a uid from event!"]; + - [row setObject:[NSNumber numberWithBool: [_event isAllDay]] + [row setObject: [NSNumber numberWithBool: isAllDay] forKey: @"isallday"]; - [row setObject:[NSNumber numberWithBool: [_event isRecurrent]] + [row setObject: [NSNumber numberWithBool: [_event isRecurrent]] forKey: @"iscycle"]; - [row setObject:[NSNumber numberWithBool: [_event isOpaque]] + [row setObject: [NSNumber numberWithBool: [_event isOpaque]] forKey: @"isopaque"]; - [row setObject:[NSNumber numberWithInt: [_event priorityNumber]] + [row setObject: [NSNumber numberWithInt: [_event priorityNumber]] forKey: @"priority"]; - if ([title isNotNull]) [row setObject: title forKey:@"title"]; - if ([location isNotNull]) [row setObject: location forKey:@"location"]; - if ([sequence isNotNull]) [row setObject: sequence forKey:@"sequence"]; + if ([title isNotNull]) [row setObject: title forKey: @"title"]; + if ([location isNotNull]) [row setObject: location forKey: @"location"]; + if ([sequence isNotNull]) [row setObject: sequence forKey: @"sequence"]; if ([startDate isNotNull]) - [row setObject: [self numberForDate: startDate] forKey:@"startdate"]; + [row setObject: [self numberForDate: startDate] + forKey: @"startdate"]; if ([endDate isNotNull]) - [row setObject: [self numberForDate: endDate] forKey:@"enddate"]; + { + if (endDate == distantFuture) + dateNumber = distantFutureNumber; + else + { + if (isAllDay) + i = 1; + else + i = 0; + dateNumber + = [NSNumber numberWithUnsignedInt: + [endDate timeIntervalSince1970] - i]; + } + [row setObject: dateNumber forKey: @"enddate"]; + } + if ([_event isRecurrent]) { NSCalendarDate *date; - + date = [_event lastPossibleRecurrenceStartDate]; if (!date) { /* this could also be *nil*, but in the end it makes the fetchspecs - more complex - thus we set it to a "reasonable" distant future */ + more complex - thus we set it to a "reasonable" distant future */ date = distantFuture; } - [row setObject:[self numberForDate:date] forKey:@"cycleenddate"]; - [row setObject:[_event cycleInfo] forKey:@"cycleinfo"]; + [row setObject:[self numberForDate:date] forKey: @"cycleenddate"]; + [row setObject:[_event cycleInfo] forKey: @"cycleinfo"]; } if ([participants length] > 0) - [row setObject: participants forKey:@"participants"]; + [row setObject: participants forKey: @"participants"]; if ([partmails length] > 0) - [row setObject: partmails forKey:@"partmails"]; + [row setObject: partmails forKey: @"partmails"]; if ([status isNotNull]) { int code = 1; - - if ([status isEqualToString:@"TENTATIVE"]) + + if ([status isEqualToString: @"TENTATIVE"]) code = 2; - else if ([status isEqualToString:@"CANCELLED"]) + else if ([status isEqualToString: @"CANCELLED"]) code = 0; - [row setObject:[NSNumber numberWithInt:code] forKey:@"status"]; + [row setObject:[NSNumber numberWithInt:code] forKey: @"status"]; } else { /* confirmed by default */ @@ -160,26 +177,26 @@ static NSNumber *distantFutureNumber = nil; organizer = [_event organizer]; if (organizer) { NSString *email; - - email = [organizer valueForKey:@"rfc822Email"]; + + email = [organizer valueForKey: @"rfc822Email"]; if (email) - [row setObject:email forKey:@"orgmail"]; + [row setObject:email forKey: @"orgmail"]; } - + /* construct partstates */ - count = [attendees count]; - partstates = [[NSMutableString alloc] initWithCapacity:count * 2]; + count = [attendees count]; + partstates = [[NSMutableString alloc] initWithCapacity:count * 2]; for ( i = 0; i < count; i++) { - iCalPerson *p; + iCalPerson *p; iCalPersonPartStat stat; - - p = [attendees objectAtIndex:i]; + + p = [attendees objectAtIndex:i]; stat = [p participationStatus]; if(i != 0) - [partstates appendString:@"\n"]; - [partstates appendFormat:@"%d", stat]; + [partstates appendString: @"\n"]; + [partstates appendFormat: @"%d", stat]; } - [row setObject:partstates forKey:@"partstates"]; + [row setObject:partstates forKey: @"partstates"]; [partstates release]; return row; } @@ -187,35 +204,35 @@ static NSNumber *distantFutureNumber = nil; - (NSMutableDictionary *) extractQuickFieldsFromTodo: (iCalToDo *) _task { NSMutableDictionary *row; - NSCalendarDate *startDate, *dueDate; - NSArray *attendees; - NSString *uid, *title, *location, *status; - NSNumber *sequence; - id organizer, date; - id participants, partmails; - NSMutableString *partstates; - unsigned i, count, code; + NSCalendarDate *startDate, *dueDate; + NSArray *attendees; + NSString *uid, *title, *location, *status; + NSNumber *sequence; + id organizer, date; + id participants, partmails; + NSMutableString *partstates; + unsigned i, count, code; iCalAccessClass accessClass; if (_task == nil) return nil; /* extract values */ - - startDate = [_task startDate]; - dueDate = [_task due]; - uid = [_task uid]; - title = [_task summary]; - location = [_task location]; - sequence = [_task sequence]; - accessClass = [_task symbolicAccessClass]; - status = [[_task status] uppercaseString]; - - attendees = [_task attendees]; - partmails = [attendees valueForKey:@"rfc822Email"]; - partmails = [partmails componentsJoinedByString:@"\n"]; - participants = [attendees valueForKey:@"cn"]; - participants = [participants componentsJoinedByString:@"\n"]; + + startDate = [_task startDate]; + dueDate = [_task due]; + uid = [_task uid]; + title = [_task summary]; + location = [_task location]; + sequence = [_task sequence]; + accessClass = [_task symbolicAccessClass]; + status = [[_task status] uppercaseString]; + + attendees = [_task attendees]; + partmails = [attendees valueForKey: @"rfc822Email"]; + partmails = [partmails componentsJoinedByString: @"\n"]; + participants = [attendees valueForKey: @"cn"]; + participants = [participants componentsJoinedByString: @"\n"]; /* build row */ @@ -224,19 +241,19 @@ static NSNumber *distantFutureNumber = nil; [row setObject: @"vtodo" forKey: @"component"]; if ([uid isNotNull]) - [row setObject:uid forKey:@"uid"]; + [row setObject:uid forKey: @"uid"]; else - [self logWithFormat:@"WARNING: could not extract a uid from event!"]; + [self logWithFormat: @"WARNING: could not extract a uid from event!"]; [row setObject:[NSNumber numberWithBool:[_task isRecurrent]] - forKey:@"iscycle"]; + forKey: @"iscycle"]; [row setObject:[NSNumber numberWithInt:[_task priorityNumber]] - forKey:@"priority"]; + forKey: @"priority"]; - if ([title isNotNull]) [row setObject: title forKey:@"title"]; - if ([location isNotNull]) [row setObject: location forKey:@"location"]; - if ([sequence isNotNull]) [row setObject: sequence forKey:@"sequence"]; - + if ([title isNotNull]) [row setObject: title forKey: @"title"]; + if ([location isNotNull]) [row setObject: location forKey: @"location"]; + if ([sequence isNotNull]) [row setObject: sequence forKey: @"sequence"]; + if ([startDate isNotNull]) date = [self numberForDate: startDate]; else @@ -250,23 +267,23 @@ static NSNumber *distantFutureNumber = nil; [row setObject: date forKey: @"enddate"]; if ([participants length] > 0) - [row setObject:participants forKey:@"participants"]; + [row setObject:participants forKey: @"participants"]; if ([partmails length] > 0) - [row setObject:partmails forKey:@"partmails"]; + [row setObject:partmails forKey: @"partmails"]; if ([status isNotNull]) { code = 0; /* NEEDS-ACTION */ - if ([status isEqualToString:@"COMPLETED"]) + if ([status isEqualToString: @"COMPLETED"]) code = 1; - else if ([status isEqualToString:@"IN-PROCESS"]) + else if ([status isEqualToString: @"IN-PROCESS"]) code = 2; - else if ([status isEqualToString:@"CANCELLED"]) + else if ([status isEqualToString: @"CANCELLED"]) code = 3; - [row setObject: [NSNumber numberWithInt: code] forKey:@"status"]; + [row setObject: [NSNumber numberWithInt: code] forKey: @"status"]; } else { /* confirmed by default */ - [row setObject:[NSNumber numberWithInt:1] forKey:@"status"]; + [row setObject:[NSNumber numberWithInt:1] forKey: @"status"]; } [row setObject: [NSNumber numberWithUnsignedInt: accessClass] @@ -275,26 +292,26 @@ static NSNumber *distantFutureNumber = nil; organizer = [_task organizer]; if (organizer) { NSString *email; - - email = [organizer valueForKey:@"rfc822Email"]; + + email = [organizer valueForKey: @"rfc822Email"]; if (email) - [row setObject:email forKey:@"orgmail"]; + [row setObject:email forKey: @"orgmail"]; } - + /* construct partstates */ - count = [attendees count]; - partstates = [[NSMutableString alloc] initWithCapacity:count * 2]; + count = [attendees count]; + partstates = [[NSMutableString alloc] initWithCapacity:count * 2]; for ( i = 0; i < count; i++) { - iCalPerson *p; + iCalPerson *p; iCalPersonPartStat stat; - - p = [attendees objectAtIndex:i]; + + p = [attendees objectAtIndex:i]; stat = [p participationStatus]; if(i != 0) - [partstates appendString:@"\n"]; - [partstates appendFormat:@"%d", stat]; + [partstates appendString: @"\n"]; + [partstates appendFormat: @"%d", stat]; } - [row setObject:partstates forKey:@"partstates"]; + [row setObject:partstates forKey: @"partstates"]; [partstates release]; return row; } @@ -304,20 +321,20 @@ static NSNumber *distantFutureNumber = nil; NSArray *elements; CardGroup *element; unsigned int count; - + elements = [ical allObjects]; count = [elements count]; if (count) { if (count > 1) - [self logWithFormat: - @"WARNING: given calendar contains more than one event: %@", - ical]; + [self logWithFormat: + @"WARNING: given calendar contains more than one event: %@", + ical]; element = [elements objectAtIndex: 0]; } else { - [self logWithFormat:@"ERROR: given calendar contains no elements: %@", ical]; + [self logWithFormat: @"ERROR: given calendar contains no elements: %@", ical]; element = nil; } @@ -328,33 +345,33 @@ static NSNumber *distantFutureNumber = nil; NSAutoreleasePool *pool; NSDictionary *fields; id cal; - + if ([_content length] == 0) return nil; pool = [[NSAutoreleasePool alloc] init]; cal = [iCalCalendar parseSingleFromSource: _content]; - + fields = nil; if (cal) { if ([cal isKindOfClass:[iCalCalendar class]]) - cal = [self firstElementFromCalendar: cal]; + cal = [self firstElementFromCalendar: cal]; if ([cal isKindOfClass:[iCalEvent class]]) - fields = [[self extractQuickFieldsFromEvent:cal] retain]; + fields = [[self extractQuickFieldsFromEvent:cal] retain]; else if ([cal isKindOfClass:[iCalToDo class]]) - fields = [[self extractQuickFieldsFromTodo:cal] retain]; + fields = [[self extractQuickFieldsFromTodo:cal] retain]; else if ([cal isNotNull]) { - [self logWithFormat:@"ERROR: unexpected iCalendar parse result: %@", - cal]; + [self logWithFormat: @"ERROR: unexpected iCalendar parse result: %@", + cal]; } } else - [self logWithFormat:@"ERROR: parsing source didn't return anything"]; + [self logWithFormat: @"ERROR: parsing source didn't return anything"]; [pool release]; - + return [fields autorelease]; } diff --git a/SOPE/NGCards/CardElement.h b/SOPE/NGCards/CardElement.h index d4fd0315..ebd89f1e 100644 --- a/SOPE/NGCards/CardElement.h +++ b/SOPE/NGCards/CardElement.h @@ -106,4 +106,22 @@ @end +#define IS_EQUAL(a,b,sel) \ + _iCalSafeCompareObjects (a, b, @selector(sel)) + +static __inline__ BOOL _iCalSafeCompareObjects(id a, id b, SEL comparator) +{ + id va = a; + id vb = b; + BOOL (*compm)(id, SEL, id); + + if((!va && vb) || (va && !vb)) + return NO; + else if(va == vb) + return YES; + compm = (BOOL (*)( id, SEL, id)) [va methodForSelector: comparator]; + + return compm(va, comparator, vb); +} + #endif /* CARDELEMENT_H */ diff --git a/SOPE/NGCards/CardGroup+iCal.h b/SOPE/NGCards/CardGroup+iCal.h deleted file mode 100644 index ece4cf1a..00000000 --- a/SOPE/NGCards/CardGroup+iCal.h +++ /dev/null @@ -1,39 +0,0 @@ -/* CardGroup+iCal.h - this file is part of $PROJECT_NAME_HERE$ - * - * Copyright (C) 2006 Inverse groupe conseil - * - * Author: Wolfgang Sourdeau - * - * 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. - */ - -#ifndef CARDGROUP_ICAL_H -#define CARDGROUP_ICAL_H - -@class NSString; -@class NSCalendarDate; - -#import "CardGroup.h" - -@interface CardGroup (iCalExtensions) - -- (void) setDate: (NSCalendarDate *) _value - forDateTimeValue: (NSString *) valueName; -- (NSCalendarDate *) dateForDateTimeValue: (NSString *) valueName; - -@end - -#endif /* CARDGROUP_ICAL_H */ diff --git a/SOPE/NGCards/CardGroup+iCal.m b/SOPE/NGCards/CardGroup+iCal.m deleted file mode 100644 index a7fb4e58..00000000 --- a/SOPE/NGCards/CardGroup+iCal.m +++ /dev/null @@ -1,48 +0,0 @@ -/* CardGroup+iCal.m - this file is part of SOPE - * - * Copyright (C) 2006 Inverse groupe conseil - * - * Author: Wolfgang Sourdeau - * - * 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 "iCalDateTime.h" - -#import "CardGroup+iCal.h" - -@implementation CardGroup (iCalExtensions) - -- (void) setDate: (NSCalendarDate *) _value - forDateTimeValue: (NSString *) valueName -{ - iCalDateTime *dateValue; - - dateValue = (iCalDateTime *) [self uniqueChildWithTag: valueName]; - - [dateValue setDateTime: _value]; -} - -- (NSCalendarDate *) dateForDateTimeValue: (NSString *) valueName -{ - iCalDateTime *dateValue; - - dateValue = (iCalDateTime *) [self uniqueChildWithTag: valueName]; - - return [dateValue dateTime]; -} - -@end diff --git a/SOPE/NGCards/ChangeLog b/SOPE/NGCards/ChangeLog index dc09aa58..fa126515 100644 --- a/SOPE/NGCards/ChangeLog +++ b/SOPE/NGCards/ChangeLog @@ -1,3 +1,40 @@ +2007-06-07 Wolfgang Sourdeau + + * iCalDateTime.m ([iCalDateTime + -_setDateTime:dateTimeforAllDayEntity:forAllDayEntity]): + inverted the all day logic because all day dates where generated + for regular dates and the other way around... + + * iCalEvent.m ([iCalEvent + -setAllDayWithStartDate:newStartDateduration:days]): new method + that sets the start and end dates in an all day fashion. + ([iCalEvent -setEndDate:newEndDate]): no longer use the methods + provided by the removed module CardGroup+iCal. + ([-isAllDay]): reimplemented method by testing if the start day + component is an all day date. + + * iCalEntityObject.m ([iCalEntityObject -setCreated:newCreated]) + ([iCalEntityObject -created], [-setLastModified:_value]) + ([iCalEntityObject -lastModified]) + ([iCalEntityObject -setTimeStampAsDate:newTimeStamp]) + ([iCalEntityObject -timeStampAsDate], [-setStartDate:_value]) + ([iCalEntityObject -startDate]): no longer use the methods + provided by the removed module CardGroup+iCal. + + * iCalDateTime.m ([iCalDateTime -setDate:dateTime]): take the date + passed as parameter as an all day date. + ([iCalDateTime -isAllDay]): new method determining whether the + current value is an all day value. + + * NSString+NGCards.m ([NSString -isAllDayDate]): new method that + determines whether the date represented in "self" is an all day + date (date only) or not (date + time). + + * CardElement.h: moved IS_EQUAL macro from removed module + "common.h". + + * CardGroup+iCal.[hm]: removed category module. + 2007-04-27 Wolfgang Sourdeau * NGVCard.m ([NGVCard -n]): simplified method by returning the diff --git a/SOPE/NGCards/GNUmakefile b/SOPE/NGCards/GNUmakefile index efc491c5..613d1c91 100644 --- a/SOPE/NGCards/GNUmakefile +++ b/SOPE/NGCards/GNUmakefile @@ -14,7 +14,6 @@ endif FHS_HEADER_DIRS = NGCards -libNGCards_PCH_FILE = common.h libNGCards_HEADER_FILES_DIR = . libNGCards_HEADER_FILES_INSTALL_DIR = /NGCards libNGCards_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) @@ -29,7 +28,6 @@ libNGCards_HEADER_FILES = \ \ CardElement.h \ CardGroup.h \ - CardGroup+iCal.h \ CardVersitRenderer.h \ \ NGCards.h \ @@ -77,7 +75,6 @@ libNGCards_OBJC_FILES = \ \ CardElement.m \ CardGroup.m \ - CardGroup+iCal.m \ CardVersitRenderer.m \ \ iCalAlarm.m \ diff --git a/SOPE/NGCards/IcalElements.m b/SOPE/NGCards/IcalElements.m index c5002dc0..f66952b6 100644 --- a/SOPE/NGCards/IcalElements.m +++ b/SOPE/NGCards/IcalElements.m @@ -38,7 +38,6 @@ } @end -#include "common.h" static inline NSDictionary *ExtractParameters(NSDictionary *_set) { /* extracts ? parameters */ diff --git a/SOPE/NGCards/NGCardsSaxHandler.m b/SOPE/NGCards/NGCardsSaxHandler.m index 8c77b557..d961c956 100644 --- a/SOPE/NGCards/NGCardsSaxHandler.m +++ b/SOPE/NGCards/NGCardsSaxHandler.m @@ -19,9 +19,10 @@ 02111-1307, USA. */ -#import "NGCardsSaxHandler.h" -#import "common.h" #import +#import + +#import "NGCardsSaxHandler.h" #import "CardGroup.h" diff --git a/SOPE/NGCards/NSCalendarDate+ICal.m b/SOPE/NGCards/NSCalendarDate+ICal.m index 7e420198..bca9721f 100644 --- a/SOPE/NGCards/NSCalendarDate+ICal.m +++ b/SOPE/NGCards/NSCalendarDate+ICal.m @@ -19,9 +19,13 @@ 02111-1307, USA. */ -#include "NSCalendarDate+ICal.h" -#include "iCalDateHolder.h" -#include "common.h" +#import +#import + +#import + +#import "NSCalendarDate+ICal.h" +#import "iCalDateHolder.h" static NSTimeZone *gmt = nil; static inline void _setupGMT(void) { diff --git a/SOPE/NGCards/NSString+NGCards.h b/SOPE/NGCards/NSString+NGCards.h index 2b57059a..0311ab6b 100644 --- a/SOPE/NGCards/NSString+NGCards.h +++ b/SOPE/NGCards/NSString+NGCards.h @@ -37,6 +37,7 @@ - (NSTimeInterval) durationAsTimeInterval; - (NSCalendarDate *) asCalendarDate; +- (BOOL) isAllDayDate; - (NSArray *) commaSeparatedValues; diff --git a/SOPE/NGCards/NSString+NGCards.m b/SOPE/NGCards/NSString+NGCards.m index 21cee5b5..2076e63b 100644 --- a/SOPE/NGCards/NSString+NGCards.m +++ b/SOPE/NGCards/NSString+NGCards.m @@ -214,9 +214,11 @@ static NSString *commaSeparator = nil; NSRange cursor; NSCalendarDate *date; NSTimeZone *utc; + unsigned int length; int year, month, day, hour, minute, second; - if ([self length] > 14) + length = [self length]; + if (length > 7) { cursor = NSMakeRange(0, 4); year = [[self substringWithRange: cursor] intValue]; @@ -226,12 +228,21 @@ static NSString *commaSeparator = nil; cursor.location += cursor.length; day = [[self substringWithRange: cursor] intValue]; - cursor.location += cursor.length + 1; - hour = [[self substringWithRange: cursor] intValue]; - cursor.location += cursor.length; - minute = [[self substringWithRange: cursor] intValue]; - cursor.location += cursor.length; - second = [[self substringWithRange: cursor] intValue]; + if (length > 14) + { + cursor.location += cursor.length + 1; + hour = [[self substringWithRange: cursor] intValue]; + cursor.location += cursor.length; + minute = [[self substringWithRange: cursor] intValue]; + cursor.location += cursor.length; + second = [[self substringWithRange: cursor] intValue]; + } + else + { + hour = 0; + minute = 0; + second = 0; + } utc = [NSTimeZone timeZoneWithAbbreviation: @"GMT"]; date = [NSCalendarDate dateWithYear: year month: month @@ -245,6 +256,11 @@ static NSString *commaSeparator = nil; return date; } +- (BOOL) isAllDayDate +{ + return ([self length] == 8); +} + - (NSArray *) commaSeparatedValues { NSEnumerator *rawValues; diff --git a/SOPE/NGCards/common.h b/SOPE/NGCards/common.h deleted file mode 100644 index 0ffdb574..00000000 --- a/SOPE/NGCards/common.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (C) 2000-2005 SKYRIX Software AG - - This file is part of SOPE. - - SOPE is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - SOPE 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 Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with SOPE; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -#ifndef __ICal_common_H__ -#define __ICal_common_H__ - -#import -#import -#include - -#define IS_EQUAL(a, b, sel) \ - _iCalSafeCompareObjects(a, b, @selector(sel)) - -static __inline__ BOOL _iCalSafeCompareObjects(id a, id b, SEL comparator) { - id va = a; - id vb = b; - BOOL (*compm)(id, SEL, id); - - if((va == nil && vb != nil) || (va != nil && vb == nil)) - return NO; - else if(va == vb) - return YES; - compm = (BOOL (*)( id, SEL, id))[va methodForSelector:comparator]; - return compm(va, comparator, vb); -} - -#endif /* __ICal_common_H__ */ diff --git a/SOPE/NGCards/iCalAlarm.m b/SOPE/NGCards/iCalAlarm.m index 2d6a95b7..a4218fa8 100644 --- a/SOPE/NGCards/iCalAlarm.m +++ b/SOPE/NGCards/iCalAlarm.m @@ -19,12 +19,13 @@ 02111-1307, USA. */ +#import + #import "iCalAttachment.h" #import "iCalRecurrenceRule.h" #import "iCalTrigger.h" #import "iCalAlarm.h" -#import "common.h" @implementation iCalAlarm diff --git a/SOPE/NGCards/iCalAttachment.m b/SOPE/NGCards/iCalAttachment.m index b115e099..6963abd6 100644 --- a/SOPE/NGCards/iCalAttachment.m +++ b/SOPE/NGCards/iCalAttachment.m @@ -19,8 +19,8 @@ 02111-1307, USA. */ +#import #import "iCalAttachment.h" -#import "common.h" @implementation iCalAttachment diff --git a/SOPE/NGCards/iCalDailyRecurrenceCalculator.m b/SOPE/NGCards/iCalDailyRecurrenceCalculator.m index 6ba00f16..17a1d483 100644 --- a/SOPE/NGCards/iCalDailyRecurrenceCalculator.m +++ b/SOPE/NGCards/iCalDailyRecurrenceCalculator.m @@ -19,15 +19,19 @@ 02111-1307, USA. */ -#include "iCalRecurrenceCalculator.h" +#import +#import + +#import + +#import "iCalRecurrenceCalculator.h" @interface iCalDailyRecurrenceCalculator : iCalRecurrenceCalculator @end -#include -#include "iCalRecurrenceRule.h" -#include "NSCalendarDate+ICal.h" -#include "common.h" +#import +#import "iCalRecurrenceRule.h" +#import "NSCalendarDate+ICal.h" @interface iCalRecurrenceCalculator(PrivateAPI) - (NSCalendarDate *)lastInstanceStartDate; diff --git a/SOPE/NGCards/iCalDataSource.m b/SOPE/NGCards/iCalDataSource.m index b84c3940..2bf9891c 100644 --- a/SOPE/NGCards/iCalDataSource.m +++ b/SOPE/NGCards/iCalDataSource.m @@ -19,11 +19,25 @@ 02111-1307, USA. */ -#include "iCalDataSource.h" -#include "iCalObject.h" -#include "iCalCalendar.h" -#include -#include "common.h" +#import +#import +#import +#import +#import + +#import +#import +#import +#import +#import +#import +#import +#import + +#import "iCalObject.h" +#import "iCalCalendar.h" + +#import "iCalDataSource.h" @interface NSObject(suppressCapitalizedKeyWarning) + (void)suppressCapitalizedKeyWarning; diff --git a/SOPE/NGCards/iCalDateHolder.m b/SOPE/NGCards/iCalDateHolder.m index 91c4e0a8..c6e73890 100644 --- a/SOPE/NGCards/iCalDateHolder.m +++ b/SOPE/NGCards/iCalDateHolder.m @@ -19,9 +19,17 @@ 02111-1307, USA. */ -#include "iCalDateHolder.h" -#include "iCalObject.h" -#include "common.h" +#import +#import +#import +#import +#import + +#import +#import + +#import "iCalDateHolder.h" +#import "iCalObject.h" @interface NSTimeZone(iCalTimeZone) diff --git a/SOPE/NGCards/iCalDateTime.h b/SOPE/NGCards/iCalDateTime.h index a3fa2c12..dea30fd6 100644 --- a/SOPE/NGCards/iCalDateTime.h +++ b/SOPE/NGCards/iCalDateTime.h @@ -33,9 +33,12 @@ - (void) setTimeZone: (iCalTimeZone *) iTZ; - (iCalTimeZone *) timeZone; +- (void) setDate: (NSCalendarDate *) date; - (void) setDateTime: (NSCalendarDate *) dateTime; - (NSCalendarDate *) dateTime; +- (BOOL) isAllDay; + @end #endif /* ICALDATETIMEELEMENT_H */ diff --git a/SOPE/NGCards/iCalDateTime.m b/SOPE/NGCards/iCalDateTime.m index b0f1a19f..fc707b32 100644 --- a/SOPE/NGCards/iCalDateTime.m +++ b/SOPE/NGCards/iCalDateTime.m @@ -89,7 +89,8 @@ /* TODO: should implement the case where the TZ would be implicitly local (no TZID and no UTC) */ -- (void) setDateTime: (NSCalendarDate *) dateTime +- (void) _setDateTime: (NSCalendarDate *) dateTime + forAllDayEntity: (BOOL) forAllDayEntity { NSCalendarDate *tmpTime; NSTimeZone *utcTZ; @@ -107,8 +108,11 @@ tmpTime = [dateTime copy]; [tmpTime setTimeZone: utcTZ]; - timeString = [NSString stringWithFormat: @"%@Z", - [tmpTime iCalFormattedDateTimeString]]; + if (forAllDayEntity) + timeString = [tmpTime iCalFormattedDateString]; + else + timeString = [NSString stringWithFormat: @"%@Z", + [tmpTime iCalFormattedDateTimeString]]; [tmpTime release]; } } @@ -118,6 +122,16 @@ [self setValue: 0 to: timeString]; } +- (void) setDateTime: (NSCalendarDate *) dateTime +{ + [self _setDateTime: dateTime forAllDayEntity: NO]; +} + +- (void) setDate: (NSCalendarDate *) dateTime +{ + [self _setDateTime: dateTime forAllDayEntity: YES]; +} + - (NSCalendarDate *) dateTime { iCalTimeZone *iTZ; @@ -152,4 +166,9 @@ return dateTime; } +- (BOOL) isAllDay +{ + return [[self value: 0] isAllDayDate]; +} + @end diff --git a/SOPE/NGCards/iCalEntityObject.h b/SOPE/NGCards/iCalEntityObject.h index 662aff90..e58dc1e5 100644 --- a/SOPE/NGCards/iCalEntityObject.h +++ b/SOPE/NGCards/iCalEntityObject.h @@ -75,7 +75,7 @@ typedef enum - (void) setTimeStampAsDate: (NSCalendarDate *)_date; - (NSCalendarDate *) timeStampAsDate; -- (void) setStartDate: (NSCalendarDate *) _date; +- (void) setStartDate: (NSCalendarDate *) newStartDate; - (NSCalendarDate *) startDate; - (BOOL) hasStartDate; diff --git a/SOPE/NGCards/iCalEntityObject.m b/SOPE/NGCards/iCalEntityObject.m index fc75f8d4..39f2afce 100644 --- a/SOPE/NGCards/iCalEntityObject.m +++ b/SOPE/NGCards/iCalEntityObject.m @@ -19,14 +19,17 @@ 02111-1307, USA. */ +#import +#import +#import +#import + #import "NSCalendarDate+NGCards.h" -#import "CardGroup+iCal.h" #import "iCalAlarm.h" #import "iCalDateTime.h" #import "iCalEntityObject.h" #import "iCalPerson.h" -#import "common.h" @interface iCalEntityObject (PrivateAPI) - (NSArray *)_filteredAttendeesThinkingOfPersons:(BOOL)_persons; @@ -206,44 +209,52 @@ [self setSequence: [NSNumber numberWithInt: seq]]; } -- (void) setCreated: (NSCalendarDate *) _value +- (void) setCreated: (NSCalendarDate *) newCreated { - [self setDate: _value forDateTimeValue: @"created"]; + [(iCalDateTime *) [self uniqueChildWithTag: @"created"] + setDateTime: newCreated]; } - (NSCalendarDate *) created { - return [self dateForDateTimeValue: @"created"]; + return [(iCalDateTime *) [self uniqueChildWithTag: @"created"] + dateTime]; } -- (void) setLastModified: (NSCalendarDate *) _value +- (void) setLastModified: (NSCalendarDate *) newLastModified { - [self setDate: _value forDateTimeValue: @"last-modified"]; + [(iCalDateTime *) [self uniqueChildWithTag: @"last-modified"] + setDateTime: newLastModified]; } - (NSCalendarDate *) lastModified { - return [self dateForDateTimeValue: @"last-modified"]; + return [(iCalDateTime *) [self uniqueChildWithTag: @"last-modified"] + dateTime]; } -- (void) setTimeStampAsDate: (NSCalendarDate *) _value +- (void) setTimeStampAsDate: (NSCalendarDate *) newTimeStamp { - [self setDate: _value forDateTimeValue: @"dtstamp"]; + [(iCalDateTime *) [self uniqueChildWithTag: @"dtstamp"] + setDateTime: newTimeStamp]; } - (NSCalendarDate *) timeStampAsDate { - return [self dateForDateTimeValue: @"dtstamp"]; + return [(iCalDateTime *) [self uniqueChildWithTag: @"dtstamp"] + dateTime]; } -- (void) setStartDate: (NSCalendarDate *) _value +- (void) setStartDate: (NSCalendarDate *) newStartDate { - [self setDate: _value forDateTimeValue: @"dtstart"]; + [(iCalDateTime *) [self uniqueChildWithTag: @"dtstart"] + setDateTime: newStartDate]; } - (NSCalendarDate *) startDate { - return [self dateForDateTimeValue: @"dtstart"]; + return [(iCalDateTime *) [self uniqueChildWithTag: @"dtstart"] + dateTime]; } - (BOOL) hasStartDate diff --git a/SOPE/NGCards/iCalEvent.h b/SOPE/NGCards/iCalEvent.h index 608b0585..576b5f79 100644 --- a/SOPE/NGCards/iCalEvent.h +++ b/SOPE/NGCards/iCalEvent.h @@ -43,6 +43,9 @@ /* accessors */ +- (void) setAllDayWithStartDate: (NSCalendarDate *) newStartDate + duration: (unsigned int) days; + - (void) setEndDate: (NSCalendarDate *) _date; - (NSCalendarDate *) endDate; - (BOOL) hasEndDate; diff --git a/SOPE/NGCards/iCalEvent.m b/SOPE/NGCards/iCalEvent.m index d237619f..d3f10f22 100644 --- a/SOPE/NGCards/iCalEvent.m +++ b/SOPE/NGCards/iCalEvent.m @@ -19,10 +19,10 @@ 02111-1307, USA. */ +#import #import #import "NSCalendarDate+NGCards.h" -#import "CardGroup+iCal.h" #import "NSString+NGCards.h" #import "iCalEventChanges.h" @@ -48,15 +48,28 @@ } /* accessors */ +- (void) setAllDayWithStartDate: (NSCalendarDate *) newStartDate + duration: (unsigned int) days +{ + NSCalendarDate *endDate; + + [(iCalDateTime *) [self uniqueChildWithTag: @"dtstart"] + setDate: newStartDate]; + endDate = [newStartDate dateByAddingYears: 0 months: 0 days: days]; + [(iCalDateTime *) [self uniqueChildWithTag: @"dtend"] + setDate: endDate]; +} -- (void) setEndDate: (NSCalendarDate *)_date +- (void) setEndDate: (NSCalendarDate *) newEndDate { - [self setDate: _date forDateTimeValue: @"dtend"]; + [(iCalDateTime *) [self uniqueChildWithTag: @"dtend"] + setDateTime: newEndDate]; } - (NSCalendarDate *) endDate { - return [self dateForDateTimeValue: @"dtend"]; + return [(iCalDateTime *) [self uniqueChildWithTag: @"dtend"] + dateTime]; } - (BOOL) hasEndDate @@ -132,31 +145,9 @@ return (![s isEqualToString: @"TRANSPARENT"]); } -/* TODO: FIX THIS! - The problem is, that startDate/endDate are inappropriately modelled here. - We'd need to have a special iCalDate in order to fix all the mess. - For the time being, we chose allday to mean 00:00 - 23:59 in startDate's - timezone. -*/ - (BOOL) isAllDay { - NSCalendarDate *ed, *startDate; - BOOL allDay; - - if ([self hasEndDate]) - { - ed = [self endDate]; - startDate = [self startDate]; - [ed setTimeZone: [startDate timeZone]]; - allDay = (([startDate hourOfDay] == 0) - && ([startDate minuteOfHour] == 0) - && ([ed hourOfDay] == 23) - && ([ed minuteOfHour] == 59)); - } - else - allDay = NO; - - return allDay; + return [(iCalDateTime *) [self uniqueChildWithTag: @"dtstart"] isAllDay]; } - (BOOL) isWithinCalendarDateRange: (NGCalendarDateRange *) _range diff --git a/SOPE/NGCards/iCalEventChanges.m b/SOPE/NGCards/iCalEventChanges.m index 6a7401c1..ccc4ab17 100644 --- a/SOPE/NGCards/iCalEventChanges.m +++ b/SOPE/NGCards/iCalEventChanges.m @@ -19,11 +19,11 @@ 02111-1307, USA. */ +#import -#include "iCalEventChanges.h" -#include "iCalEvent.h" -#include "iCalPerson.h" -#include "common.h" +#import "iCalEventChanges.h" +#import "iCalEvent.h" +#import "iCalPerson.h" @interface iCalEventChanges (PrivateAPI) - (void)_trackAttendeeChanges:(iCalEvent *)_from :(iCalEvent *)_to; diff --git a/SOPE/NGCards/iCalFreeBusy.m b/SOPE/NGCards/iCalFreeBusy.m index efae27e7..17fd8e41 100644 --- a/SOPE/NGCards/iCalFreeBusy.m +++ b/SOPE/NGCards/iCalFreeBusy.m @@ -23,7 +23,6 @@ #import #import -#import "CardGroup+iCal.h" #import "iCalDateTime.h" #import "NSCalendarDate+NGCards.h" @@ -46,14 +45,16 @@ } /* accessors */ -- (void) setEndDate: (NSCalendarDate *)_date +- (void) setEndDate: (NSCalendarDate *) newEndDate { - [self setDate: _date forDateTimeValue: @"dtend"]; + [(iCalDateTime *) [self uniqueChildWithTag: @"dtend"] + setDateTime: newEndDate]; } - (NSCalendarDate *) endDate { - return [self dateForDateTimeValue: @"dtend"]; + return [(iCalDateTime *) [self uniqueChildWithTag: @"dtend"] + dateTime]; } - (BOOL) hasEndDate diff --git a/SOPE/NGCards/iCalJournal.m b/SOPE/NGCards/iCalJournal.m index 3c158772..a2ac9cb5 100644 --- a/SOPE/NGCards/iCalJournal.m +++ b/SOPE/NGCards/iCalJournal.m @@ -19,8 +19,9 @@ 02111-1307, USA. */ -#include "iCalJournal.h" -#include "common.h" +#import + +#import "iCalJournal.h" @implementation iCalJournal diff --git a/SOPE/NGCards/iCalMonthlyRecurrenceCalculator.m b/SOPE/NGCards/iCalMonthlyRecurrenceCalculator.m index b2809eda..a7112540 100644 --- a/SOPE/NGCards/iCalMonthlyRecurrenceCalculator.m +++ b/SOPE/NGCards/iCalMonthlyRecurrenceCalculator.m @@ -19,16 +19,17 @@ 02111-1307, USA. */ -#include "iCalRecurrenceCalculator.h" +#import + +#import "iCalRecurrenceCalculator.h" @interface iCalMonthlyRecurrenceCalculator : iCalRecurrenceCalculator @end -#include -#include "iCalRecurrenceRule.h" -#include "NSCalendarDate+ICal.h" -#include "common.h" -#include +#import +#import "iCalRecurrenceRule.h" +#import "NSCalendarDate+ICal.h" +#import @interface iCalRecurrenceCalculator(PrivateAPI) - (NSCalendarDate *)lastInstanceStartDate; diff --git a/SOPE/NGCards/iCalObject.m b/SOPE/NGCards/iCalObject.m index 71f4597c..ad157354 100644 --- a/SOPE/NGCards/iCalObject.m +++ b/SOPE/NGCards/iCalObject.m @@ -19,8 +19,9 @@ 02111-1307, USA. */ -#include "iCalObject.h" -#include "common.h" +#import + +#import "iCalObject.h" @implementation iCalObject diff --git a/SOPE/NGCards/iCalPerson.m b/SOPE/NGCards/iCalPerson.m index e22a81ab..68e3deef 100644 --- a/SOPE/NGCards/iCalPerson.m +++ b/SOPE/NGCards/iCalPerson.m @@ -19,8 +19,9 @@ 02111-1307, USA. */ -#include "iCalPerson.h" -#include "common.h" +#import + +#import "iCalPerson.h" @implementation iCalPerson diff --git a/SOPE/NGCards/iCalRecurrenceCalculator.m b/SOPE/NGCards/iCalRecurrenceCalculator.m index d144efea..a56eaef3 100644 --- a/SOPE/NGCards/iCalRecurrenceCalculator.m +++ b/SOPE/NGCards/iCalRecurrenceCalculator.m @@ -19,11 +19,16 @@ 02111-1307, USA. */ -#include "iCalRecurrenceCalculator.h" -#include -#include "iCalRecurrenceRule.h" -#include "NSCalendarDate+ICal.h" -#include "common.h" +#import +#import +#import +#import + +#import "iCalRecurrenceRule.h" +#import "NSCalendarDate+ICal.h" + + +#import "iCalRecurrenceCalculator.h" /* class cluster */ diff --git a/SOPE/NGCards/iCalRepeatableEntityObject.m b/SOPE/NGCards/iCalRepeatableEntityObject.m index 1a772d02..2b36288c 100644 --- a/SOPE/NGCards/iCalRepeatableEntityObject.m +++ b/SOPE/NGCards/iCalRepeatableEntityObject.m @@ -23,7 +23,6 @@ #include #include "iCalRecurrenceRule.h" #include "iCalRecurrenceCalculator.h" -#include "common.h" @implementation iCalRepeatableEntityObject diff --git a/SOPE/NGCards/iCalTimeZonePeriod.m b/SOPE/NGCards/iCalTimeZonePeriod.m index d157720b..29bd9bb1 100644 --- a/SOPE/NGCards/iCalTimeZonePeriod.m +++ b/SOPE/NGCards/iCalTimeZonePeriod.m @@ -26,7 +26,6 @@ #import "iCalDateTime.h" #import "iCalRecurrenceRule.h" -#import "CardGroup+iCal.h" #import "iCalTimeZonePeriod.h" diff --git a/SOPE/NGCards/iCalToDo.m b/SOPE/NGCards/iCalToDo.m index e5e2c0a1..0319f2d6 100644 --- a/SOPE/NGCards/iCalToDo.m +++ b/SOPE/NGCards/iCalToDo.m @@ -22,7 +22,6 @@ #import #import "NSCalendarDate+NGCards.h" -#import "CardGroup+iCal.h" #import "iCalDateTime.h" #import "iCalToDo.h" @@ -57,27 +56,29 @@ return [[self uniqueChildWithTag: @"percent-complete"] value: 0]; } -- (void) setDue: (NSCalendarDate *) _date +- (void) setDue: (NSCalendarDate *) newDueDate { - [self setDate: _date - forDateTimeValue: @"due"]; + [(iCalDateTime *) [self uniqueChildWithTag: @"due"] + setDate: newDueDate]; } - (NSCalendarDate *) due { - return [self dateForDateTimeValue: @"due"]; -// return [[self uniqueChildWithTag: @"percent-complete"] asCalendarDate]; + return [(iCalDateTime *) [self uniqueChildWithTag: @"due"] + dateTime]; } -- (void) setCompleted: (NSCalendarDate *) _date +- (void) setCompleted: (NSCalendarDate *) newCompletedDate { + [(iCalDateTime *) [self uniqueChildWithTag: @"completed"] + setDate: newCompletedDate]; [self setStatus: @"COMPLETED"]; - [self setDate: _date forDateTimeValue: @"completed"]; } - (NSCalendarDate *) completed { - return [self dateForDateTimeValue: @"completed"]; + return [(iCalDateTime *) [self uniqueChildWithTag: @"completed"] + dateTime]; } /* ical typing */ diff --git a/SOPE/NGCards/iCalTrigger.m b/SOPE/NGCards/iCalTrigger.m index ac26958f..d48e8b1c 100644 --- a/SOPE/NGCards/iCalTrigger.m +++ b/SOPE/NGCards/iCalTrigger.m @@ -19,8 +19,9 @@ 02111-1307, USA. */ -#include "iCalTrigger.h" -#include "common.h" +#import + +#import "iCalTrigger.h" @implementation iCalTrigger diff --git a/SOPE/NGCards/iCalWeeklyRecurrenceCalculator.m b/SOPE/NGCards/iCalWeeklyRecurrenceCalculator.m index 1db42c84..eade0196 100644 --- a/SOPE/NGCards/iCalWeeklyRecurrenceCalculator.m +++ b/SOPE/NGCards/iCalWeeklyRecurrenceCalculator.m @@ -19,15 +19,16 @@ 02111-1307, USA. */ -#include "iCalRecurrenceCalculator.h" +#import + +#import "iCalRecurrenceCalculator.h" @interface iCalWeeklyRecurrenceCalculator : iCalRecurrenceCalculator @end -#include -#include "iCalRecurrenceRule.h" -#include "NSCalendarDate+ICal.h" -#include "common.h" +#import +#import "iCalRecurrenceRule.h" +#import "NSCalendarDate+ICal.h" @interface iCalRecurrenceCalculator (PrivateAPI) diff --git a/SOPE/NGCards/iCalYearlyRecurrenceCalculator.m b/SOPE/NGCards/iCalYearlyRecurrenceCalculator.m index b940b26a..53603d5e 100644 --- a/SOPE/NGCards/iCalYearlyRecurrenceCalculator.m +++ b/SOPE/NGCards/iCalYearlyRecurrenceCalculator.m @@ -19,15 +19,16 @@ 02111-1307, USA. */ -#include "iCalRecurrenceCalculator.h" +#import + +#import "iCalRecurrenceCalculator.h" @interface iCalYearlyRecurrenceCalculator : iCalRecurrenceCalculator @end -#include -#include "iCalRecurrenceRule.h" -#include "NSCalendarDate+ICal.h" -#include "common.h" +#import +#import "iCalRecurrenceRule.h" +#import "NSCalendarDate+ICal.h" @interface iCalRecurrenceCalculator(PrivateAPI) - (NSCalendarDate *)lastInstanceStartDate; diff --git a/SoObjects/Appointments/SOGoCalendarComponent.h b/SoObjects/Appointments/SOGoCalendarComponent.h index 5675724b..db0d4df9 100644 --- a/SoObjects/Appointments/SOGoCalendarComponent.h +++ b/SoObjects/Appointments/SOGoCalendarComponent.h @@ -38,13 +38,11 @@ { iCalCalendar *calendar; NSString *calContent; - BOOL isNew; } - (NSString *) componentTag; - (iCalCalendar *) calendar: (BOOL) create; - (iCalRepeatableEntityObject *) component: (BOOL) create; -- (BOOL) isNew; - (NSException *) primarySaveContentString: (NSString *) _iCalString; - (NSException *) primaryDelete; diff --git a/SoObjects/Appointments/SOGoCalendarComponent.m b/SoObjects/Appointments/SOGoCalendarComponent.m index f0744483..5f707b18 100644 --- a/SoObjects/Appointments/SOGoCalendarComponent.m +++ b/SoObjects/Appointments/SOGoCalendarComponent.m @@ -71,7 +71,6 @@ static BOOL sendEMailNotifications = NO; { calendar = nil; calContent = nil; - isNew = NO; } return self; @@ -183,7 +182,6 @@ static BOOL sendEMailNotifications = NO; newComponent = [[calendar classForTag: componentTag] groupWithTag: componentTag]; [calendar addChild: newComponent]; - isNew = YES; } } if (calendar) @@ -200,11 +198,6 @@ static BOOL sendEMailNotifications = NO; firstChildWithTag: [self componentTag]]; } -- (BOOL) isNew -{ - return isNew; -} - /* raw saving */ - (NSException *) primarySaveContentString: (NSString *) _iCalString diff --git a/SoObjects/Mailer/SOGoMailFolder.m b/SoObjects/Mailer/SOGoMailFolder.m index c257a319..68c74678 100644 --- a/SoObjects/Mailer/SOGoMailFolder.m +++ b/SoObjects/Mailer/SOGoMailFolder.m @@ -283,16 +283,14 @@ static BOOL useAltNamespace = NO; /* create object */ - return [[[SOGoMailFolder alloc] initWithName:_key - inContainer:self] autorelease]; + return [SOGoMailFolder objectWithName: _key inContainer: self]; } - (id) lookupImap4Message: (NSString *) _key inContext: (id) _ctx { // TODO: we might want to check for existence prior controller creation - return [[[SOGoMailObject alloc] initWithName:_key - inContainer:self] autorelease]; + return [SOGoMailObject objectWithName: _key inContainer: self]; } - (id) lookupName: (NSString *) _key diff --git a/SoObjects/Mailer/SOGoMailObject.m b/SoObjects/Mailer/SOGoMailObject.m index 8f91f247..bfa226d5 100644 --- a/SoObjects/Mailer/SOGoMailObject.m +++ b/SoObjects/Mailer/SOGoMailObject.m @@ -680,12 +680,15 @@ static BOOL debugSoParts = NO; /* name lookup */ -- (id)lookupImap4BodyPartKey:(NSString *)_key inContext:(id)_ctx { +- (id) lookupImap4BodyPartKey: (NSString *) _key + inContext: (id) _ctx +{ // TODO: we might want to check for existence prior controller creation Class clazz; clazz = [SOGoMailBodyPart bodyPartClassForKey:_key inContext:_ctx]; - return [[[clazz alloc] initWithName:_key inContainer:self] autorelease]; + + return [clazz objectWithName:_key inContainer: self]; } - (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag { @@ -1064,6 +1067,11 @@ static BOOL debugSoParts = NO; return @"IPM.Message"; /* email, default class */ } +- (NSArray *) aclsForUser: (NSString *) uid +{ + return [container aclsForUser: uid]; +} + /* debugging */ - (BOOL)isDebuggingEnabled { diff --git a/SoObjects/SOGo/GNUmakefile b/SoObjects/SOGo/GNUmakefile index c5a1dcd0..ca032f9e 100644 --- a/SoObjects/SOGo/GNUmakefile +++ b/SoObjects/SOGo/GNUmakefile @@ -40,6 +40,8 @@ libSOGo_HEADER_FILES = \ NSDictionary+Utilities.h \ NSObject+Utilities.h \ NSString+Utilities.h \ + NSNumber+Utilities.h \ + NSNull+Utilities.h \ NSDictionary+URL.h \ NSCalendarDate+SOGo.h \ \ @@ -68,6 +70,8 @@ libSOGo_OBJC_FILES = \ NSDictionary+Utilities.m \ NSObject+Utilities.m \ NSString+Utilities.m \ + NSNumber+Utilities.m \ + NSNull+Utilities.m \ NSCalendarDate+SOGo.m \ \ SOGoAuthenticator.m \ diff --git a/UI/MailerUI/product.plist b/UI/MailerUI/product.plist index 242c43da..2ad34027 100644 --- a/UI/MailerUI/product.plist +++ b/UI/MailerUI/product.plist @@ -285,6 +285,11 @@ categories = { actionClass = "UIxMailAccountActions"; actionName = "listMailboxes"; }; + createFolder = { + protectedBy = "View"; + actionClass = "UIxMailFolderActions"; + actionName = "createFolder"; + }; }; }; diff --git a/UI/SOGoUI/SOGoDateFormatter.h b/UI/SOGoUI/SOGoDateFormatter.h index 4d460294..2e084842 100644 --- a/UI/SOGoUI/SOGoDateFormatter.h +++ b/UI/SOGoUI/SOGoDateFormatter.h @@ -41,6 +41,7 @@ - (void)setFullWeekdayNameAndDetails; - (NSString *)stringForObjectValue:(id)_obj; +- (NSString *) stringForSecondsSinceThe70s: (unsigned int) seconds; - (NSString *)shortDayOfWeek:(int)_day; - (NSString *)fullDayOfWeek:(int)_day; diff --git a/UI/SOGoUI/SOGoDateFormatter.m b/UI/SOGoUI/SOGoDateFormatter.m index c64aca82..c618be41 100644 --- a/UI/SOGoUI/SOGoDateFormatter.m +++ b/UI/SOGoUI/SOGoDateFormatter.m @@ -58,11 +58,18 @@ /* operation */ -- (NSString *)stringForObjectValue:(id)_obj { +- (NSString *) stringForObjectValue: (id) _obj +{ return [self performSelector:self->formatAction withObject:_obj]; } +- (NSString *) stringForSecondsSinceThe70s: (unsigned int) seconds +{ + return [self stringForObjectValue: + [NSCalendarDate dateWithTimeIntervalSince1970: seconds]]; +} + /* Helpers */ - (NSString *)shortDayOfWeek:(int)_day { diff --git a/UI/SOGoUI/UIxComponent.m b/UI/SOGoUI/UIxComponent.m index d18e248a..9332a7e5 100644 --- a/UI/SOGoUI/UIxComponent.m +++ b/UI/SOGoUI/UIxComponent.m @@ -541,7 +541,7 @@ static BOOL uixDebugEnabled = NO; - (NSDictionary *)locale { /* we need no fallback here, as locale is guaranteed to be set by sogod */ - return [[self context] valueForKey:@"locale"]; + return [context valueForKey: @"locale"]; } - (WOResourceManager *) pageResourceManager diff --git a/UI/Scheduler/English.lproj/Localizable.strings b/UI/Scheduler/English.lproj/Localizable.strings index 05d991c9..f49a55a9 100644 --- a/UI/Scheduler/English.lproj/Localizable.strings +++ b/UI/Scheduler/English.lproj/Localizable.strings @@ -362,7 +362,7 @@ validate_endbeforestart = "Enddate is before startdate!"; "Workweek days only" = "Workweek days only"; "Tasks in View" = "Tasks in View"; -"appointmentDeleteConfirmation" = "Erasing this event will be permanent.\\nWould you like to continue?"; +"eventDeleteConfirmation" = "Erasing this event will be permanent.\\nWould you like to continue?"; "taskDeleteConfirmation" = "Erasing this task will be permanent.\\nWould you like to continue?"; /* Legend */ diff --git a/UI/Scheduler/French.lproj/Localizable.strings b/UI/Scheduler/French.lproj/Localizable.strings index 44e9be99..5da57be7 100644 --- a/UI/Scheduler/French.lproj/Localizable.strings +++ b/UI/Scheduler/French.lproj/Localizable.strings @@ -360,7 +360,7 @@ validate_endbeforestart = "La date de fin est avant la date de début !"; "Workweek days only" = "Semaine de travail seulement"; "Tasks in View" = "Afficher les tâches"; -"appointmentDeleteConfirmation" = "L'effacement de cet événement sera permanent.\\nVoulez-vous continuer?"; +"eventDeleteConfirmation" = "L'effacement de cet événement sera permanent.\\nVoulez-vous continuer?"; "taskDeleteConfirmation" = "L'effacement de cette tâche sera permanent.\\nVoulez-vous continuer?"; /* Legend */ diff --git a/UI/Scheduler/GNUmakefile b/UI/Scheduler/GNUmakefile index 66c045d8..455d1bd1 100644 --- a/UI/Scheduler/GNUmakefile +++ b/UI/Scheduler/GNUmakefile @@ -20,8 +20,6 @@ SchedulerUI_OBJC_FILES = \ \ UIxComponent+Scheduler.m \ UIxCalView.m \ - UIxCalAptListView.m \ - UIxCalTasksListView.m \ UIxCalDayView.m \ UIxCalMulticolumnDayView.m \ UIxCalWeekView.m \ @@ -29,6 +27,8 @@ SchedulerUI_OBJC_FILES = \ UIxCalMonthViewOld.m \ UIxAptTableView.m \ \ + UIxCalListingActions.m \ + \ UIxAttendeesEditor.m \ UIxComponentEditor.m \ UIxCalendarSelector.m \ @@ -41,8 +41,6 @@ SchedulerUI_OBJC_FILES = \ UIxCalDateLabel.m \ UIxDatePicker.m \ UIxTimeDateControl.m \ - UIxCalInlineAptView.m \ - UIxCalInlineMonthAptView.m \ UIxCalParticipationStatusView.m \ UIxCalMonthOverview.m diff --git a/UI/Scheduler/UIxAppointmentEditor.h b/UI/Scheduler/UIxAppointmentEditor.h index 7254f5d6..e9074550 100644 --- a/UI/Scheduler/UIxAppointmentEditor.h +++ b/UI/Scheduler/UIxAppointmentEditor.h @@ -31,6 +31,7 @@ @interface UIxAppointmentEditor : UIxComponent { iCalEvent *event; + BOOL isAllDay; NSCalendarDate *aptStartDate; NSCalendarDate *aptEndDate; NSString *item; diff --git a/UI/Scheduler/UIxAppointmentEditor.m b/UI/Scheduler/UIxAppointmentEditor.m index 3c4d20e9..365cab4e 100644 --- a/UI/Scheduler/UIxAppointmentEditor.m +++ b/UI/Scheduler/UIxAppointmentEditor.m @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include + #import #import #import @@ -46,6 +48,7 @@ aptEndDate = nil; item = nil; event = nil; + isAllDay = NO; } return self; @@ -66,11 +69,17 @@ /* icalendar values */ - (BOOL) isAllDay { - return NO; + NSString *hm; + + hm = [self queryParameterForKey: @"hm"]; + + return (isAllDay + || (hm && [hm isEqualToString: @"allday"])); } - (void) setIsAllDay: (BOOL) newIsAllDay { + isAllDay = newIsAllDay; } - (void) setAptStartDate: (NSCalendarDate *) newAptStartDate @@ -245,7 +254,11 @@ if (event) { startDate = [event startDate]; - endDate = [event endDate]; + isAllDay = [event isAllDay]; + if (isAllDay) + endDate = [[event endDate] dateByAddingYears: 0 months: 0 days: -1]; + else + endDate = [event endDate]; } else { @@ -263,6 +276,7 @@ ASSIGN (aptStartDate, startDate); ASSIGN (aptEndDate, endDate); + /* here comes the code for initializing repeat, reminder and isAllDay... */ return self; @@ -299,7 +313,7 @@ iCalString = [[clientObject calendar: NO] versitString]; [clientObject saveContentString: iCalString]; - return [self jsCloseWithRefreshMethod: @"refreshAppointmentsAndDisplay()"]; + return [self jsCloseWithRefreshMethod: @"refreshEventsAndDisplay()"]; } - (BOOL) shouldTakeValuesFromRequest: (WORequest *) request @@ -313,14 +327,25 @@ inContext: (WOContext *) _ctx { SOGoAppointmentObject *clientObject; + int nbrDays; clientObject = [self clientObject]; event = (iCalEvent *) [clientObject component: YES]; [super takeValuesFromRequest: _rq inContext: _ctx]; - [event setStartDate: aptStartDate]; - [event setEndDate: aptEndDate]; + if (isAllDay) + { + nbrDays = ((float) abs ([aptEndDate timeIntervalSinceDate: aptStartDate]) + / 86400) + 1; + [event setAllDayWithStartDate: aptStartDate + duration: nbrDays]; + } + else + { + [event setStartDate: aptStartDate]; + [event setEndDate: aptEndDate]; + } if ([clientObject isNew]) [event setTransparency: @"OPAQUE"]; } diff --git a/UI/Scheduler/UIxCalAptListView.h b/UI/Scheduler/UIxCalAptListView.h deleted file mode 100644 index b2205239..00000000 --- a/UI/Scheduler/UIxCalAptListView.h +++ /dev/null @@ -1,43 +0,0 @@ -/* UIxCalAptListView.h - this file is part of SOGo - * - * Copyright (C) 2006 Inverse groupe conseil - * - * Author: Wolfgang Sourdeau - * - * 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. - */ - -#ifndef UIXCALAPTLISTVIEW_H -#define UIXCALAPTLISTVIEW_H - -#import "UIxCalView.h" - -@class NSDictionary; - -@interface UIxCalAptListView : UIxCalView -{ - NSCalendarDate *startDate; - NSCalendarDate *endDate; - - NSDictionary *currentAppointment; -} - -- (void) setCurrentAppointment: (NSDictionary *) apt; -- (NSDictionary *) currentAppointment; - -@end - -#endif /* UIXCALAPTLIST_H */ diff --git a/UI/Scheduler/UIxCalAptListView.m b/UI/Scheduler/UIxCalAptListView.m deleted file mode 100644 index 92d227d8..00000000 --- a/UI/Scheduler/UIxCalAptListView.m +++ /dev/null @@ -1,183 +0,0 @@ -/* UIxCalAptListView.m - this file is part of SOGo - * - * Copyright (C) 2006 Inverse groupe conseil - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import - -#import -#import - -#import - -#import "UIxCalAptListView.h" - -@implementation UIxCalAptListView - -- (id) init -{ - if ((self = [super init])) - { - startDate = nil; - endDate = nil; - } - - return self; -} - -- (void) setCurrentAppointment: (NSDictionary *) apt -{ - currentAppointment = apt; -} - -- (NSDictionary *) currentAppointment -{ - return currentAppointment; -} - -- (NSCalendarDate *) startDate -{ - NSCalendarDate *today; - NSString *filterPopup; - - if (!startDate) - { - filterPopup = [self queryParameterForKey: @"filterpopup"]; - today = [[NSCalendarDate date] beginOfDay]; - if (!filterPopup || ![filterPopup length]) - startDate = today; - else if ([filterPopup isEqualToString: @"view_selectedday"]) - startDate = [[self selectedDate] beginOfDay]; - else if ([filterPopup isEqualToString: @"view_thismonth"]) - startDate = [today firstDayOfMonth]; - else if ([filterPopup isEqualToString: @"view_all"]) - startDate = [NSCalendarDate dateWithTimeIntervalSince1970: 0]; - else - startDate = today; - } - - return startDate; -} - -- (NSCalendarDate *) endDate -{ - NSCalendarDate *today; - NSString *filterPopup; - - if (!endDate) - { - filterPopup = [self queryParameterForKey: @"filterpopup"]; - - today = [[NSCalendarDate date] endOfDay]; - if (!filterPopup || ![filterPopup length] - || [filterPopup isEqualToString: @"view_today"]) - endDate = today; - else if ([filterPopup isEqualToString: @"view_all"] - || [filterPopup isEqualToString: @"view_future"]) - endDate = [NSCalendarDate dateWithTimeIntervalSince1970: 0x7fffffff]; - else if ([filterPopup isEqualToString: @"view_thismonth"]) - endDate = [today lastDayOfMonth]; - else if ([filterPopup isEqualToString: @"view_selectedday"]) - endDate = [[self selectedDate] endOfDay]; - else if ([filterPopup isEqualToString: @"view_next7"]) - endDate = [today dateByAddingYears: 0 months: 0 days: 7]; - else if ([filterPopup isEqualToString: @"view_next14"]) - endDate = [today dateByAddingYears: 0 months: 0 days: 14]; - else if ([filterPopup isEqualToString: @"view_next31"]) - endDate = [today dateByAddingYears: 0 months: 1 days: 0]; - else - endDate = today; - } - - return endDate; -} - -- (SOGoDateFormatter *) itemDateFormatter -{ - SOGoDateFormatter *fmt; - - fmt = [[SOGoDateFormatter alloc] initWithLocale: [self locale]]; - [fmt autorelease]; - [fmt setFullWeekdayNameAndDetails]; - - return fmt; -} - -- (NSString *) currentStartTime -{ - NSCalendarDate *date; - - date = [NSCalendarDate dateWithTimeIntervalSince1970: - [[currentAppointment objectForKey: @"startdate"] - intValue]]; - [date setTimeZone: timeZone]; - - return [[self itemDateFormatter] stringForObjectValue: date]; -} - -- (NSString *) currentEndTime -{ - NSCalendarDate *date; - - date = [NSCalendarDate dateWithTimeIntervalSince1970: - [[currentAppointment objectForKey: @"enddate"] - intValue]]; - [date setTimeZone: timeZone]; - - return [[self itemDateFormatter] stringForObjectValue: date]; -} - -- (NSString *) currentLocation -{ - return [currentAppointment objectForKey: @"location"]; -} - -- (NSString *) currentSerialDay -{ - NSCalendarDate *date; - int intDate; - - intDate = [[currentAppointment objectForKey: @"startdate"] intValue]; - date = [NSCalendarDate dateWithTimeIntervalSince1970: intDate]; - [date setTimeZone: timeZone]; - - return [NSString stringWithFormat: @"%d%.2d%.2d", - [date yearOfCommonEra], - [date monthOfYear], - [date dayOfMonth]]; -} - -- (NSString *) currentSerialHour -{ - NSCalendarDate *date; - int intDate; - - intDate = [[currentAppointment objectForKey: @"startdate"] intValue]; - date = [NSCalendarDate dateWithTimeIntervalSince1970: intDate]; - [date setTimeZone: timeZone]; - - return [NSString stringWithFormat: @"%.2d%.2d", - [date hourOfDay], - [date minuteOfHour]]; -} - -@end diff --git a/UI/Scheduler/UIxCalDayTable.h b/UI/Scheduler/UIxCalDayTable.h index 1cd2d3ad..37f6364d 100644 --- a/UI/Scheduler/UIxCalDayTable.h +++ b/UI/Scheduler/UIxCalDayTable.h @@ -40,9 +40,6 @@ NSString *currentTableHour; NSMutableArray *daysToDisplay; NSMutableArray *hoursToDisplay; - NSArray *allAppointments; - - NSDictionary *currentAppointment; NSString *cssClass; NSString *cssId; @@ -65,9 +62,6 @@ - (void) setCurrentTableDay: (NSCalendarDate *) aTableDay; - (NSCalendarDate *) currentTableDay; -- (void) setCurrentAppointment: (NSDictionary *) newCurrentAppointment; -- (NSDictionary *) currentAppointment; - @end #endif /* UIXCALDAYTABLE_H */ diff --git a/UI/Scheduler/UIxCalDayTable.m b/UI/Scheduler/UIxCalDayTable.m index 0cb213e2..aac4cf73 100644 --- a/UI/Scheduler/UIxCalDayTable.m +++ b/UI/Scheduler/UIxCalDayTable.m @@ -41,7 +41,7 @@ { if ((self = [super init])) { - allAppointments = nil; +// allAppointments = nil; daysToDisplay = nil; hoursToDisplay = nil; numberOfDays = 1; @@ -57,12 +57,10 @@ - (void) dealloc { - if (allAppointments) - [allAppointments release]; - if (daysToDisplay) - [daysToDisplay release]; - if (hoursToDisplay) - [hoursToDisplay release]; +// if (allAppointments) +// [allAppointments release]; + [daysToDisplay release]; + [hoursToDisplay release]; [dateFormatter release]; [super dealloc]; } @@ -90,11 +88,8 @@ - (void) setNumberOfDays: (NSString *) aNumber { numberOfDays = [aNumber intValue]; - if (daysToDisplay) - { - [daysToDisplay release]; - daysToDisplay = nil; - } + [daysToDisplay release]; + daysToDisplay = nil; } - (NSString *) numberOfDays @@ -105,11 +100,8 @@ - (void) setStartDate: (NSCalendarDate *) aStartDate { startDate = aStartDate; - if (daysToDisplay) - { - [daysToDisplay release]; - daysToDisplay = nil; - } + [daysToDisplay release]; + daysToDisplay = nil; } - (NSCalendarDate *) startDate @@ -169,6 +161,7 @@ [daysToDisplay addObject: [currentDate dateByAddingYears: 0 months: 0 days: count]]; + } return daysToDisplay; @@ -201,94 +194,97 @@ - (NSString *) labelForDay { - return [NSString stringWithFormat: @"%@
%@", - [dateFormatter shortDayOfWeek: [currentTableDay dayOfWeek]], - [dateFormatter stringForObjectValue: currentTableDay]]; + return [dateFormatter shortDayOfWeek: [currentTableDay dayOfWeek]]; } -- (NSDictionary *) _adjustedAppointment: (NSDictionary *) anAppointment - forStart: (NSCalendarDate *) start - andEnd: (NSCalendarDate *) end +- (NSString *) labelForDate { - NSMutableDictionary *newMutableAppointment; - NSDictionary *newAppointment; - BOOL startIsEarlier, endIsLater; - - startIsEarlier - = ([[anAppointment objectForKey: @"startDate"] laterDate: start] == start); - endIsLater - = ([[anAppointment objectForKey: @"endDate"] earlierDate: end] == end); - - if (startIsEarlier || endIsLater) - { - newMutableAppointment - = [NSMutableDictionary dictionaryWithDictionary: anAppointment]; - - if (startIsEarlier) - [newMutableAppointment setObject: start - forKey: @"startDate"]; - if (endIsLater) - [newMutableAppointment setObject: end - forKey: @"endDate"]; - - newAppointment = newMutableAppointment; - } - else - newAppointment = anAppointment; - - return newAppointment; + return [dateFormatter stringForObjectValue: currentTableDay]; } -- (NSArray *) appointmentsForCurrentDay -{ - NSMutableArray *filteredAppointments; - NSEnumerator *aptsEnumerator; - NSDictionary *currentDayAppointment; - NSCalendarDate *start, *end; - int endHour; - - if (!allAppointments) - { - allAppointments = [self fetchCoreAppointmentsInfos]; - [allAppointments retain]; - } - - filteredAppointments = [NSMutableArray new]; - [filteredAppointments autorelease]; - - start = [currentTableDay hour: [self dayStartHour] minute: 0]; - endHour = [self dayEndHour]; - if (endHour < 24) - end = [currentTableDay hour: [self dayEndHour] minute: 59]; - else - end = [[currentTableDay tomorrow] hour: 0 minute: 0]; - - aptsEnumerator = [allAppointments objectEnumerator]; - currentDayAppointment = [aptsEnumerator nextObject]; - while (currentDayAppointment) - { - if (([end laterDate: [currentDayAppointment - valueForKey: @"startDate"]] == end) - && ([start earlierDate: [currentDayAppointment - valueForKey: @"endDate"]] == start)) - [filteredAppointments - addObject: [self _adjustedAppointment: currentDayAppointment - forStart: start andEnd: end]]; - currentDayAppointment = [aptsEnumerator nextObject]; - } - - return filteredAppointments; -} - -- (void) setCurrentAppointment: (NSDictionary *) newCurrentAppointment -{ - currentAppointment = newCurrentAppointment; -} - -- (NSDictionary *) currentAppointment -{ - return currentAppointment; -} +// - (NSDictionary *) _adjustedAppointment: (NSDictionary *) anAppointment +// forStart: (NSCalendarDate *) start +// andEnd: (NSCalendarDate *) end +// { +// NSMutableDictionary *newMutableAppointment; +// NSDictionary *newAppointment; +// BOOL startIsEarlier, endIsLater; + +// startIsEarlier +// = ([[anAppointment objectForKey: @"startDate"] laterDate: start] == start); +// endIsLater +// = ([[anAppointment objectForKey: @"endDate"] earlierDate: end] == end); + +// if (startIsEarlier || endIsLater) +// { +// newMutableAppointment +// = [NSMutableDictionary dictionaryWithDictionary: anAppointment]; + +// if (startIsEarlier) +// [newMutableAppointment setObject: start +// forKey: @"startDate"]; +// if (endIsLater) +// [newMutableAppointment setObject: end +// forKey: @"endDate"]; + +// newAppointment = newMutableAppointment; +// } +// else +// newAppointment = anAppointment; + +// return newAppointment; +// } + +// - (NSArray *) appointmentsForCurrentDay +// { +// NSMutableArray *filteredAppointments; +// NSEnumerator *aptsEnumerator; +// NSDictionary *currentDayAppointment; +// NSCalendarDate *start, *end; +// int endHour; + +// if (!allAppointments) +// { +// allAppointments = [self fetchCoreAppointmentsInfos]; +// [allAppointments retain]; +// } + +// filteredAppointments = [NSMutableArray new]; +// [filteredAppointments autorelease]; + +// start = [currentTableDay hour: [self dayStartHour] minute: 0]; +// endHour = [self dayEndHour]; +// if (endHour < 24) +// end = [currentTableDay hour: [self dayEndHour] minute: 59]; +// else +// end = [[currentTableDay tomorrow] hour: 0 minute: 0]; + +// aptsEnumerator = [allAppointments objectEnumerator]; +// currentDayAppointment = [aptsEnumerator nextObject]; +// while (currentDayAppointment) +// { +// if (([end laterDate: [currentDayAppointment +// valueForKey: @"startDate"]] == end) +// && ([start earlierDate: [currentDayAppointment +// valueForKey: @"endDate"]] == start)) +// [filteredAppointments +// addObject: [self _adjustedAppointment: currentDayAppointment +// forStart: start andEnd: end]]; +// currentDayAppointment = [aptsEnumerator nextObject]; +// } + +// return filteredAppointments; +// } + +// - (void) setCurrentAppointment: (NSDictionary *) newCurrentAppointment +// { +// currentAppointment = newCurrentAppointment; +// } + +// - (NSDictionary *) currentAppointment +// { +// return currentAppointment; +// } - (NSString *) appointmentsClasses { diff --git a/UI/Scheduler/UIxCalInlineAptView.h b/UI/Scheduler/UIxCalInlineAptView.h deleted file mode 100644 index f35ad15e..00000000 --- a/UI/Scheduler/UIxCalInlineAptView.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (C) 2000-2004 SKYRIX Software AG - - This file is part of OGo - - OGo is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - OGo 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 Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. - */ -// $Id: UIxCalInlineAptView.h 1031 2007-03-07 22:52:32Z wolfgang $ - -#ifndef UIXCALINLINEAPTVIEW_H -#define UIXCALINLINEAPTVIEW_H - -#import - -@interface UIxCalInlineAptView : WOComponent -{ - NSDictionary *appointment; - id formatter; - id tooltipFormatter; - id url; - id style; - id queryDictionary; - id referenceDate; - int dayStartHour; - int dayEndHour; - BOOL canAccess; -} - -@end - -#endif /* UIXCALINLINEAPTVIEW_H */ diff --git a/UI/Scheduler/UIxCalInlineAptView.m b/UI/Scheduler/UIxCalInlineAptView.m deleted file mode 100644 index 9fd641ac..00000000 --- a/UI/Scheduler/UIxCalInlineAptView.m +++ /dev/null @@ -1,287 +0,0 @@ -/* - Copyright (C) 2000-2004 SKYRIX Software AG - - This file is part of OGo - - OGo is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - OGo 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 Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. - */ -// $Id$ - -#import - -#import - -#import -#import -#import - -#import -#import -#import -#import - -#import "UIxCalInlineAptView.h" - -@implementation UIxCalInlineAptView - -- (id) init -{ - if ((self = [super init])) - { - dayStartHour = 0; - dayEndHour = 24; - appointment = nil; - } - - return self; -} - -- (void) dealloc -{ - [appointment release]; - [formatter release]; - [tooltipFormatter release]; - [url release]; - [style release]; - [queryDictionary release]; - [referenceDate release]; - [super dealloc]; -} - -- (void) setAppointment: (NSDictionary *) _appointment -{ - ASSIGN(appointment, _appointment); -} - -- (NSDictionary *) appointment -{ - return appointment; -} - -- (void) setDayStartHour: (unsigned int) anHour -{ - dayStartHour = anHour; -} - -- (void) setDayEndHour: (unsigned int) anHour -{ - dayEndHour = anHour; -} - -- (void) setFormatter: (id) _formatter -{ - ASSIGN(formatter, _formatter); -} - -- (id) formatter -{ - return formatter; -} - -- (void) setTooltipFormatter: (id) _tooltipFormatter -{ - ASSIGN(tooltipFormatter, _tooltipFormatter); -} - -- (id) tooltipFormatter -{ - return tooltipFormatter; -} - -- (void) setUrl: (id) _url -{ - ASSIGN(url, _url); -} - -- (id) url -{ - return url; -} - -- (void) setStyle: (id) _style -{ - NSMutableString *ms; - NSNumber *prio; - NSString *s; - NSString *email; - - if (_style) - ms = [NSMutableString stringWithString: _style]; - else - ms = (NSMutableString *)[NSMutableString string]; - - if ((prio = [appointment valueForKey:@"priority"])) { - [ms appendFormat:@" apt_prio%@", prio]; - } - email = [[context activeUser] primaryEmail]; - s = [appointment valueForKey:@"orgmail"]; - if ([s isNotNull]) - { - if ([s rangeOfString: email].length > 0) - [ms appendString:@" apt_organizer"]; - else - [ms appendString:@" apt_other"]; - } - s = [appointment valueForKey:@"partmails"]; - if ([s isNotNull]) - { - if ([s rangeOfString:email].length > 0) - [ms appendString:@" apt_participant"]; - else - [ms appendString:@" apt_nonparticipant"]; - } - ASSIGNCOPY(style, ms); -} - -- (id)style { - return style; -} - -- (void) setQueryDictionary: (id) _queryDictionary -{ - ASSIGN(queryDictionary, _queryDictionary); -} - -- (id) queryDictionary -{ - return queryDictionary; -} - -- (void) setReferenceDate: (id) _referenceDate -{ - ASSIGN(referenceDate, _referenceDate); -} - -- (id) referenceDate -{ - return referenceDate; -} - -- (void) setCanAccess: (BOOL) _canAccess -{ - canAccess = _canAccess; -} - -- (BOOL) canAccess -{ - return canAccess; -} - -- (NSString *) displayClasses -{ - NSTimeInterval secondsStart, secondsEnd, delta; - NSCalendarDate *startDate; - int deltaStart, deltaLength; - - startDate = [appointment objectForKey: @"startDate"]; - secondsStart = [startDate timeIntervalSince1970]; - secondsEnd = [[appointment objectForKey: @"endDate"] timeIntervalSince1970]; - delta = (secondsEnd - [startDate timeIntervalSince1970]) / 60; - deltaLength = delta / 15; - if (((int) delta % 15) > 0) - deltaLength += 1; - - deltaStart = (([startDate hourOfDay] * 60 + [startDate minuteOfHour] - - dayStartHour * 60) / 15); - - return [NSString stringWithFormat: @"appointment starts%d lasts%d", - deltaStart, deltaLength, [startDate dayOfWeek]]; -} - -- (NSString *) innerDisplayClasses -{ - return [NSString stringWithFormat: @"appointmentInside ownerIs%@", - [appointment objectForKey: @"owner"]]; -} - -- (NSString *) displayStyle -{ - NSCalendarDate *startDate, *endDate, *dayStart, *dayEnd; - int sSeconds, eSeconds, deltaMinutes; - unsigned int height; - NSTimeZone *uTZ; - - uTZ = [referenceDate timeZone]; - dayStart = [referenceDate beginOfDay]; - dayEnd = [referenceDate endOfDay]; - - sSeconds = [[appointment objectForKey: @"startdate"] intValue]; - eSeconds = [[appointment objectForKey: @"enddate"] intValue]; - startDate = [NSCalendarDate dateWithTimeIntervalSince1970: sSeconds]; - [startDate setTimeZone: uTZ]; - if ([startDate earlierDate: dayStart] == startDate) - startDate = dayStart; - endDate = [NSCalendarDate dateWithTimeIntervalSince1970: eSeconds]; - [endDate setTimeZone: uTZ]; - if ([endDate earlierDate: dayEnd] == dayEnd) - endDate = dayEnd; - - deltaMinutes = (([endDate hourOfDay] - [startDate hourOfDay]) * 60 - + [endDate minuteOfHour] - [startDate minuteOfHour]); - height = ceil(deltaMinutes / 15) * 25; - - return [NSString stringWithFormat: @"height: %d%%;", height]; -} - -/* helpers */ - -- (NSString *) startHour -{ - NSCalendarDate *start; - - start = [appointment objectForKey: @"startDate"]; - - return [NSString stringWithFormat: @"%.2d:%.2d", - [start hourOfDay], [start minuteOfHour]]; -} - -- (NSString *) title -{ - return [formatter stringForObjectValue: appointment - referenceDate: [self referenceDate]]; -} - -- (NSString *) tooltip -{ - return [tooltipFormatter stringForObjectValue: appointment - referenceDate: [self referenceDate]]; -} - -- (BOOL) _userIsInTheCard: (NSString *) email -{ - NSString *orgMailString, *partMailsString; - NSArray *partMails; - BOOL userIsInTheCard; - - orgMailString = [appointment objectForKey: @"orgmail"]; - if ([orgMailString isNotNull] && [orgMailString isEqualToString: email]) - userIsInTheCard = YES; - else - { - partMailsString = [appointment objectForKey: @"partmails"]; - if ([partMailsString isNotNull]) - { - partMails = [partMailsString componentsSeparatedByString: @"\n"]; - userIsInTheCard = [partMails containsObject: email]; - } - else - userIsInTheCard = NO; - } - - return userIsInTheCard; -} - -@end diff --git a/UI/Scheduler/UIxCalInlineMonthAptView.h b/UI/Scheduler/UIxCalInlineMonthAptView.h deleted file mode 100644 index aae77fc5..00000000 --- a/UI/Scheduler/UIxCalInlineMonthAptView.h +++ /dev/null @@ -1,32 +0,0 @@ -/* UIxCalInlineMonthAptView.h - this file is part of SOGo - * - * Copyright (C) 2007 Inverse groupe conseil - * - * Author: Wolfgang Sourdeau - * - * 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. - */ - -#ifndef UIXCALINLINEMONTHAPTVIEW_H -#define UIXCALINLINEMONTHAPTVIEW_H - -#import "UIxCalInlineAptView.h" - -@interface UIxCalInlineMonthAptView : UIxCalInlineAptView - -@end - -#endif /* UIXCALINLINEMONTHAPTVIEW_H */ diff --git a/UI/Scheduler/UIxCalInlineMonthAptView.m b/UI/Scheduler/UIxCalInlineMonthAptView.m deleted file mode 100644 index ff7a6b6d..00000000 --- a/UI/Scheduler/UIxCalInlineMonthAptView.m +++ /dev/null @@ -1,27 +0,0 @@ -/* UIxCalInlineMonthAptView.m - this file is part of SOGo - * - * Copyright (C) 2007 Inverse groupe conseil - * - * Author: Wolfgang Sourdeau - * - * 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 "UIxCalInlineMonthAptView.h" - -@implementation UIxCalInlineMonthAptView - -@end diff --git a/UI/Scheduler/UIxCalTasksListView.h b/UI/Scheduler/UIxCalListingActions.h similarity index 62% rename from UI/Scheduler/UIxCalTasksListView.h rename to UI/Scheduler/UIxCalListingActions.h index 8cefb7ca..ed455673 100644 --- a/UI/Scheduler/UIxCalTasksListView.h +++ b/UI/Scheduler/UIxCalListingActions.h @@ -1,4 +1,4 @@ -/* UIxCalTasksListView.h - this file is part of SOGo +/* UIxCalListingActions.h - this file is part of SOGo * * Copyright (C) 2006 Inverse groupe conseil * @@ -20,18 +20,35 @@ * Boston, MA 02111-1307, USA. */ -#ifndef UIXCALTASKSLISTVIEW_H -#define UIXCALTASKSLISTVIEW_H +#ifndef UIXCALLISTINGACTIONVIEW_H +#define UIXCALLISTINGACTIONVIEW_H #import -@class WOResponse; +@class NSCalendarDate; +@class NSMutableDictionary; +@class NSString; +@class NSTimeZone; -@interface UIxCalTasksListView : WODirectAction +@class SOGoDateFormatter; +@class WOResponse; +@class WORequest; + +@interface UIxCalListingActions : WODirectAction +{ + NSMutableDictionary *componentsData; + NSCalendarDate *startDate; + NSCalendarDate *endDate; + NSString *userLogin; + WORequest *request; + SOGoDateFormatter *dateFormatter; +} + +- (WOResponse *) eventsListAction; - (WOResponse *) tasksListAction; @end -#endif /* UIXCALTASKSLIST_H */ +#endif /* UIXCALLISTINGACTION_H */ diff --git a/UI/Scheduler/UIxCalListingActions.m b/UI/Scheduler/UIxCalListingActions.m new file mode 100644 index 00000000..d3aa3cac --- /dev/null +++ b/UI/Scheduler/UIxCalListingActions.m @@ -0,0 +1,430 @@ +/* UIxCalListingActions.m - this file is part of SOGo + * + * Copyright (C) 2006 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * 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 +#import +#import +#import +#import + +#import +#import +#import +#import +#import + +#import +#import +#import +#import +#import + +#import "../SOGoUI/SOGoDateFormatter.h" + +#import "UIxCalListingActions.h" + +@implementation UIxCalListingActions + +- (id) initWithRequest: (WORequest *) newRequest +{ + NSDictionary *locale; + + if ((self = [super initWithRequest: newRequest])) + { + componentsData = [NSMutableDictionary new]; + startDate = nil; + endDate = nil; + ASSIGN (request, newRequest); + locale = [[self context] valueForKey: @"locale"]; + dateFormatter = [[SOGoDateFormatter alloc] initWithLocale: locale]; + [dateFormatter setFullWeekdayNameAndDetails]; + } + + return self; +} + +- (void) dealloc +{ + [dateFormatter release]; + [request release]; + [componentsData release]; + [startDate release]; + [endDate release]; + [super dealloc]; +} + +- (void) _setupDatesWithPopup: (NSString *) popupValue + andUserTZ: (NSTimeZone *) userTZ +{ + NSCalendarDate *newDate; + NSString *param; + + if ([popupValue isEqualToString: @"view_today"]) + { + newDate = [NSCalendarDate calendarDate]; + [newDate setTimeZone: userTZ]; + startDate = [newDate beginOfDay]; + endDate = [newDate endOfDay]; + } + else if ([popupValue isEqualToString: @"view_all"]) + { + startDate = nil; + endDate = nil; + } + else if ([popupValue isEqualToString: @"view_next7"]) + { + newDate = [NSCalendarDate calendarDate]; + [newDate setTimeZone: userTZ]; + startDate = [newDate beginOfDay]; + endDate = [[startDate dateByAddingYears: 0 months: 0 days: 6] endOfDay]; + } + else if ([popupValue isEqualToString: @"view_next14"]) + { + newDate = [NSCalendarDate calendarDate]; + [newDate setTimeZone: userTZ]; + startDate = [newDate beginOfDay]; + endDate = [[startDate dateByAddingYears: 0 months: 0 days: 13] endOfDay]; + } + else if ([popupValue isEqualToString: @"view_next31"]) + { + newDate = [NSCalendarDate calendarDate]; + [newDate setTimeZone: userTZ]; + startDate = [newDate beginOfDay]; + endDate = [[startDate dateByAddingYears: 0 months: 0 days: 30] endOfDay]; + } + else if ([popupValue isEqualToString: @"view_thismonth"]) + { + newDate = [NSCalendarDate calendarDate]; + [newDate setTimeZone: userTZ]; + startDate = [[newDate firstDayOfMonth] beginOfDay]; + endDate = [[newDate lastDayOfMonth] endOfDay]; + } + else if ([popupValue isEqualToString: @"view_future"]) + { + newDate = [NSCalendarDate calendarDate]; + [newDate setTimeZone: userTZ]; + startDate = [newDate beginOfDay]; + endDate = [NSCalendarDate distantFuture]; + } + else if ([popupValue isEqualToString: @"view_selectedday"]) + { + param = [request formValueForKey: @"day"]; + if ([param length] > 0) + startDate = [[NSCalendarDate dateFromShortDateString: param + andShortTimeString: nil + inTimeZone: userTZ] beginOfDay]; + else + { + newDate = [NSCalendarDate calendarDate]; + [newDate setTimeZone: userTZ]; + startDate = [newDate beginOfDay]; + } + endDate = [startDate endOfDay]; + } +} + +- (void) _setupContext +{ + SOGoUser *user; + NSTimeZone *userTZ; + NSString *param; + + user = [context activeUser]; + userLogin = [user login]; + userTZ = [user timeZone]; + + param = [request formValueForKey: @"filterpopup"]; + if ([param length] > 0) + [self _setupDatesWithPopup: param andUserTZ: userTZ]; + else + { + param = [request formValueForKey: @"sd"]; + if ([param length] > 0) + startDate = [[NSCalendarDate dateFromShortDateString: param + andShortTimeString: nil + inTimeZone: userTZ] beginOfDay]; + else + startDate = nil; + + param = [request formValueForKey: @"ed"]; + if ([param length] > 0) + endDate = [[NSCalendarDate dateFromShortDateString: param + andShortTimeString: nil + inTimeZone: userTZ] endOfDay]; + else + endDate = nil; + } +} + +- (void) _updatePrivacyInComponent: (NSMutableDictionary *) component + fromFolder: (SOGoAppointmentFolder *) folder +{ + int privacyFlag; + NSString *roleString; + + privacyFlag = [[component objectForKey: @"classification"] intValue]; + roleString = [folder roleForComponentsWithAccessClass: privacyFlag + forUser: userLogin]; + if ([roleString isEqualToString: @"ComponentDAndTViewer"]) + { + [component setObject: @"" forKey: @"title"]; + [component setObject: @"" forKey: @"location"]; + } +} + +- (SOGoAppointmentFolder *) _aptFolder: (NSString *) folder + withClientObject: (SOGoAppointmentFolder *) clientObject +{ + SOGoAppointmentFolder *aptFolder; + NSArray *folderParts; + + if ([folder isEqualToString: @"/"]) + aptFolder = clientObject; + else + { + folderParts = [folder componentsSeparatedByString: @":"]; + aptFolder + = [clientObject lookupCalendarFolderForUID: + [folderParts objectAtIndex: 0]]; + } + + return aptFolder; +} + +- (NSArray *) _activeCalendarFolders +{ + NSMutableArray *activeFolders; + NSEnumerator *folders; + NSDictionary *currentFolderDict; + SOGoAppointmentFolder *currentFolder, *clientObject; + + activeFolders = [NSMutableArray new]; + [activeFolders autorelease]; + + clientObject = [self clientObject]; + + folders = [[clientObject calendarFolders] objectEnumerator]; + currentFolderDict = [folders nextObject]; + while (currentFolderDict) + { + if ([[currentFolderDict objectForKey: @"active"] boolValue]) + { + currentFolder + = [self _aptFolder: [currentFolderDict objectForKey: @"folder"] + withClientObject: clientObject]; + [activeFolders addObject: currentFolder]; + } + + currentFolderDict = [folders nextObject]; + } + + return activeFolders; +} + +- (NSArray *) _fetchFields: (NSArray *) fields + forComponentOfType: (NSString *) component +{ + NSEnumerator *folders, *currentInfos; + SOGoAppointmentFolder *currentFolder; + NSMutableDictionary *infos, *currentInfo, *newInfo; + NSString *owner, *uid; + NSNull *marker; + + marker = [NSNull null]; + + infos = [NSMutableDictionary dictionary]; + folders = [[self _activeCalendarFolders] objectEnumerator]; + currentFolder = [folders nextObject]; + while (currentFolder) + { + owner = [currentFolder ownerInContext: context]; + currentInfos = [[currentFolder fetchCoreInfosFrom: startDate + to: endDate + component: component] objectEnumerator]; + newInfo = [currentInfos nextObject]; + while (newInfo) + { + uid = [newInfo objectForKey: @"uid"]; + currentInfo = [infos objectForKey: uid]; + if (!currentInfo + || [owner isEqualToString: userLogin]) + { + [self _updatePrivacyInComponent: newInfo + fromFolder: currentFolder]; + [newInfo setObject: owner forKey: @"owner"]; + [infos setObject: [newInfo objectsForKeys: fields + notFoundMarker: marker] + forKey: uid]; + } + newInfo = [currentInfos nextObject]; + } + currentFolder = [folders nextObject]; + } + + return [infos allValues]; +} + +- (WOResponse *) _responseWithData: (NSArray *) data +{ + WOResponse *response; + + response = [context response]; + [response setHeader: @"text/plain; charset=utf-8" + forKey: @"content-type"]; + [response setStatus: 200]; + [response appendContentString: [data jsonRepresentation]]; + + return response; +} + +- (WOResponse *) eventsListAction +{ + NSArray *fields, *oldEvent; + NSEnumerator *events; + NSString *date; + NSMutableArray *newEvents, *newEvent; + unsigned int interval; + + [self _setupContext]; + + newEvents = [NSMutableArray array]; + fields = [NSArray arrayWithObjects: @"c_name", @"owner", @"status", + @"title", @"startdate", @"enddate", @"location", + @"isallday", nil]; + events = [[self _fetchFields: fields + forComponentOfType: @"vevent"] objectEnumerator]; + oldEvent = [events nextObject]; + while (oldEvent) + { + newEvent = [NSMutableArray arrayWithArray: oldEvent]; + interval = [[oldEvent objectAtIndex: 4] intValue]; + date = [dateFormatter stringForSecondsSinceThe70s: interval]; + [newEvent addObject: date]; + interval = [[oldEvent objectAtIndex: 5] intValue]; + date = [dateFormatter stringForSecondsSinceThe70s: interval]; + [newEvent addObject: date]; + [newEvents addObject: newEvent]; + + oldEvent = [events nextObject]; + } + + return [self _responseWithData: newEvents]; +} + +- (NSString *) _getStatusClassForStatusCode: (int) statusCode + andEndDateStamp: (unsigned int) endDateStamp +{ + NSCalendarDate *taskDate, *now; + NSString *statusClass; + + if (statusCode == 1) + statusClass = @"completed"; + else + { + if (endDateStamp) + { + now = [NSCalendarDate calendarDate]; + taskDate + = [NSCalendarDate dateWithTimeIntervalSince1970: endDateStamp]; + if ([taskDate earlierDate: now] == taskDate) + statusClass = @"overdue"; + else + { + if ([taskDate isToday]) + statusClass = @"duetoday"; + else + statusClass = @"duelater"; + } + } + else + statusClass = @"duelater"; + } + + return statusClass; +} + +- (WOResponse *) tasksListAction +{ + NSEnumerator *tasks; + NSMutableArray *filteredTasks, *filteredTask; + BOOL showCompleted; + NSArray *fields, *task; + int statusCode; + unsigned int endDateStamp; + NSString *statusFlag; + + filteredTasks = [NSMutableArray array]; + + [self _setupContext]; + + fields = [NSArray arrayWithObjects: @"c_name", @"owner", @"status", + @"title", @"enddate", nil]; + + tasks = [[self _fetchFields: fields + forComponentOfType: @"vtodo"] objectEnumerator]; + showCompleted = [[request formValueForKey: @"show-completed"] intValue]; + + task = [tasks nextObject]; + while (task) + { + statusCode = [[task objectAtIndex: 2] intValue]; + if (statusCode != 1 || showCompleted) + { + filteredTask = [NSMutableArray arrayWithArray: task]; + endDateStamp = [[task objectAtIndex: 4] intValue]; + statusFlag = [self _getStatusClassForStatusCode: statusCode + andEndDateStamp: endDateStamp]; + [filteredTask addObject: statusFlag]; + [filteredTasks addObject: filteredTask]; + } + task = [tasks nextObject]; + } + + return [self _responseWithData: filteredTasks]; +} + +// - (BOOL) shouldDisplayCurrentTask +// { +// if (!knowsToShow) +// { +// showCompleted +// = [[self queryParameterForKey: @"show-completed"] intValue]; +// knowsToShow = YES; +// } + +// return ([[currentTask objectForKey: @"status"] intValue] != 1 +// || showCompleted); +// } + +// - (BOOL) shouldShowCompletedTasks +// { +// if (!knowsToShow) +// { +// showCompleted +// = [[self queryParameterForKey: @"show-completed"] intValue]; +// knowsToShow = YES; +// } + +// return showCompleted; +// } + +@end diff --git a/UI/Scheduler/UIxCalMonthView.h b/UI/Scheduler/UIxCalMonthView.h index 82a9f132..48190556 100644 --- a/UI/Scheduler/UIxCalMonthView.h +++ b/UI/Scheduler/UIxCalMonthView.h @@ -46,8 +46,6 @@ NSArray *currentTableColumn; } -- (id ) defaultAction; - - (NSDictionary *) monthBeforePrevMonthQueryParameters; - (NSDictionary *) prevMonthQueryParameters; - (NSDictionary *) nextMonthQueryParameters; diff --git a/UI/Scheduler/UIxCalMonthView.m b/UI/Scheduler/UIxCalMonthView.m index 53bd5a75..9f307665 100644 --- a/UI/Scheduler/UIxCalMonthView.m +++ b/UI/Scheduler/UIxCalMonthView.m @@ -64,39 +64,6 @@ [super dealloc]; } -- (void) _addEventToSortedEvents: (NSDictionary *) newEvent -{ - NSMutableArray *eventArray; - NSString *dayId; - - dayId = [[newEvent objectForKey: @"startDate"] shortDateString]; - eventArray = [sortedAppointments objectForKey: dayId]; - if (!eventArray) - { - eventArray = [NSMutableArray new]; - [eventArray autorelease]; - [sortedAppointments setObject: eventArray forKey: dayId]; - } - [eventArray addObject: newEvent]; -} - -- (id ) defaultAction -{ - NSEnumerator *events; - NSDictionary *currentEvent; - - events = [[self fetchCoreAppointmentsInfos] objectEnumerator]; - currentEvent = [events nextObject]; - while (currentEvent) - { - [self _addEventToSortedEvents: currentEvent]; - currentEvent = [events nextObject]; -// NSLog (@"event:\n'%@'", currentEvent); - } - - return self; -} - - (NSArray *) headerDaysToDisplay { NSMutableArray *headerDaysToDisplay; diff --git a/UI/Scheduler/UIxCalMulticolumnDayView.h b/UI/Scheduler/UIxCalMulticolumnDayView.h index 2b915a56..656ff423 100644 --- a/UI/Scheduler/UIxCalMulticolumnDayView.h +++ b/UI/Scheduler/UIxCalMulticolumnDayView.h @@ -31,10 +31,10 @@ NSString *currentTableHour; NSMutableArray *subscriptionUsers; NSMutableArray *hoursToDisplay; - NSArray *allAppointments; +// NSArray *allAppointments; NSString *currentTableUser; - NSDictionary *currentAppointment; +// NSDictionary *currentAppointment; NSString *cssClass; NSString *cssId; @@ -50,8 +50,8 @@ - (void) setCurrentTableUser: (NSString *) aTableDay; - (NSString *) currentTableUser; -- (void) setCurrentAppointment: (NSDictionary *) newCurrentAppointment; -- (NSDictionary *) currentAppointment; +// - (void) setCurrentAppointment: (NSDictionary *) newCurrentAppointment; +// - (NSDictionary *) currentAppointment; @end diff --git a/UI/Scheduler/UIxCalMulticolumnDayView.m b/UI/Scheduler/UIxCalMulticolumnDayView.m index 975d1c2d..cabe13f8 100644 --- a/UI/Scheduler/UIxCalMulticolumnDayView.m +++ b/UI/Scheduler/UIxCalMulticolumnDayView.m @@ -38,13 +38,13 @@ { if ((self = [super init])) { - allAppointments = nil; +// allAppointments = nil; subscriptionUsers = nil; hoursToDisplay = nil; currentTableUser = nil; currentTableHour = nil; - dateFormatter = [[SOGoDateFormatter alloc] - initWithLocale: [self locale]]; +// dateFormatter = [[SOGoDateFormatter alloc] +// initWithLocale: [self locale]]; } return self; @@ -52,13 +52,10 @@ - (void) dealloc { - if (allAppointments) - [allAppointments release]; - if (subscriptionUsers) - [subscriptionUsers release]; - if (hoursToDisplay) - [hoursToDisplay release]; - [dateFormatter release]; +// [allAppointments release]; + [subscriptionUsers release]; + [hoursToDisplay release]; +// [dateFormatter release]; [super dealloc]; } @@ -189,69 +186,69 @@ /* fetching */ -- (NSCalendarDate *) startDate -{ - return [[self selectedDate] beginOfDay]; -} - -- (NSCalendarDate *) endDate -{ - return [[self selectedDate] endOfDay]; -} - -- (NSArray *) appointmentsForCurrentUser -{ - NSMutableArray *filteredAppointments; - NSEnumerator *aptsEnumerator; - NSDictionary *userAppointment; - NSCalendarDate *start, *end; - int endHour; - - if (!allAppointments) - { - allAppointments = [self fetchCoreAppointmentsInfos]; - [allAppointments retain]; - } - - start = [[self selectedDate] hour: [self dayStartHour] minute: 0]; - endHour = [self dayEndHour]; - if (endHour < 24) - end = [[self selectedDate] hour: [self dayEndHour] minute: 59]; - else - end = [[[self selectedDate] tomorrow] hour: 0 minute: 0]; - - filteredAppointments = [NSMutableArray new]; - [filteredAppointments autorelease]; - - aptsEnumerator = [allAppointments objectEnumerator]; - userAppointment = [aptsEnumerator nextObject]; - while (userAppointment) - { - if ([[userAppointment objectForKey: @"owner"] - isEqualToString: currentTableUser]) - [filteredAppointments - addObject: [self _adjustedAppointment: userAppointment - forStart: start andEnd: end]]; - userAppointment = [aptsEnumerator nextObject]; - } - - return filteredAppointments; -} - -- (void) setCurrentAppointment: (NSDictionary *) newCurrentAppointment -{ - currentAppointment = newCurrentAppointment; -} - -- (NSDictionary *) currentAppointment -{ - return currentAppointment; -} - -- (NSString *) appointmentsClasses -{ - return @"appointments appointmentsFor1Days"; -} +// - (NSCalendarDate *) startDate +// { +// return [[self selectedDate] beginOfDay]; +// } + +// - (NSCalendarDate *) endDate +// { +// return [[self selectedDate] endOfDay]; +// } + +// - (NSArray *) appointmentsForCurrentUser +// { +// NSMutableArray *filteredAppointments; +// NSEnumerator *aptsEnumerator; +// NSDictionary *userAppointment; +// NSCalendarDate *start, *end; +// int endHour; + +// if (!allAppointments) +// { +// allAppointments = [self fetchCoreAppointmentsInfos]; +// [allAppointments retain]; +// } + +// start = [[self selectedDate] hour: [self dayStartHour] minute: 0]; +// endHour = [self dayEndHour]; +// if (endHour < 24) +// end = [[self selectedDate] hour: [self dayEndHour] minute: 59]; +// else +// end = [[[self selectedDate] tomorrow] hour: 0 minute: 0]; + +// filteredAppointments = [NSMutableArray new]; +// [filteredAppointments autorelease]; + +// aptsEnumerator = [allAppointments objectEnumerator]; +// userAppointment = [aptsEnumerator nextObject]; +// while (userAppointment) +// { +// if ([[userAppointment objectForKey: @"owner"] +// isEqualToString: currentTableUser]) +// [filteredAppointments +// addObject: [self _adjustedAppointment: userAppointment +// forStart: start andEnd: end]]; +// userAppointment = [aptsEnumerator nextObject]; +// } + +// return filteredAppointments; +// } + +// - (void) setCurrentAppointment: (NSDictionary *) newCurrentAppointment +// { +// currentAppointment = newCurrentAppointment; +// } + +// - (NSDictionary *) currentAppointment +// { +// return currentAppointment; +// } + +// - (NSString *) appointmentsClasses +// { +// return @"appointments appointmentsFor1Days"; +// } - (NSString *) currentUserClasses { diff --git a/UI/Scheduler/UIxCalTasksListView.m b/UI/Scheduler/UIxCalTasksListView.m deleted file mode 100644 index ab01e056..00000000 --- a/UI/Scheduler/UIxCalTasksListView.m +++ /dev/null @@ -1,187 +0,0 @@ -/* UIxCalTasksListView.m - this file is part of SOGo - * - * Copyright (C) 2006 Inverse groupe conseil - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import - -#import -#import -#import - -#import "UIxCalTasksListView.h" - -@implementation UIxCalTasksListView - -- (id) init -{ - if ((self = [super init])) - { - startDate = nil; - endDate = nil; - knowsToShow = NO; - showCompleted = NO; - } - - return self; -} - -- (void) _updatePrivacyInObjects: (NSArray *) objectInfos - fromFolder: (SOGoAppointmentFolder *) folder -{ - int hideDetails[] = {-1, -1, -1}; - NSMutableDictionary *currentRecord; - int privacyFlag; - NSString *roleString, *userLogin; - NSEnumerator *infos; - - userLogin = [[context activeUser] login]; - infos = [objectInfos objectEnumerator]; - currentRecord = [infos nextObject]; - while (currentRecord) - { - privacyFlag = [[currentRecord objectForKey: @"classification"] intValue]; - if (hideDetails[privacyFlag] == -1) - { - roleString = [folder roleForComponentsWithAccessClass: privacyFlag - forUser: userLogin]; - hideDetails[privacyFlag] = ([roleString isEqualToString: @"ComponentDAndTViewer"] - ? 1 : 0); - } - if (hideDetails[privacyFlag]) - { - [currentRecord setObject: [self labelForKey: @"(Private Event)"] - forKey: @"title"]; - [currentRecord setObject: @"" forKey: @"location"]; - } - currentRecord = [infos nextObject]; - } -} - -- (NSArray *) _fetchCoreInfosForComponent: (NSString *) component -{ - NSArray *currentInfos; - NSMutableArray *infos; - NSEnumerator *folders; - SOGoAppointmentFolder *currentFolder; - - infos = [componentsData objectForKey: component]; - if (!infos) - { - infos = [NSMutableArray array]; - folders = [[self _activeCalendarFolders] objectEnumerator]; - currentFolder = [folders nextObject]; - while (currentFolder) - { - currentInfos = [currentFolder fetchCoreInfosFrom: [[self startDate] beginOfDay] - to: [[self endDate] endOfDay] - component: component]; - [currentInfos makeObjectsPerform: @selector (setObject:forKey:) - withObject: [currentFolder ownerInContext: nil] - withObject: @"owner"]; - [self _updatePrivacyInObjects: currentInfos - fromFolder: currentFolder]; - [infos addObjectsFromArray: currentInfos]; - currentFolder = [folders nextObject]; - } - [componentsData setObject: infos forKey: component]; - } - - return infos; -} - -- (NSArray *) fetchCoreAppointmentsInfos -{ - if (!appointments) - [self setAppointments: [self _fetchCoreInfosForComponent: @"vevent"]]; - - return appointments; -} - -- (WOResponse *) tasksListAction -{ - WOResponse *response; - NSDictionary *tasks; - NSMutableArray *filteredTasks; - BOOL showCompleted; - unsigned i, count; - - response = [context response]; - filteredTasks = [NSMutableArray new]; - [filteredTasks autorelease]; - tasks = [self _fetchCoreInfosForComponent: @"vtodo"]; - showCompleted = [[self queryParameterForKey: @"show-completed"] intValue]; - - count = [tasks count]; - for (i = 0; i < count; i++) { - NSDictionary *task; - NSArray *filteredTask; - - task = [tasks objectAtIndex: i]; - - if ([[task objectForKey: @"status"] intValue] != 1 - || showCompleted) - { - filteredTask = [NSArray arrayWithObjects: - [task objectForKey: @"c_name"], - [task objectForKey: @"owner"], - [task objectForKey: @"status"], - [task objectForKey: @"title"], - [self getStatusClassForTask: task], - nil]; - [filteredTasks addObject: filteredTask]; - } - } - - [response setStatus: 200]; - [response appendContentString: [filteredTasks jsonRepresentation]]; - - return response; -} - -- (BOOL) shouldDisplayCurrentTask -{ - if (!knowsToShow) - { - showCompleted - = [[self queryParameterForKey: @"show-completed"] intValue]; - knowsToShow = YES; - } - - return ([[currentTask objectForKey: @"status"] intValue] != 1 - || showCompleted); -} - -- (BOOL) shouldShowCompletedTasks -{ - if (!knowsToShow) - { - showCompleted - = [[self queryParameterForKey: @"show-completed"] intValue]; - knowsToShow = YES; - } - - return showCompleted; -} - -@end diff --git a/UI/Scheduler/UIxCalView.h b/UI/Scheduler/UIxCalView.h index 253e30f2..46236dc2 100644 --- a/UI/Scheduler/UIxCalView.h +++ b/UI/Scheduler/UIxCalView.h @@ -98,8 +98,6 @@ - (NSCalendarDate *) startDate; - (NSCalendarDate *) endDate; -- (NSArray *) fetchCoreAppointmentsInfos; -- (NSArray *) fetchCoreTasksInfos; /* date selection */ diff --git a/UI/Scheduler/UIxCalView.m b/UI/Scheduler/UIxCalView.m index 96ecf6f8..7db34e80 100644 --- a/UI/Scheduler/UIxCalView.m +++ b/UI/Scheduler/UIxCalView.m @@ -451,135 +451,6 @@ static BOOL shouldDisplayWeekend = NO; return [[self startDate] tomorrow]; } -- (SOGoAppointmentFolder *) _aptFolder: (NSString *) folder - withClientObject: (SOGoAppointmentFolder *) clientObject -{ - SOGoAppointmentFolder *aptFolder; - NSArray *folderParts; - - if ([folder isEqualToString: @"/"]) - aptFolder = clientObject; - else - { - folderParts = [folder componentsSeparatedByString: @":"]; - aptFolder - = [clientObject lookupCalendarFolderForUID: - [folderParts objectAtIndex: 0]]; - } - - return aptFolder; -} - -- (NSArray *) _activeCalendarFolders -{ - NSMutableArray *activeFolders; - NSEnumerator *folders; - NSDictionary *currentFolderDict; - SOGoAppointmentFolder *currentFolder, *clientObject; - - activeFolders = [NSMutableArray new]; - [activeFolders autorelease]; - - clientObject = [self clientObject]; - - folders = [[clientObject calendarFolders] objectEnumerator]; - currentFolderDict = [folders nextObject]; - while (currentFolderDict) - { - if ([[currentFolderDict objectForKey: @"active"] boolValue]) - { - currentFolder - = [self _aptFolder: [currentFolderDict objectForKey: @"folder"] - withClientObject: clientObject]; - [activeFolders addObject: currentFolder]; - } - - currentFolderDict = [folders nextObject]; - } - - return activeFolders; -} - -- (void) _updatePrivacyInObjects: (NSArray *) objectInfos - fromFolder: (SOGoAppointmentFolder *) folder -{ - int hideDetails[] = {-1, -1, -1}; - NSMutableDictionary *currentRecord; - int privacyFlag; - NSString *roleString, *userLogin; - NSEnumerator *infos; - - userLogin = [[context activeUser] login]; - infos = [objectInfos objectEnumerator]; - currentRecord = [infos nextObject]; - while (currentRecord) - { - privacyFlag = [[currentRecord objectForKey: @"classification"] intValue]; - if (hideDetails[privacyFlag] == -1) - { - roleString = [folder roleForComponentsWithAccessClass: privacyFlag - forUser: userLogin]; - hideDetails[privacyFlag] = ([roleString isEqualToString: @"ComponentDAndTViewer"] - ? 1 : 0); - } - if (hideDetails[privacyFlag]) - { - [currentRecord setObject: [self labelForKey: @"(Private Event)"] - forKey: @"title"]; - [currentRecord setObject: @"" forKey: @"location"]; - } - currentRecord = [infos nextObject]; - } -} - -- (NSArray *) _fetchCoreInfosForComponent: (NSString *) component -{ - NSArray *currentInfos; - NSMutableArray *infos; - NSEnumerator *folders; - SOGoAppointmentFolder *currentFolder; - - infos = [componentsData objectForKey: component]; - if (!infos) - { - infos = [NSMutableArray array]; - folders = [[self _activeCalendarFolders] objectEnumerator]; - currentFolder = [folders nextObject]; - while (currentFolder) - { - currentInfos = [currentFolder fetchCoreInfosFrom: [[self startDate] beginOfDay] - to: [[self endDate] endOfDay] - component: component]; - [currentInfos makeObjectsPerform: @selector (setObject:forKey:) - withObject: [currentFolder ownerInContext: nil] - withObject: @"owner"]; - [self _updatePrivacyInObjects: currentInfos - fromFolder: currentFolder]; - [infos addObjectsFromArray: currentInfos]; - currentFolder = [folders nextObject]; - } - [componentsData setObject: infos forKey: component]; - } - - return infos; -} - -- (NSArray *) fetchCoreAppointmentsInfos -{ - if (!appointments) - [self setAppointments: [self _fetchCoreInfosForComponent: @"vevent"]]; - - return appointments; -} - -- (NSArray *) fetchCoreTasksInfos -{ - if (!tasks) - [self setTasks: [self _fetchCoreInfosForComponent: @"vtodo"]]; - - return tasks; -} - /* query parameters */ - (BOOL) shouldDisplayRejectedAppointments diff --git a/UI/Scheduler/product.plist b/UI/Scheduler/product.plist index 1a4a61d3..63d85f5e 100644 --- a/UI/Scheduler/product.plist +++ b/UI/Scheduler/product.plist @@ -1,224 +1,226 @@ -{ +{ /* -*-javascript-*- */ requires = ( MAIN, MainUI, CommonUI, Appointments, Contacts, ContactsUI ); publicResources = ( - previous_week.gif, - next_week.gif, - icon_view_overview.gif, - icon_view_overview_inactive.gif, - icon_view_chart.gif, - icon_view_chart_inactive.gif, - icon_view_list.gif, - icon_view_list_inactive.gif, - icon_view_columns.gif, - icon_view_columns_inactive.gif, - icon_popupcalendar.gif, - first.gif, - previous.gif, - next.gif, - last.gif, - skycalendar.html, - skycalendar.js, - green_corner.gif, - invisible_space_2.gif, - cycles.plist, + previous_week.gif, + next_week.gif, + icon_view_overview.gif, + icon_view_overview_inactive.gif, + icon_view_chart.gif, + icon_view_chart_inactive.gif, + icon_view_list.gif, + icon_view_list_inactive.gif, + icon_view_columns.gif, + icon_view_columns_inactive.gif, + icon_popupcalendar.gif, + first.gif, + previous.gif, + next.gif, + last.gif, + skycalendar.html, + skycalendar.js, + green_corner.gif, + invisible_space_2.gif, + cycles.plist, ); factories = { }; categories = { - SOGoAppointmentFolder = { - slots = { - toolbar = { - protectedBy = "View"; - value = "SOGoAppointmentFolder.toolbar"; - }; - }; - methods = { - view = { - protectedBy = "View"; - pageName = "UIxCalMainView"; - }; - dateselector = { - protectedBy = "View"; - pageName = "UIxCalDateSelector"; - }; - aptlist = { - protectedBy = "View"; - pageName = "UIxCalAptListView"; - }; - taskslist = { - protectedBy = "View"; - pageName = "UIxCalTasksListView"; - }; - dayview = { - protectedBy = "View"; - pageName = "UIxCalDayView"; - }; - multicolumndayview = { - protectedBy = "View"; - pageName = "UIxCalMulticolumnDayView"; - }; - weekview = { - protectedBy = "View"; - pageName = "UIxCalWeekView"; - }; - monthview = { - protectedBy = "View"; - pageName = "UIxCalMonthView"; - }; - newevent = { - protectedBy = "Add Documents, Images, and Files"; - pageName = "UIxAppointmentEditor"; - actionName = "new"; - }; - newtask = { - protectedBy = "Add Documents, Images, and Files"; - pageName = "UIxTaskEditor"; - actionName = "new"; - }; - show = { - protectedBy = "View"; - pageName = "UIxCalView"; - actionName = "redirectForUIDs"; - }; - proposal = { - protectedBy = "View"; - pageName = "UIxAppointmentProposal"; - }; - proposalSearch = { - protectedBy = "View"; - pageName = "UIxAppointmentProposal"; - actionName = "proposalSearch"; - }; - batchDelete = { - protectedBy = "Delete Objects"; - pageName = "UIxCalMainView"; - actionName = "batchDelete"; - }; - updateCalendars = { - protectedBy = "View"; - pageName = "UIxCalMainView"; - actionName = "updateCalendars"; - }; - editAttendees = { - protectedBy = "View"; - pageName = "UIxAttendeesEditor"; + SOGoAppointmentFolder = { + slots = { + toolbar = { + protectedBy = "View"; + value = "SOGoAppointmentFolder.toolbar"; + }; }; - userRights = { - protectedBy = "ReadAcls"; - pageName = "UIxCalUserRightsEditor"; - }; - saveUserRights = { - protectedBy = "SaveAcls"; - pageName = "UIxCalUserRightsEditor"; - actionName = "saveUserRights"; + methods = { + view = { + protectedBy = "View"; + pageName = "UIxCalMainView"; + }; + dateselector = { + protectedBy = "View"; + pageName = "UIxCalDateSelector"; + }; + eventslist = { + protectedBy = "View"; + actionClass = "UIxCalListingActions"; + actionName = "eventsList"; + }; + taskslist = { + protectedBy = "View"; + actionClass = "UIxCalListingActions"; + actionName = "tasksList"; + }; + dayview = { + protectedBy = "View"; + pageName = "UIxCalDayView"; + }; + multicolumndayview = { + protectedBy = "View"; + pageName = "UIxCalMulticolumnDayView"; + }; + weekview = { + protectedBy = "View"; + pageName = "UIxCalWeekView"; + }; + monthview = { + protectedBy = "View"; + pageName = "UIxCalMonthView"; + }; + newevent = { + protectedBy = "Add Documents, Images, and Files"; + pageName = "UIxAppointmentEditor"; + actionName = "new"; + }; + newtask = { + protectedBy = "Add Documents, Images, and Files"; + pageName = "UIxTaskEditor"; + actionName = "new"; + }; + show = { + protectedBy = "View"; + pageName = "UIxCalView"; + actionName = "redirectForUIDs"; + }; + proposal = { + protectedBy = "View"; + pageName = "UIxAppointmentProposal"; + }; + proposalSearch = { + protectedBy = "View"; + pageName = "UIxAppointmentProposal"; + actionName = "proposalSearch"; + }; + batchDelete = { + protectedBy = "Delete Objects"; + pageName = "UIxCalMainView"; + actionName = "batchDelete"; + }; + updateCalendars = { + protectedBy = "View"; + pageName = "UIxCalMainView"; + actionName = "updateCalendars"; + }; + editAttendees = { + protectedBy = "View"; + pageName = "UIxAttendeesEditor"; + }; + userRights = { + protectedBy = "ReadAcls"; + pageName = "UIxCalUserRightsEditor"; + }; + saveUserRights = { + protectedBy = "SaveAcls"; + pageName = "UIxCalUserRightsEditor"; + actionName = "saveUserRights"; + }; }; - }; - }; - SOGoCalendarComponent = { - }; + }; + SOGoCalendarComponent = { + }; - SOGoAppointmentObject = { - slots = { - toolbar = { - protectedBy = "View"; - value = "SOGoAppointmentObject.toolbar"; - }; - }; - methods = { - view = { - protectedBy = "ViewAllComponent"; - pageName = "UIxAppointmentView"; - }; - delete = { - protectedBy = "Delete Objects"; - pageName = "UIxAppointmentView"; - actionName = "delete"; - }; - edit = { - protectedBy = "ViewAllComponent"; - pageName = "UIxAppointmentEditor"; - }; - editAsAppointment = { - protectedBy = "ViewAllComponent"; - pageName = "UIxAppointmentEditor"; - }; - save = { - protectedBy = "ModifyComponent"; - pageName = "UIxAppointmentEditor"; - actionName = "save"; - }; - saveAsAppointment = { - protectedBy = "ModifyComponent"; - pageName = "UIxAppointmentEditor"; - actionName = "save"; - }; - accept = { - protectedBy = "RespondToComponent"; - pageName = "UIxAppointmentEditor"; - actionName = "accept"; - }; - decline = { - protectedBy = "RespondToComponent"; - pageName = "UIxAppointmentEditor"; - actionName = "decline"; - }; - }; - }; + SOGoAppointmentObject = { + slots = { + toolbar = { + protectedBy = "View"; + value = "SOGoAppointmentObject.toolbar"; + }; + }; + methods = { + view = { + protectedBy = "ViewAllComponent"; + pageName = "UIxAppointmentView"; + }; + delete = { + protectedBy = "Delete Objects"; + pageName = "UIxAppointmentView"; + actionName = "delete"; + }; + edit = { + protectedBy = "ViewAllComponent"; + pageName = "UIxAppointmentEditor"; + }; + editAsAppointment = { + protectedBy = "ViewAllComponent"; + pageName = "UIxAppointmentEditor"; + }; + save = { + protectedBy = "ModifyComponent"; + pageName = "UIxAppointmentEditor"; + actionName = "save"; + }; + saveAsAppointment = { + protectedBy = "ModifyComponent"; + pageName = "UIxAppointmentEditor"; + actionName = "save"; + }; + accept = { + protectedBy = "RespondToComponent"; + pageName = "UIxAppointmentEditor"; + actionName = "accept"; + }; + decline = { + protectedBy = "RespondToComponent"; + pageName = "UIxAppointmentEditor"; + actionName = "decline"; + }; + }; + }; - SOGoTaskObject = { - slots = { - toolbar = { - protectedBy = "View"; - value = "SOGoAppointmentObject.toolbar"; - }; - }; - methods = { - view = { - protectedBy = "ViewAllComponent"; - pageName = "UIxTaskView"; - }; - delete = { - protectedBy = "Delete Objects"; - pageName = "UIxTaskView"; - actionName = "delete"; - }; - edit = { - protectedBy = "ViewAllComponent"; - pageName = "UIxTaskEditor"; - }; - editAsTask = { - protectedBy = "ViewAllComponent"; - pageName = "UIxTaskEditor"; - }; - save = { - protectedBy = "ModifyComponent"; - pageName = "UIxTaskEditor"; - actionName = "save"; - }; - saveAsTask = { - protectedBy = "ModifyComponent"; - pageName = "UIxTaskEditor"; - actionName = "save"; - }; - changeStatus = { - protectedBy = "ModifyComponent"; - pageName = "UIxTaskEditor"; - actionName = "changeStatus"; - }; - accept = { - protectedBy = "RespondToComponent"; - pageName = "UIxTaskEditor"; - actionName = "accept"; - }; - decline = { - protectedBy = "RespondToComponent"; - pageName = "UIxTaskEditor"; - actionName = "decline"; - }; - }; - }; + SOGoTaskObject = { + slots = { + toolbar = { + protectedBy = "View"; + value = "SOGoAppointmentObject.toolbar"; + }; + }; + methods = { + view = { + protectedBy = "ViewAllComponent"; + pageName = "UIxTaskView"; + }; + delete = { + protectedBy = "Delete Objects"; + pageName = "UIxTaskView"; + actionName = "delete"; + }; + edit = { + protectedBy = "ViewAllComponent"; + pageName = "UIxTaskEditor"; + }; + editAsTask = { + protectedBy = "ViewAllComponent"; + pageName = "UIxTaskEditor"; + }; + save = { + protectedBy = "ModifyComponent"; + pageName = "UIxTaskEditor"; + actionName = "save"; + }; + saveAsTask = { + protectedBy = "ModifyComponent"; + pageName = "UIxTaskEditor"; + actionName = "save"; + }; + changeStatus = { + protectedBy = "ModifyComponent"; + pageName = "UIxTaskEditor"; + actionName = "changeStatus"; + }; + accept = { + protectedBy = "RespondToComponent"; + pageName = "UIxTaskEditor"; + actionName = "accept"; + }; + decline = { + protectedBy = "RespondToComponent"; + pageName = "UIxTaskEditor"; + actionName = "decline"; + }; + }; + }; }; } diff --git a/UI/Templates/MailerUI/UIxMailFilterPanel.wox b/UI/Templates/MailerUI/UIxMailFilterPanel.wox index 349b5c0b..71e4be51 100644 --- a/UI/Templates/MailerUI/UIxMailFilterPanel.wox +++ b/UI/Templates/MailerUI/UIxMailFilterPanel.wox @@ -42,8 +42,7 @@ + const:name="filterpopup" /> diff --git a/UI/Templates/MailerUI/UIxMailListView.wox b/UI/Templates/MailerUI/UIxMailListView.wox index cabb3a4d..55c320c8 100644 --- a/UI/Templates/MailerUI/UIxMailListView.wox +++ b/UI/Templates/MailerUI/UIxMailListView.wox @@ -20,7 +20,7 @@ const:href="view" var:queryDictionary="context.request.formValues" />; -
- + check addresses -->
- + diff --git a/UI/Templates/SchedulerUI/UIxAppointmentEditor.wox b/UI/Templates/SchedulerUI/UIxAppointmentEditor.wox index d918e7bd..533f88b0 100644 --- a/UI/Templates/SchedulerUI/UIxAppointmentEditor.wox +++ b/UI/Templates/SchedulerUI/UIxAppointmentEditor.wox @@ -10,14 +10,9 @@ className="UIxComponentEditor" var:component="event" var:saveURL="saveURL"> - diff --git a/UI/Templates/SchedulerUI/UIxCalAptListView.wox b/UI/Templates/SchedulerUI/UIxCalAptListView.wox deleted file mode 100644 index 1a73d0d5..00000000 --- a/UI/Templates/SchedulerUI/UIxCalAptListView.wox +++ /dev/null @@ -1,61 +0,0 @@ - - - - - -
diff --git a/UI/Templates/SchedulerUI/UIxCalDayTable.wox b/UI/Templates/SchedulerUI/UIxCalDayTable.wox index 15662a4c..9a08afe8 100644 --- a/UI/Templates/SchedulerUI/UIxCalDayTable.wox +++ b/UI/Templates/SchedulerUI/UIxCalDayTable.wox @@ -1,73 +1,91 @@ - -
-
-
:00
-
+ + +
+

+
+
+
+ +
+
+
:00
+
-
-
-
+
+
+
+
+
+ +
+
+
+
-
-
-
-
-
- -
-
-
-
+
+
- +
+
diff --git a/UI/Templates/SchedulerUI/UIxCalDayView.wox b/UI/Templates/SchedulerUI/UIxCalDayView.wox index 821d803b..deca9e61 100644 --- a/UI/Templates/SchedulerUI/UIxCalDayView.wox +++ b/UI/Templates/SchedulerUI/UIxCalDayView.wox @@ -1,49 +1,49 @@ - - - - - - -
- -
-
+ + + + + + +
+ +
+
diff --git a/UI/Templates/SchedulerUI/UIxCalInlineAptView.wox b/UI/Templates/SchedulerUI/UIxCalInlineAptView.wox deleted file mode 100644 index 7d769af3..00000000 --- a/UI/Templates/SchedulerUI/UIxCalInlineAptView.wox +++ /dev/null @@ -1,32 +0,0 @@ - - -
-

-
-
-
diff --git a/UI/Templates/SchedulerUI/UIxCalInlineMonthAptView.wox b/UI/Templates/SchedulerUI/UIxCalInlineMonthAptView.wox deleted file mode 100644 index de2393c8..00000000 --- a/UI/Templates/SchedulerUI/UIxCalInlineMonthAptView.wox +++ /dev/null @@ -1,25 +0,0 @@ - - -
-
-
-
-
diff --git a/UI/Templates/SchedulerUI/UIxCalMainView.wox b/UI/Templates/SchedulerUI/UIxCalMainView.wox index 6c075ace..34c751a4 100644 --- a/UI/Templates/SchedulerUI/UIxCalMainView.wox +++ b/UI/Templates/SchedulerUI/UIxCalMainView.wox @@ -28,7 +28,7 @@ >
- -
+
+ +
+
-
+
+ + + + + + + +
+
diff --git a/UI/Templates/SchedulerUI/UIxCalMonthView.wox b/UI/Templates/SchedulerUI/UIxCalMonthView.wox index cb098db5..bbed4037 100644 --- a/UI/Templates/SchedulerUI/UIxCalMonthView.wox +++ b/UI/Templates/SchedulerUI/UIxCalMonthView.wox @@ -46,25 +46,25 @@ >
-
- - +
@@ -92,7 +92,7 @@ -
- -

- -
    -
  • -
    -
-
diff --git a/UI/WebServerResources/ContactsUI.css b/UI/WebServerResources/ContactsUI.css index e11714e9..e96cc3b4 100644 --- a/UI/WebServerResources/ContactsUI.css +++ b/UI/WebServerResources/ContactsUI.css @@ -97,7 +97,7 @@ table.titletable td.titlecell SELECT border-bottom: 2px solid #222; -moz-border-bottom-colors: #000 #9c9a94 transparent; -moz-border-right-colors: #000 #9c9a94 transparent; - background: #DCDAD5; + background-color: #DCDAD5; } .whitesec_title @@ -117,17 +117,15 @@ DIV#contactFoldersList padding: 0px; overflow: hidden; } -DIV#contactFoldersList > DIV.toolbar +DIV#contactFoldersList DIV.toolbar { width: 100%; - background: #f00; padding: 0px; margin: 0px; border-top: 1px solid #aaa; border-left: 1px solid #aaa; } UL#contactFolders -{ visibility: hidden; - list-style-type: none; +{ list-style-type: none; list-style-image: none; clear: both; cursor: default; @@ -175,7 +173,6 @@ TABLE#contactsList color: #000; background: #fff; width: 100%; - height: 100%; } TABLE#contactsList TD @@ -319,7 +316,9 @@ DIV.contactSelection > DIV.calendar { text-align: center; } DIV.contactSelection INPUT.button -{ margin-top: .25em; } +{ font-size: 8pt; + margin-top: .25em; + padding: 0px; } DIV.contactSelection SPAN#selectionLabel { float: left; } diff --git a/UI/WebServerResources/ContactsUI.js b/UI/WebServerResources/ContactsUI.js index 0bfa6a7d..0e3b0357 100644 --- a/UI/WebServerResources/ContactsUI.js +++ b/UI/WebServerResources/ContactsUI.js @@ -85,7 +85,7 @@ function contactsListCallback(http) { configureSortableTableHeaders(); } else - log ("ajax fuckage 1"); + log ("ajax problem 1"); } function onContactFoldersContextMenu(event) { @@ -186,7 +186,7 @@ function contactLoadCallback(http) { div.innerHTML = content; } else - log ("ajax fuckage 2: " + http.status); + log ("ajax problem 2: " + http.status); } var rowSelectionCount = 0; @@ -336,11 +336,13 @@ function onHeaderClick(event) { document.contactsListAjaxRequest.aborted = true; document.contactsListAjaxRequest.abort(); } - url = URLForFolderID(currentContactFolder) + "/" + this.link; - if (!this.link.match(/noframe=/)) - url += "&noframe=1"; + url = URLForFolderID(currentContactFolder); +// // log("url: " + url); +// var url = "" + this.href; + if (url.indexOf("noframe=", 0) == -1) + url += "&noframe=1"; document.contactsListAjaxRequest - = triggerAjaxRequest(url, contactsListCallback); + = triggerAjaxRequest(url, contactsListCallback); event.preventDefault(); } @@ -433,15 +435,15 @@ function onAddressBookNew(event) { document.newAbAjaxRequest = triggerAjaxRequest(url, newAbCallback, name); } - event.preventDefault(); + preventDefault(event); } function appendAddressBook(name, folder) { var li = document.createElement("li"); + $("contactFolders").appendChild(li); li.setAttribute("id", folder); li.appendChild(document.createTextNode(name)); setEventsOnContactFolder(li); - $("contactFolders").appendChild(li); } function newAbCallback(http) { @@ -451,7 +453,7 @@ function newAbCallback(http) { appendAddressBook(name, "/" + name); } else - log ("ajax fuckage 4:" + http.status); + log ("ajax problem 4:" + http.status); } function newUserFolderCallback(folderData) { @@ -531,7 +533,7 @@ function deletePersonalAddressBookCallback(http) { document.deletePersonalABAjaxRequest = null; } else - log ("ajax fuckage"); + log ("ajax problem"); } function configureDragHandles() { @@ -555,13 +557,14 @@ function lookupDeniedFolders() { for (var i = 0; i < list.length; i++) { var folderID = list[i].getAttribute("id"); var url = URLForFolderID(folderID) + "/canAccessContent"; + triggerAjaxRequest(url, deniedFoldersLookupCallback, folderID); } } function deniedFoldersLookupCallback(http) { - if (http.readyState == 4) { - var denied = (http.status != 204) + if (http.readyState == 4) { + var denied = ! isHttpStatus204(http.status); var entry = $(http.callbackData); if (denied) entry.addClassName("denied"); @@ -581,14 +584,14 @@ function configureAbToolbar() { function configureContactFolders() { var contactFolders = $("contactFolders"); if (contactFolders) { - Event.observe(contactFolders, "selectionchange", onFolderSelectionChange, false); + Event.observe(contactFolders, "mousedown", listRowMouseDownHandler); + Event.observe(contactFolders, "click", onFolderSelectionChange); var lis = contactFolders.childNodesWithTag("li"); for (var i = 0; i < lis.length; i++) setEventsOnContactFolder(lis[i]); lookupDeniedFolders(); - contactFolders.setStyle({ visibility: 'visible' }); - + var personalFolder = $("/personal"); personalFolder.select(); } @@ -597,7 +600,7 @@ function configureContactFolders() { function setEventsOnContactFolder(node) { Event.observe(node, "mousedown", listRowMouseDownHandler, false); Event.observe(node, "click", onRowClick, false); - Event.observe(node, "contextmenu", onContactFoldersContextMenu, false); + Event.observe(node, "contextmenu", onContactFoldersContextMenu.bindAsEventListener(node), false); } function onMenuSharing(event) { @@ -641,18 +644,15 @@ function configureSelectionButtons() { } } -var initContacts = { - handleEvent: function (event) { - if (!document.body.hasClassName("popup")) { - configureAbToolbar(); - configureSearchField(); - } - else - configureSelectionButtons(); - configureContactFolders(); +function initContacts(event) { + if (!document.body.hasClassName("popup")) { + configureAbToolbar(); + configureSearchField(); + } + else + configureSelectionButtons(); + configureContactFolders(); // initDnd(); - } } -//window.addEventListener("load", initContacts, false); -Event.observe(window, "load", initContacts, false); +addEvent(window, 'load', initContacts); diff --git a/UI/WebServerResources/HTMLElement.js b/UI/WebServerResources/HTMLElement.js index 46f4c54e..761bbc7f 100644 --- a/UI/WebServerResources/HTMLElement.js +++ b/UI/WebServerResources/HTMLElement.js @@ -23,21 +23,6 @@ Element.addMethods({ return matchingNodes; }, - removeClassName: function(element, className) { - element = $(element); - var classStr = '' + element.readAttribute('class'); - - position = classStr.indexOf(className, 0); - while (position > -1) { - classStr1 = classStr.substring(0, position); - classStr2 = classStr.substring(position + 10, classStr.length); - classStr = classStr1 + classStr2; - position = classStr.indexOf(className, 0); - } - - element.setAttribute('class', classStr); - }, - getParentWithTagName: function(element, tagName) { element = $(element); var currentElement = element; @@ -126,8 +111,8 @@ Element.addMethods({ for (var i = 0; i < element.childNodes.length; i++) { node = element.childNodes.item(i); if (node.nodeType == 1 - && isNodeSelected(node)) - selArray.push(node.getAttribute("id")); + && isNodeSelected(node)) { + selArray.push(node.getAttribute("id")); } } return selArray; @@ -181,7 +166,7 @@ Element.addMethods({ for (var i = 0; i < element.childNodes.length; i++) { var node = element.childNodes.item(i); if (node.nodeType == 1) - node.deselect(); + $(node).deselect(); } } diff --git a/UI/WebServerResources/HTMLTableElement.js b/UI/WebServerResources/HTMLTableElement.js index 98a81bb1..7979e41f 100644 --- a/UI/WebServerResources/HTMLTableElement.js +++ b/UI/WebServerResources/HTMLTableElement.js @@ -4,7 +4,7 @@ Element.addMethods({ if (element.tagName == 'TABLE') { var tbody = (element.getElementsByTagName('tbody'))[0]; - return tbody.getSelectedNodes(); + return $(tbody).getSelectedNodes(); } else if (element.tagName == 'UL') { return element.getSelectedNodes(); @@ -16,7 +16,7 @@ Element.addMethods({ if (element.tagName == 'TABLE') { var tbody = (element.getElementsByTagName('tbody'))[0]; - return tbody.getSelectedNodesId(); + return $(tbody).getSelectedNodesId(); } else if (element.tagName == 'UL') { return element.getSelectedNodesId(); @@ -30,8 +30,7 @@ Element.addMethods({ var nodes = tbody.childNodes; for (var i = 0; i < nodes.length; i++) { var node = nodes.item(i); - if (node instanceof HTMLElement - && node.hasClassName(className)) + if (node.tagName && node.hasClassName(className)) node.select(); } } diff --git a/UI/WebServerResources/JavascriptAPIExtensions.js b/UI/WebServerResources/JavascriptAPIExtensions.js index 088a7f10..f1756edc 100644 --- a/UI/WebServerResources/JavascriptAPIExtensions.js +++ b/UI/WebServerResources/JavascriptAPIExtensions.js @@ -33,7 +33,15 @@ String.prototype.asDate = function () { newDate = new Date(date[2], date[1] - 1, date[0]); else { date = this.split("-"); - newDate = new Date(date[0], date[1] - 1, date[2]); + if (date.length == 3) + newDate = new Date(date[0], date[1] - 1, date[2]); + else { + if (this.length == 8) { + newDate = new Date(this.substring(0, 4), + this.substring(4, 6) - 1, + this.substring(6, 8)); + } + } } return newDate; @@ -64,6 +72,7 @@ Date.prototype.sogoDayName = function() { Date.prototype.daysUpTo = function(otherDate) { var days = new Array(); + var day1 = this.getTime(); var day2 = otherDate.getTime(); @@ -77,6 +86,41 @@ Date.prototype.daysUpTo = function(otherDate) { return days; } +Date.prototype.getDayString = function() { + var newString = this.getYear() + 1900; + var month = '' + (this.getMonth() + 1); + if (month.length == 1) + month = '0' + month; + newString += month; + var day = '' + this.getDate(); + if (day.length == 1) + day = '0' + day; + newString += day; + + return newString; +} + +Date.prototype.getHourString = function() { + var newString = this.getHours() + '00'; + if (newString.length == 3) + newString = '0' + newString; + + return newString; +} + +Date.prototype.getDisplayHoursString = function() { + var hoursString = this.getHours(); + if (hoursString.length == 1) + hoursString = '0' + hoursString; + + var minutesString = this.getMinutes(); + if (minutesString.length == 1) + minutesString = '0' + minutesString; + + + return hoursString + ":" + minutesString; +} + Date.prototype.stringWithSeparator = function(separator) { var month = '' + (this.getMonth() + 1); var day = '' + this.getDate(); @@ -96,3 +140,73 @@ Date.prototype.stringWithSeparator = function(separator) { Date.prototype.sogoFreeBusyStringWithSeparator = function(separator) { return this.sogoDayName() + ", " + this.stringWithSeparator(separator); } + +Date.prototype.addDays = function(nbrDays) { + var milliSeconds = this.getTime(); + milliSeconds += 86400000 * nbrDays; + this.setTime(milliSeconds); +} + +Date.prototype.earlierDate = function(otherDate) { + var workDate = new Date(); + workDate.setTime(otherDate.getTime()); + workDate.setHours(0); + return ((this.getTime() < workDate.getTime()) + ? this : otherDate); +} + +Date.prototype.laterDate = function(otherDate) { + var workDate = new Date(); + workDate.setTime(otherDate.getTime()); + workDate.setHours(23); + workDate.setMinutes(59); + workDate.setSeconds(59); + workDate.setMilliseconds(999); + return ((this.getTime() < workDate.getTime()) + ? otherDate : this); +} + +Date.prototype.beginOfWeek = function() { + var beginNumber; + var dayNumber = this.getDay(); + if (weekStartIsMonday) { + beginNumber = 1; + if (dayNumber == 0) + dayNumber = 7; + } + else + beginNumber = 0; + + var beginOfWeek = new Date(); + beginOfWeek.setTime(this.getTime()); + beginOfWeek.addDays(beginNumber - dayNumber); + beginOfWeek.setHours(0); + beginOfWeek.setMinutes(0); + beginOfWeek.setSeconds(0); + beginOfWeek.setMilliseconds(0); + + return beginOfWeek; +} + +Date.prototype.endOfWeek = function() { + var beginNumber; + var dayNumber = this.getDay(); + if (weekStartIsMonday) { + beginNumber = 1; + if (dayNumber == 0) + dayNumber = 7; + } + else + beginNumber = 0; + + var endOfWeek = new Date(); + endOfWeek.setTime(this.getTime()); + endOfWeek.addDays(6 + beginNumber - dayNumber); + + endOfWeek.setHours(23); + endOfWeek.setMinutes(59); + endOfWeek.setSeconds(59); + endOfWeek.setMilliseconds(999); + + return endOfWeek; +} diff --git a/UI/WebServerResources/MailerUI.css b/UI/WebServerResources/MailerUI.css index 05530852..014e08dd 100644 --- a/UI/WebServerResources/MailerUI.css +++ b/UI/WebServerResources/MailerUI.css @@ -46,11 +46,12 @@ DIV#rightPanel } DIV#mailboxContent -{ position: absolute; +{ background-color: #fff; + position: absolute; width: 100%; height: 18em; left: 0px; - top: .5em; + top: 2.5em; right: 0px; } DIV#messageContent @@ -334,15 +335,15 @@ DIV#messageContent div.mailer_mailcontent td.mailer_fieldname { white-space: nowrap; - padding-left: 1em; + padding: 0 1em; text-align: right; font-weight: bold; vertical-align: top; + width: 6em; } td.mailer_fieldvalue { - width: 95%; } td.mailer_subjectfieldvalue @@ -471,12 +472,12 @@ TABLE#addr_table TABLE#messageList { display: block; position: absolute; - background: #fff; - color: #000; + background-color: #fff; + color: #000; width: 100%; left: 0px; right: 0px; - top: 2em; + top: 0px; bottom: 0px; overflow: auto; overflow-x: hidden; @@ -498,7 +499,13 @@ TABLE#messageList TD } TABLE#messageList TD.tbtv_subject_headercell -{ width: 30%; } +{ width: 40%; } + +TABLE#messageList TD.tbtv_from_headercell +{ width: 35%; } + +TABLE#messageList TD.tbtv_date_headercell +{ width: 25%; } TABLE#messageList TR._selected TD { diff --git a/UI/WebServerResources/MailerUI.js b/UI/WebServerResources/MailerUI.js index 6dcb3981..8dc1cb30 100644 --- a/UI/WebServerResources/MailerUI.js +++ b/UI/WebServerResources/MailerUI.js @@ -76,7 +76,7 @@ function clickedEditorSend(sender) { if (!validateEditorInput(sender)) return false; - document.pageform.action="send"; + document.pageform.action = "send"; document.pageform.submit(); // if everything is ok, close the window return true; @@ -93,14 +93,14 @@ function clickedEditorAttach(sender) { } function clickedEditorSave(sender) { - document.pageform.action="save"; + document.pageform.action = "save"; document.pageform.submit(); refreshOpener(); return true; } function clickedEditorDelete(sender) { - document.pageform.action="delete"; + document.pageform.action = "delete"; document.pageform.submit(); refreshOpener(); window.close(); @@ -122,7 +122,7 @@ function openAddressbook(sender) { function onMenuSharing(event) { var folderID = document.menuTarget.getAttribute("dataname"); var urlstr = URLForFolderID(folderID) + "/acls"; - event.preventDefault(); + preventDefault(event); openAclWindow(urlstr); } @@ -372,7 +372,7 @@ function moveMessages(rowIds, folder) { function onMenuDeleteMessage(event) { uixDeleteSelectedMessages(); - event.preventDefault(); + preventDefault(event); } function onMailboxTreeItemClick(event) { @@ -395,7 +395,7 @@ function onMailboxTreeItemClick(event) { else openMailbox(mailbox); - event.preventDefault(); + preventDefault(event); } function onMailboxMenuMove() { @@ -451,12 +451,12 @@ function openMailbox(mailbox, reload) { document.messageListAjaxRequest = triggerAjaxRequest(url, messageListCallback, currentMessages[mailbox]); - if (mailboxContent.style.visibility == "hidden") { - mailboxContent.style.visibility = "visible;"; - rightDragHandle.style.visibility = "visible;"; - messageContent.style.top = (rightDragHandle.offsetTop - + rightDragHandle.offsetHeight - + 'px;'); + if (mailboxContent.getStyle('visibility') == "hidden") { + mailboxContent.setStyle({ visibility: "visible" }); + rightDragHandle.setStyle({ visibility: "visible" }); + messageContent.setStyle({ top: (rightDragHandle.offsetTop + + rightDragHandle.offsetHeight + + 'px') }); } } } @@ -474,12 +474,12 @@ function openMailboxAtIndex(event) { document.messageListAjaxRequest = triggerAjaxRequest(url, messageListCallback); - event.preventDefault(); + preventDefault(event); } function messageListCallback(http) { var div = $('mailboxContent'); - + if (http.readyState == 4 && http.status == 200) { document.messageListAjaxRequest = null; @@ -493,7 +493,7 @@ function messageListCallback(http) { configureSortableTableHeaders(); } else - log("problem during ajax request"); + log("messageListCallback: problem during ajax request (readyState = " + http.readyState + ", status = " + http.status + ")"); } function onMessageContextMenu(event) { @@ -555,7 +555,7 @@ function onFolderMenuClick(event) { topNode.menuSelectedEntry = this; this.select(); - event.preventDefault(); + preventDefault(event); } function onFolderMenuHide(event) { @@ -625,6 +625,7 @@ function storeCachedMessage(cachedMessage) { function onMessageSelectionChange() { var rows = this.getSelectedRowsId(); + if (rows.length == 1) { var idx = rows[0].substr(4); @@ -662,12 +663,12 @@ function configureLinksInMessage() { var messageDiv = $('messageContent'); var mailContentDiv = document.getElementsByClassName('mailer_mailcontent', messageDiv)[0]; - Event.observe(mailContentDiv, "contextmenu", onMessageContentMenu); + Event.observe(mailContentDiv, "contextmenu", onMessageContentMenu.bindAsEventListener(mailContentDiv)); var anchors = messageDiv.getElementsByTagName('a'); for (var i = 0; i < anchors.length; i++) if (anchors[i].href.substring(0,7) == "mailto:") { - Event.observe(anchors[i], "click", onEmailAddressClick); - Event.observe(anchors[i], "contextmenu", onEmailAddressClick); + Event.observe(anchors[i], "click", onEmailAddressClick.bindAsEventListener(anchors[i])); + Event.observe(anchors[i], "contextmenu", onEmailAddressClick.bindAsEventListener(anchors[i])); } else Event.observe(anchors[i], "click", onMessageAnchorClick); @@ -683,7 +684,7 @@ function onEmailAddressClick(event) { function onMessageAnchorClick (event) { window.open(this.href); - event.preventDefault(); + preventDefault(event); } function messageCallback(http) { @@ -694,7 +695,7 @@ function messageCallback(http) { document.messageAjaxRequest = null; div.innerHTML = http.responseText; configureLinksInMessage(); - + if (http.callbackData) { var cachedMessage = new Array(); cachedMessage['idx'] = currentMailbox + '/' + http.callbackData; @@ -705,7 +706,7 @@ function messageCallback(http) { } } else - log("problem during ajax request"); + log("messageCallback: problem during ajax request: " + http.status); } function processMailboxMenuAction(mailbox) { @@ -837,13 +838,14 @@ function onHeaderClick(event) { document.messageListAjaxRequest.aborted = true; document.messageListAjaxRequest.abort(); } - url = ApplicationBaseURL + currentMailbox + "/" + this.link; - if (!this.link.match(/noframe=/)) + var link = this.getAttribute('href'); + url = ApplicationBaseURL + currentMailbox + "/" + link; + if (!link.match(/noframe=/)) url += "&noframe=1"; document.messageListAjaxRequest = triggerAjaxRequest(url, messageListCallback); - event.preventDefault(); + preventDefault(event); } function onSearchFormSubmit() { @@ -935,23 +937,21 @@ var messageListData = function(type) { function configureMessageListEvents() { var messageList = $("messageList"); if (messageList) { - Event.observe(messageList, "selectionchange", onMessageSelectionChange); + Event.observe(messageList, "mousedown", onMessageSelectionChange.bindAsEventListener(messageList)); var rows = messageList.tBodies[0].rows; var start = 0; if (rows.length > 1) { - if (rows[start].cells[0].hasClassName("tbtv_headercell")) + if ($(rows[start].cells[0]).hasClassName("tbtv_headercell")) start++; - if (rows[start].cells[0].hasClassName("tbtv_navcell")) { - log("start:" + start); + if ($(rows[start].cells[0]).hasClassName("tbtv_navcell")) { var anchors = $(rows[start].cells[0]).childNodesWithTag("a"); - log("nr anchors: " + anchors.length); for (var i = 0; i < anchors.length; i++) - Event.observe(anchors[i], "click", openMailboxAtIndex); + Event.observe(anchors[i], "click", openMailboxAtIndex.bindAsEventListener(anchors[i])); start++; } for (var i = start; i < rows.length; i++) { Event.observe(rows[i], "mousedown", onRowClick); - Event.observe(rows[i], "contextmenu", onMessageContextMenu); + Event.observe(rows[i], "contextmenu", onMessageContextMenu.bindAsEventListener(rows[i])); rows[i].dndTypes = function() { return new Array("mailRow"); }; rows[i].dndGhost = messageListGhost; @@ -962,7 +962,7 @@ function configureMessageListEvents() { var cell = rows[i].cells[j]; Event.observe(cell, "mousedown", listRowMouseDownHandler); if (j == 2 || j == 3 || j == 5) - Event.observe(cell, "dblclick", onMessageDoubleClick); + Event.observe(cell, "dblclick", onMessageDoubleClick.bindAsEventListener(cell)); else if (j == 4) { var img = cell.childNodesWithTag("img")[0]; Event.observe(img, "click", mailListMarkMessage); @@ -1032,11 +1032,11 @@ function openInbox(node) { function configureSearchField() { var searchValue = $("searchValue"); - Event.observe(searchValue, "mousedown", onSearchMouseDown); - Event.observe(searchValue, "click", popupSearchMenu); - Event.observe(searchValue, "blur", onSearchBlur); - Event.observe(searchValue, "focus", onSearchFocus); - Event.observe(searchValue, "keydown", onSearchKeyDown); + Event.observe(searchValue, "mousedown", onSearchMouseDown.bindAsEventListener(searchValue)); + Event.observe(searchValue, "click", popupSearchMenu.bindAsEventListener(searchValue)); + Event.observe(searchValue, "blur", onSearchBlur.bindAsEventListener(searchValue)); + Event.observe(searchValue, "focus", onSearchFocus.bindAsEventListener(searchValue)); + Event.observe(searchValue, "keydown", onSearchKeyDown.bindAsEventListener(searchValue)); } function initMailer(event) { @@ -1110,7 +1110,7 @@ function mailboxMenuNode(type, name) { function generateMenuForMailbox(mailbox, prefix, callback) { var menuDIV = document.createElement("div"); - menuDIV.addClassName("menu"); + $(menuDIV).addClassName("menu"); menuDIV.setAttribute("id", prefix + "Submenu"); var menu = document.createElement("ul"); menuDIV.appendChild(menu); @@ -1159,15 +1159,19 @@ function updateMailboxMenus() { var menuDIV = $(menuId); if (menuDIV) menuDIV.parentNode.removeChild(menuDIV); + menuDIV = document.createElement("div"); - menuDIV.addClassName("menu"); - menuDIV.setAttribute("id", menuId); + document.body.appendChild(menuDIV); + var menu = document.createElement("ul"); menuDIV.appendChild(menu); + $(menuDIV).addClassName("menu"); + menuDIV.setAttribute("id", menuId); + var submenuIds = new Array(); for (var i = 0; i < mailAccounts.length; i++) { - var menuEntry = mailboxMenuNode("account", mailAccounts[i]); + var menuEntry = mailboxMenuNode("account", mailAccounts[i]); menu.appendChild(menuEntry); var mailbox = accounts[mailAccounts[i]]; var newSubmenu = generateMenuForMailbox(mailbox, @@ -1176,8 +1180,6 @@ function updateMailboxMenus() { submenuIds.push(newSubmenu.getAttribute("id")); } initMenu(menuDIV, submenuIds); - - document.body.appendChild(menuDIV); } } @@ -1190,8 +1192,8 @@ function onLoadMailboxesCallback(http) { mailboxTree.addMailAccount(newAccount); mailboxTree.pendingRequests--; if (!mailboxTree.pendingRequests) { - updateMailboxTreeInPage(); - updateMailboxMenus(); + updateMailboxTreeInPage(); + updateMailboxMenus(); } } @@ -1324,7 +1326,7 @@ function getMenus() { return menus; } -Event.observe(window, "load", initMailer); +addEvent(window, 'load', initMailer); function Mailbox(type, name) { this.type = type; diff --git a/UI/WebServerResources/SOGoDragHandles.js b/UI/WebServerResources/SOGoDragHandles.js index bcd4b194..c3c6793d 100644 --- a/UI/WebServerResources/SOGoDragHandles.js +++ b/UI/WebServerResources/SOGoDragHandles.js @@ -40,13 +40,13 @@ var SOGoDragHandlesInterface = { this.origLeft = this.leftBlock.offsetWidth; delta = 0; this.origRight = this.rightBlock.offsetLeft - 5; - document.body.style.cursor = "e-resize"; + document.body.setStyle({ cursor: "e-resize" }); } else if (this.dhType == 'vertical') { this.origY = this.offsetTop; this.origUpper = this.upperBlock.offsetHeight; delta = event.clientY - this.offsetTop - 5; this.origLower = this.lowerBlock.offsetTop - 5; - document.body.style.cursor = "n-resize"; + document.body.setStyle({ cursor: "n-resize" }); } this.stopHandleDraggingBound = this.stopHandleDragging.bindAsEventListener(this); Event.observe(document.body, "mouseup", this.stopHandleDraggingBound, true); @@ -64,13 +64,13 @@ var SOGoDragHandlesInterface = { if (this.dhType == 'horizontal') { var deltaX = Math.floor(event.clientX - this.origX - (this.offsetWidth / 2)); - this.rightBlock.style.left = (this.origRight + deltaX) + 'px'; - this.leftBlock.style.width = (this.origLeft + deltaX) + 'px'; + this.rightBlock.setStyle({ left: (this.origRight + deltaX) + 'px' }); + this.leftBlock.setStyle({ width: (this.origLeft + deltaX) + 'px' }); } else if (this.dhType == 'vertical') { var deltaY = Math.floor(event.clientY - this.origY - (this.offsetHeight / 2)); - this.lowerBlock.style.top = (this.origLower + deltaY - delta) + 'px'; - this.upperBlock.style.height = (this.origUpper + deltaY - delta) + 'px'; + this.lowerBlock.setStyle({ top: (this.origLower + deltaY - delta) + 'px' }); + this.upperBlock.setStyle({ height: (this.origUpper + deltaY - delta) + 'px' }); } Event.stopObserving(document.body, "mouseup", this.stopHandleDraggingBound, true); @@ -91,7 +91,7 @@ var SOGoDragHandlesInterface = { var hX = event.clientX; if (hX > -1) { var newLeft = Math.floor(hX - (width / 2)); - this.style.left = newLeft + 'px'; + this.setStyle({ left: newLeft + 'px' }); event.cancelBubble = true; return false; @@ -101,7 +101,7 @@ var SOGoDragHandlesInterface = { var hY = event.clientY; if (hY > -1) { var newTop = Math.floor(hY - (height / 2)) - delta; - this.style.top = newTop + 'px'; + this.setStyle({ top: newTop + 'px' }); event.cancelBubble = true; return false; @@ -117,9 +117,9 @@ var SOGoDragHandlesInterface = { if (this.offsetLeft > lLeft) { var leftdelta = this.rightBlock.offsetLeft - this.offsetLeft; - this.style.left = lLeft + 'px'; - this.leftBlock.style.width = '0px'; - this.rightBlock.style.left = (lLeft + leftdelta) + 'px'; + this.setStyle({ left: lLeft + 'px' }); + this.leftBlock.setStyle({ width: '0px' }); + this.rightBlock.setStyle({ left: (lLeft + leftdelta) + 'px' }); } } else if (this.dhType == 'vertical') { var uTop = this.upperBlock.offsetTop; @@ -127,9 +127,9 @@ var SOGoDragHandlesInterface = { if (this.offsetTop > uTop) { var topdelta = this.lowerBlock.offsetTop - this.offsetTop; - this.style.top = uTop + 'px'; - this.upperBlock.style.width = '0px'; - this.lowerBlock.style.top = (uTop + topdelta) + 'px'; + this.setStyle({ top: uTop + 'px' }); + this.upperBlock.setStyle({ width: '0px' }); + this.lowerBlock.setStyle({ top: (uTop + topdelta) + 'px' }); } } } diff --git a/UI/WebServerResources/SchedulerUI.css b/UI/WebServerResources/SchedulerUI.css index a9a29731..b3b26fc4 100644 --- a/UI/WebServerResources/SchedulerUI.css +++ b/UI/WebServerResources/SchedulerUI.css @@ -1,32 +1,26 @@ DIV#leftPanel -{ - position: absolute; +{ position: absolute; top: 5.5em; left: 0px; - width: 18.5em; + width: 19.25em; bottom: 0px; - overflow: hidden; -} + overflow: hidden; } DIV#schedulerTabs -{ - position: absolute; +{ position: absolute; top: 0.5em; left: .2em; right: .2em; - height: 17em; -} + height: 14em; } DIV#tasksListView -{ - position: absolute; - top: 20em; +{ position: absolute; + top: 17em; bottom: 0px; left: .2em; right: .7em; - padding: 0px; -} + padding: 0px; } DIV#tasksListView H2 { font-size: 10pt; @@ -67,7 +61,7 @@ UL#tasksList, UL#calendarList border-right: 1px solid #fff; border-top: 2px solid #222; border-left: 2px solid #222; - background: #fff; + background-color: #fff; -moz-border-top-colors: #9c9a94 #000 transparent; -moz-border-left-colors: #9c9a94 #000 transparent; list-style-type: none; @@ -84,7 +78,7 @@ UL#calendarList LI UL#tasksList { position: absolute; width: 100%; - top: 3em; + top: 2em; left: .25em; right: .25em; bottom: .25em; } @@ -106,28 +100,21 @@ UL#tasksList LI.duelater { color: #999; } UL#tasksList LI[class~="_selected"].overdue -{ - color: #fff !important; - background-color: #f00 !important; -} +{ color: #fff !important; + background-color: #f00 !important; } UL#tasksList LI[class~="_selected"].duetoday -{ - color: #fff !important; - background-color: #00f !important; -} +{ color: #fff !important; + background-color: #00f !important; } UL#tasksList LI[class~="_selected"].duelater -{ - color: #fff !important; - background-color: #999 !important; -} +{ color: #fff !important; + background-color: #999 !important; } DIV#rightPanel -{ - position: absolute; +{ position: absolute; top: 5.5em; - left: 18.5em; + left: 19.25em; right: 0px; bottom: 0px; margin: 0px; @@ -135,72 +122,63 @@ DIV#rightPanel padding: 0px; overflow: hidden; } -DIV#appointmentsListView +DIV#eventsListView { display: block; + cursor: default; position: absolute; - background: #fff; + background-color: #fff; top: 2.5em; left: 0px; right: 0px; - overflow: auto; - overflow-x: hidden; height: 15.5em; - min-width: 600px; } + overflow: hidden; + overflow-y: auto; } DIV#calendarView -{ - position: absolute; - background: #fff; +{ position: absolute; + background-color: #fff; top: 18em; margin-top: 5px; bottom: 0px; width: 100%; border-top: 1px solid #aaa; - border-left: 1px solid #aaa; -} + border-left: 1px solid #aaa; } DIV#calendarView A -{ - text-decoration: none; +{ text-decoration: none; font: inherit; - color: inherit; -} + color: inherit; } #verticalDragHandle -{ - cursor: e-resize; +{ cursor: e-resize; top: 7.5em; - left: 18.5em; + left: 19.25em; width: 5px; - bottom: 0px; -} + bottom: 0px; } #rightDragHandle -{ - cursor: n-resize; +{ cursor: n-resize; top: 18em; left: 0px; right: 0px; - height: 5px; -} + height: 5px; } #filterPanel -{ - padding-right: .5em; -} +{ padding-right: .5em; } + +DIV#dateSelectorView +{ overflow: hidden; } #dateSelector -{ - margin: 0px auto; - background: #fff; +{ margin: 0px auto; + background-color: #fff; border-top: 1px solid #fff; border-left: 1px solid #fff; border-right: 1px solid #aaa; - border-bottom: 1px solid #aaa; -} + border-bottom: 1px solid #aaa; } #dateSelector > .header -{ background: #efefef; +{ background-color: #efefef; width: 100%; white-space: nowrap; vertical-align: middle; @@ -210,20 +188,14 @@ DIV#calendarView A border: 0px; } #dateSelector > .header A -{ - width: 1em; - padding: .4em .2em; -} +{ width: 1em; + padding: .4em .2em; } #dateSelector > .header #leftArrow -{ - float: left; -} +{ float: left; } #dateSelector > .header #rightArrow -{ - float: right; -} +{ float: right; } #dateSelector > .header SPAN { cursor: default; @@ -242,6 +214,9 @@ DIV#calendarView A #dateSelector .dayOfWeek { color: #00f; } +TABLE#dateSelectorTable +{ padding: 2px; } + #dateSelector TABLE#dateSelectorTable TD { width: 14%; } @@ -255,23 +230,24 @@ DIV#calendarView A width: 100%; } #dateSelector TABLE TABLE TD -{ - cursor: pointer; +{ cursor: pointer; margin: 0px; padding: 0px; width: 100%; - border: 1px solid #fff; -} + border: 1px solid #fff; } #dateSelector TABLE TABLE TD:hover { color: #f00; border: 1px solid #deebf7; } +#dateSelector TABLE TABLE TD:hover A +{ color: #f00; } + #dateSelector .inactiveDay { color: #dedfde; } #dateSelector .dayOfToday -{ background: #deebf7; +{ background-color: #deebf7; border: 1px solid #deebf7; } #dateSelector TD SPAN @@ -281,28 +257,28 @@ DIV#calendarView A display: block; } #dateSelector TD SPAN A -{ color: inherit; +{ color: #000; background: inherit; text-decoration: none; } #dateSelector TD:active -{ background: #ddd; +{ background-color: #ddd; border: 1px solid #deebf7; } -TABLE#appointmentsList +TABLE#eventsList { display: block; position: relative; width: 100%; } -TABLE#appointmentsList td.tbtv_subject_headercell, -TABLE#appointmentsList td.headerLocation +TABLE#eventsList td.tbtv_subject_headercell, +TABLE#eventsList td.headerLocation { width: 35%; } ._unfocused#dateSelector TD._selected, UL._unfocused > LI._selected, -TABLE._unfocused#appointmentsList TR._selected TD +TABLE._unfocused#eventsList TR._selected TD { - background: #d4d0c8 !important;; + background-color: #d4d0c8 !important;; color: #fff !important;; } @@ -315,14 +291,14 @@ SPAN.weeksHeader, SPAN.monthsHeader { display: block; white-space: nowrap; - background: #d4d0c8; + background-color: #d4d0c8; overflow: hidden; width: 100%; margin: 0px; height: 3em; padding: 2px 1.5em; - border: 0px; - border-bottom: 1px solid #ccc; } +/* HERE border: 0px; + */ border-bottom: 1px solid #ccc; } SPAN.daysHeader SPAN, SPAN.weeksHeader SPAN, @@ -391,50 +367,103 @@ SPAN.day0, SPAN.week0, SPAN.month0 border-left: 1px solid #828482 !important; border-bottom: 1px solid #fff !important; border-right: 1px solid #fff !important; - background: #ddd; } + background-color: #ddd; } A.leftNavigationArrow -{ - position: absolute; +{ position: absolute; display: block; top: .5em; - left: .5em; -} + left: .5em; } A.rightNavigationArrow -{ - position: absolute; +{ position: absolute; display: block; top: .5em; - right: .5em; -} + right: .5em; } -DIV#calendarContent +DIV#calendarHeader, +DIV#daysView { position: absolute; - top: 3.5em; + left: 0px; + right: 0px; padding: 0px; - margin: 0px; + margin: 0px; } + +DIV#daysView +{ top: 11em; bottom: 0px; - left: 0px; + margin-left: 1px; + border-left: 1px solid #397d94; + border-bottom: 1px solid #397d94; + border-top: 2px solid #397d94; + overflow: auto; } + +DIV#calendarHeader +{ top: 3.5em; + border: 0px; + height: 7.5em; } + +DIV#calendarHeader DIV.dayLabels, +DIV#calendarHeader DIV.days +{ position: absolute; + margin: 0px; + padding: 0px; +/* HERE border: 0px; */ + border-right: 1px solid #397d94; + border-top: 1px solid #397d94; + left: 5em; + margin-left: 1px; + margin-right: 16px; right: 0px; - overflow: auto; + overflow: hidden; } + +DIV#calendarHeader DIV.dayLabels +{ bottom: 4em; + height: 3em; } + +DIV#calendarHeader DIV.dayLabels DIV.day +{ text-align: center; + font-weight: bold; + color: #77a; + background-color: #e7efef; } + +DIV#calendarHeader SPAN.dayOfWeek +{ font-size: medium; } + +DIV#calendarHeader DIV.dayLabels +{ cursor: default; } + +DIV#calendarHeader DIV.days +{ cursor: pointer; + bottom: 0px; + height: 4em; } + +DIV#calendarHeader DIV.day +{ height: 100%; + margin: 0px; + padding: 0px; + margin-right: 1px; } + +DIV#calendarHeader DIV.days DIV.day +{ overflow: hidden; + overflow-y: auto; } + +/* DIV#daysView /* background-position: top center; background-repeat: no-repeat; background-image: url("/SOGo.woa/WebServerResources/background.jpg"); - */} + } */ .menu LI.currentMonth, .menu LI.currentYear -{ - border-top: 1px solid #aaa; +{ border-top: 1px solid #aaa; border-left: 1px solid #aaa; border-bottom: 1px solid #fff; border-right: 1px solid #fff; - background: #ccc; - color: #222; -} + background-color: #ccc; + color: #222; } -DIV.appointmentView +DIV.eventView { display: block; overflow: hidden; white-space: nowrap; @@ -442,18 +471,13 @@ DIV.appointmentView /* new draggable presentation */ -DIV.daysView -{ position: relative; - margin: 1em; - height: 100em; - border-bottom: 1px solid #397d94; } - -DIV.daysView DIV.days +DIV#daysView DIV.days { position: absolute; + margin: 0px; + height: 96em; top: 0px; - bottom: 0px; left: 5em; - right: 0px; } + right: 2px; } DIV.multicolumnDayView DIV.lastDayUser { border-right: 1px solid #397d94; } @@ -461,10 +485,10 @@ DIV.multicolumnDayView DIV.lastDayUser DIV.monthView { position: absolute; left: .5em; - top: .5em; + top: 4em; right: 1em; bottom: 1em; - border: 0px; +/* border: 0px; HERE */ margin: 0px; padding: 0px; min-width: 20em; @@ -478,6 +502,7 @@ DIV.monthView > DIV.days > DIV DIV.monthView > DIV.headerDay { text-align: center; + cursor: default; padding-top: .5em; border-left: 2px solid #397d94 !important; border-top: 2px solid #397d94 !important; @@ -485,28 +510,29 @@ DIV.monthView > DIV.headerDay color: #397d94; height: 1.5em; font-weight: bold; - background: #e7efef; } + background-color: #e7efef; } -DIV.monthView DIV.dayOfToday -{ border: 0px solid #397d94; - background-color: #deebf7; } +DIV.dayOfToday +{ background-color: #deebf7; } -DIV.monthView DIV.weekEndDay +DIV.weekEndDay { background-color: #fffbe7; } -DIV.monthView DIV.dayOfAnotherMonth +DIV.dayOfAnotherMonth { background-color: #e7efef; } -DIV.monthView DIV.selectedDay +DIV.selectedDay { background-color: #ffe79c; } DIV.monthView DIV.dayHeader { margin-left: 1em; + cursor: pointer; color: #397d94; font-weight: bold; } DIV.monthView DIV.days { top: 2em; + cursor: pointer; bottom: 0px; left: 0px; right: 0px; } @@ -583,36 +609,36 @@ DIV.monthView DIV.week5 DIV.monthView DIV.week6 { top: 90%; } -DIV.daysView DIV.day +DIV#calendarHeader DIV.day, +DIV#daysView DIV.day { position: absolute; border-left: 1px solid #397d94; - left: 0px; - top: 0px; - bottom: 0px; } + margin: 0px; + padding: 0px; + top: 0px; } + +/* DIV#calendarHeader DIV.day1 +{ border-left: 0px; } + */ -DIV.daysView > DIV.days > DIV.day > DIV.header -{ height: 3.5em; +/* DIV#daysView > DIV.days > DIV.day > DIV.header +{ position: fixed; + top: ; + height: 3.5em; padding-top: .5em; border: 0px; border-top: 1px solid #397d94; font-weight: bold; text-align: center; - background: #e7efef; - color: #397d94; } - -DIV.daysView > DIV.days > DIV.dayOfToday -{ background-color: #deebf7; } - -DIV.daysView > DIV.days > DIV.weekEndDay -{ background-color: #fffbe7; } - -DIV.daysView > DIV.days > DIV.selectedDay -{ background-color: #ffe79c; } + background-color: #e7efef; + color: #397d94; } */ DIV.daysViewFor1Days DIV.day -{ width: 100%; - border-right: 1px solid #397d94; - left: 0px; } +{ border-right: 1px solid #397d94; + width: 100%; } + +/* DIV#daysView DIV.day +{ margin-right: 3px; } */ DIV.monthView DIV.headerDay, DIV.monthView DIV.day, @@ -651,158 +677,157 @@ DIV.daysViewFor7Days DIV.day0 { left: 85.7142%; border-right: 1px solid #397d94; } -DIV.daysView > DIV.hours +DIV#daysView > DIV.hours { position: absolute; - border: 0px; left: 0px; - top: 4em; + top: 0px; width: 4.5em; height: 95.5em; font-weight: bold; - color: #77a; margin: 0px; padding-top: .5em; padding-right: .5em; - border-left: 1px solid #397d94; - background: #e7efef; + color: #77a; + background-color: #e7efef; text-align: right; } -DIV.daysView > DIV.hours > DIV.hour +DIV#daysView > DIV.hours > DIV.hour { height: 4em; } -DIV.daysView > DIV.hourLines > DIV.hourLine +DIV#daysView > DIV.hourLines > DIV.hourLine { position: absolute; - z-index: 1; height: 1px; left: 0px; right: 0px; - border-top: 1px solid #397d94; } + padding-left: 1em; + margin-right: 2px; + border-bottom: 1px solid #397d94; } DIV.clickableHourCell -{ width: 100%; +{ cursor: pointer; + width: 100%; height: 4em; } DIV.clickableHourCell0 { top: 0px; } DIV.clickableHourCell1, -DIV.daysView > DIV.hourLines > DIV.hourLine0 +DIV#daysView > DIV.hourLines > DIV.hourLine0 { top: 4em; } DIV.clickableHourCell2, -DIV.daysView > DIV.hourLines > DIV.hourLine1 +DIV#daysView > DIV.hourLines > DIV.hourLine1 { top: 8em; } DIV.clickableHourCell3, -DIV.daysView > DIV.hourLines > DIV.hourLine2 +DIV#daysView > DIV.hourLines > DIV.hourLine2 { top: 12em; } -DIV.clickableHourCell3, -DIV.daysView > DIV.hourLines > DIV.hourLine3 +DIV.clickableHourCell4, +DIV#daysView > DIV.hourLines > DIV.hourLine3 { top: 16em; } DIV.clickableHourCell5, -DIV.daysView > DIV.hourLines > DIV.hourLine4 +DIV#daysView > DIV.hourLines > DIV.hourLine4 { top: 20em; } -DIV.clickableHourCell4, -DIV.daysView > DIV.hourLines > DIV.hourLine5 +DIV.clickableHourCell6, +DIV#daysView > DIV.hourLines > DIV.hourLine5 { top: 24em; } -DIV.clickableHourCell5, -DIV.daysView > DIV.hourLines > DIV.hourLine6 +DIV.clickableHourCell7, +DIV#daysView > DIV.hourLines > DIV.hourLine6 { top: 28em; } -DIV.clickableHourCell6, -DIV.daysView > DIV.hourLines > DIV.hourLine7 +DIV.clickableHourCell8, +DIV#daysView > DIV.hourLines > DIV.hourLine7 { top: 32em; } -DIV.clickableHourCell7, -DIV.daysView > DIV.hourLines > DIV.hourLine8 +DIV.clickableHourCell9, +DIV#daysView > DIV.hourLines > DIV.hourLine8 { top: 36em; } -DIV.clickableHourCell8, -DIV.daysView > DIV.hourLines > DIV.hourLine9 +DIV.clickableHourCell10, +DIV#daysView > DIV.hourLines > DIV.hourLine9 { top: 40em; } -DIV.clickableHourCell9, -DIV.daysView > DIV.hourLines > DIV.hourLine10 +DIV.clickableHourCell11, +DIV#daysView > DIV.hourLines > DIV.hourLine10 { top: 44em; } -DIV.clickableHourCell10, -DIV.daysView > DIV.hourLines > DIV.hourLine11 +DIV.clickableHourCell12, +DIV#daysView > DIV.hourLines > DIV.hourLine11 { top: 48em; } -DIV.clickableHourCell11, -DIV.daysView > DIV.hourLines > DIV.hourLine12 +DIV.clickableHourCell13, +DIV#daysView > DIV.hourLines > DIV.hourLine12 { top: 52em; } -DIV.clickableHourCell12, -DIV.daysView > DIV.hourLines > DIV.hourLine13 +DIV.clickableHourCell14, +DIV#daysView > DIV.hourLines > DIV.hourLine13 { top: 56em; } -DIV.clickableHourCell13, -DIV.daysView > DIV.hourLines > DIV.hourLine14 +DIV.clickableHourCell15, +DIV#daysView > DIV.hourLines > DIV.hourLine14 { top: 60em; } -DIV.clickableHourCell14, -DIV.daysView > DIV.hourLines > DIV.hourLine15 +DIV.clickableHourCell16, +DIV#daysView > DIV.hourLines > DIV.hourLine15 { top: 64em; } -DIV.clickableHourCell15, -DIV.daysView > DIV.hourLines > DIV.hourLine16 +DIV.clickableHourCell17, +DIV#daysView > DIV.hourLines > DIV.hourLine16 { top: 68em; } -DIV.clickableHourCell16, -DIV.daysView > DIV.hourLines > DIV.hourLine17 +DIV.clickableHourCell18, +DIV#daysView > DIV.hourLines > DIV.hourLine17 { top: 72em; } -DIV.clickableHourCell17, -DIV.daysView > DIV.hourLines > DIV.hourLine18 +DIV.clickableHourCell19, +DIV#daysView > DIV.hourLines > DIV.hourLine18 { top: 76em; } -DIV.clickableHourCell18, -DIV.daysView > DIV.hourLines > DIV.hourLine19 +DIV.clickableHourCell20, +DIV#daysView > DIV.hourLines > DIV.hourLine19 { top: 80em; } -DIV.clickableHourCell19, -DIV.daysView > DIV.hourLines > DIV.hourLine20 +DIV.clickableHourCell21, +DIV#daysView > DIV.hourLines > DIV.hourLine20 { top: 84em; } -DIV.clickableHourCell20, -DIV.daysView > DIV.hourLines > DIV.hourLine21 +DIV.clickableHourCell22, +DIV#daysView > DIV.hourLines > DIV.hourLine21 { top: 88em; } -DIV.clickableHourCell21, -DIV.daysView > DIV.hourLines > DIV.hourLine22 +DIV.clickableHourCell23, +DIV#daysView > DIV.hourLines > DIV.hourLine22 { top: 92em; } -DIV.clickableHourCell22, -DIV.daysView > DIV.hourLines > DIV.hourLine23 +DIV#daysView > DIV.hourLines > DIV.hourLine23 { top: 96em; } -DIV.daysView DIV.appointments -{ position: absolute; - z-index: 2; - border-top: 1px solid #397d94; +DIV#daysView DIV.events +{ z-index: 2; left: 0px; right: 0px; bottom: 0px; - top: 4em; } + top: 0px; } -DIV.appointments > DIV.appointment +DIV.events > DIV.event { cursor: default; + z-index: 1; position: absolute; left: 0px; right: 1px; + margin-top: 1px; padding: 1px; } -DIV[class~="appointment"]._selected > DIV.appointmentInside +DIV[class~="event"]._selected > DIV.eventInside { -moz-opacity: 0.7; opacity: 0.7; filter: alpha(opacity=70); } -DIV.appointment > DIV.appointmentInside +DIV.event > DIV.eventInside { position: absolute; overflow: hidden; top: 1px; @@ -846,7 +871,7 @@ DIV.shadow4 right: 3px; top: 3px; bottom: 4px; - moz-opacity: 0.4; + -moz-opacity: 0.4; opacity: 0.4; filter: alpha(opacity=40); } @@ -862,596 +887,598 @@ DIV.gradient > IMG { height: 100%; width: 100%; } -DIV.monthView DIV.appointment +DIV#calendarHeader DIV.event, +DIV.monthView DIV.event { position: relative; cursor: default; white-space: nowrap; - margin: 2px; + margin-top: 1px; + margin-left: 1px; margin-right: 3px; padding: 1px; height: 2em; } -DIV.appointment DIV.text +DIV.event DIV.text { font-size: 92%; } -DIV.daysView DIV[class~="appointment"].starts0 +DIV#daysView DIV[class~="event"].starts0 { top: 0.000000%; } -DIV.daysView DIV[class~="appointment"].starts1 +DIV#daysView DIV[class~="event"].starts1 { top: 1.041667%; } -DIV.daysView DIV[class~="appointment"].starts2 +DIV#daysView DIV[class~="event"].starts2 { top: 2.083333%; } -DIV.daysView DIV[class~="appointment"].starts3 +DIV#daysView DIV[class~="event"].starts3 { top: 3.125000%; } -DIV.daysView DIV[class~="appointment"].starts4 +DIV#daysView DIV[class~="event"].starts4 { top: 4.166667%; } -DIV.daysView DIV[class~="appointment"].starts5 +DIV#daysView DIV[class~="event"].starts5 { top: 5.208333%; } -DIV.daysView DIV[class~="appointment"].starts6 +DIV#daysView DIV[class~="event"].starts6 { top: 6.250000%; } -DIV.daysView DIV[class~="appointment"].starts7 +DIV#daysView DIV[class~="event"].starts7 { top: 7.291667%; } -DIV.daysView DIV[class~="appointment"].starts8 +DIV#daysView DIV[class~="event"].starts8 { top: 8.333333%; } -DIV.daysView DIV[class~="appointment"].starts9 +DIV#daysView DIV[class~="event"].starts9 { top: 9.375000%; } -DIV.daysView DIV[class~="appointment"].starts10 +DIV#daysView DIV[class~="event"].starts10 { top: 10.416667%; } -DIV.daysView DIV[class~="appointment"].starts11 +DIV#daysView DIV[class~="event"].starts11 { top: 11.458333%; } -DIV.daysView DIV[class~="appointment"].starts12 +DIV#daysView DIV[class~="event"].starts12 { top: 12.500000%; } -DIV.daysView DIV[class~="appointment"].starts13 +DIV#daysView DIV[class~="event"].starts13 { top: 13.541667%; } -DIV.daysView DIV[class~="appointment"].starts14 +DIV#daysView DIV[class~="event"].starts14 { top: 14.583333%; } -DIV.daysView DIV[class~="appointment"].starts15 +DIV#daysView DIV[class~="event"].starts15 { top: 15.625000%; } -DIV.daysView DIV[class~="appointment"].starts16 +DIV#daysView DIV[class~="event"].starts16 { top: 16.666667%; } -DIV.daysView DIV[class~="appointment"].starts17 +DIV#daysView DIV[class~="event"].starts17 { top: 17.708333%; } -DIV.daysView DIV[class~="appointment"].starts18 +DIV#daysView DIV[class~="event"].starts18 { top: 18.750000%; } -DIV.daysView DIV[class~="appointment"].starts19 +DIV#daysView DIV[class~="event"].starts19 { top: 19.791667%; } -DIV.daysView DIV[class~="appointment"].starts20 +DIV#daysView DIV[class~="event"].starts20 { top: 20.833333%; } -DIV.daysView DIV[class~="appointment"].starts21 +DIV#daysView DIV[class~="event"].starts21 { top: 21.875000%; } -DIV.daysView DIV[class~="appointment"].starts22 +DIV#daysView DIV[class~="event"].starts22 { top: 22.916667%; } -DIV.daysView DIV[class~="appointment"].starts23 +DIV#daysView DIV[class~="event"].starts23 { top: 23.958333%; } -DIV.daysView DIV[class~="appointment"].starts24 +DIV#daysView DIV[class~="event"].starts24 { top: 25.000000%; } -DIV.daysView DIV[class~="appointment"].starts25 +DIV#daysView DIV[class~="event"].starts25 { top: 26.041667%; } -DIV.daysView DIV[class~="appointment"].starts26 +DIV#daysView DIV[class~="event"].starts26 { top: 27.083333%; } -DIV.daysView DIV[class~="appointment"].starts27 +DIV#daysView DIV[class~="event"].starts27 { top: 28.125000%; } -DIV.daysView DIV[class~="appointment"].starts28 +DIV#daysView DIV[class~="event"].starts28 { top: 29.166667%; } -DIV.daysView DIV[class~="appointment"].starts29 +DIV#daysView DIV[class~="event"].starts29 { top: 30.208333%; } -DIV.daysView DIV[class~="appointment"].starts30 +DIV#daysView DIV[class~="event"].starts30 { top: 31.250000%; } -DIV.daysView DIV[class~="appointment"].starts31 +DIV#daysView DIV[class~="event"].starts31 { top: 32.291667%; } -DIV.daysView DIV[class~="appointment"].starts32 +DIV#daysView DIV[class~="event"].starts32 { top: 33.333333%; } -DIV.daysView DIV[class~="appointment"].starts33 +DIV#daysView DIV[class~="event"].starts33 { top: 34.375000%; } -DIV.daysView DIV[class~="appointment"].starts34 +DIV#daysView DIV[class~="event"].starts34 { top: 35.416667%; } -DIV.daysView DIV[class~="appointment"].starts35 +DIV#daysView DIV[class~="event"].starts35 { top: 36.458333%; } -DIV.daysView DIV[class~="appointment"].starts36 +DIV#daysView DIV[class~="event"].starts36 { top: 37.500000%; } -DIV.daysView DIV[class~="appointment"].starts37 +DIV#daysView DIV[class~="event"].starts37 { top: 38.541667%; } -DIV.daysView DIV[class~="appointment"].starts38 +DIV#daysView DIV[class~="event"].starts38 { top: 39.583333%; } -DIV.daysView DIV[class~="appointment"].starts39 +DIV#daysView DIV[class~="event"].starts39 { top: 40.625000%; } -DIV.daysView DIV[class~="appointment"].starts40 +DIV#daysView DIV[class~="event"].starts40 { top: 41.666667%; } -DIV.daysView DIV[class~="appointment"].starts41 +DIV#daysView DIV[class~="event"].starts41 { top: 42.708333%; } -DIV.daysView DIV[class~="appointment"].starts42 +DIV#daysView DIV[class~="event"].starts42 { top: 43.750000%; } -DIV.daysView DIV[class~="appointment"].starts43 +DIV#daysView DIV[class~="event"].starts43 { top: 44.791667%; } -DIV.daysView DIV[class~="appointment"].starts44 +DIV#daysView DIV[class~="event"].starts44 { top: 45.833333%; } -DIV.daysView DIV[class~="appointment"].starts45 +DIV#daysView DIV[class~="event"].starts45 { top: 46.875000%; } -DIV.daysView DIV[class~="appointment"].starts46 +DIV#daysView DIV[class~="event"].starts46 { top: 47.916667%; } -DIV.daysView DIV[class~="appointment"].starts47 +DIV#daysView DIV[class~="event"].starts47 { top: 48.958333%; } -DIV.daysView DIV[class~="appointment"].starts48 +DIV#daysView DIV[class~="event"].starts48 { top: 50.000000%; } -DIV.daysView DIV[class~="appointment"].starts49 +DIV#daysView DIV[class~="event"].starts49 { top: 51.041667%; } -DIV.daysView DIV[class~="appointment"].starts50 +DIV#daysView DIV[class~="event"].starts50 { top: 52.083333%; } -DIV.daysView DIV[class~="appointment"].starts51 +DIV#daysView DIV[class~="event"].starts51 { top: 53.125000%; } -DIV.daysView DIV[class~="appointment"].starts52 +DIV#daysView DIV[class~="event"].starts52 { top: 54.166667%; } -DIV.daysView DIV[class~="appointment"].starts53 +DIV#daysView DIV[class~="event"].starts53 { top: 55.208333%; } -DIV.daysView DIV[class~="appointment"].starts54 +DIV#daysView DIV[class~="event"].starts54 { top: 56.250000%; } -DIV.daysView DIV[class~="appointment"].starts55 +DIV#daysView DIV[class~="event"].starts55 { top: 57.291667%; } -DIV.daysView DIV[class~="appointment"].starts56 +DIV#daysView DIV[class~="event"].starts56 { top: 58.333333%; } -DIV.daysView DIV[class~="appointment"].starts57 +DIV#daysView DIV[class~="event"].starts57 { top: 59.375000%; } -DIV.daysView DIV[class~="appointment"].starts58 +DIV#daysView DIV[class~="event"].starts58 { top: 60.416667%; } -DIV.daysView DIV[class~="appointment"].starts59 +DIV#daysView DIV[class~="event"].starts59 { top: 61.458333%; } -DIV.daysView DIV[class~="appointment"].starts60 +DIV#daysView DIV[class~="event"].starts60 { top: 62.500000%; } -DIV.daysView DIV[class~="appointment"].starts61 +DIV#daysView DIV[class~="event"].starts61 { top: 63.541667%; } -DIV.daysView DIV[class~="appointment"].starts62 +DIV#daysView DIV[class~="event"].starts62 { top: 64.583333%; } -DIV.daysView DIV[class~="appointment"].starts63 +DIV#daysView DIV[class~="event"].starts63 { top: 65.625000%; } -DIV.daysView DIV[class~="appointment"].starts64 +DIV#daysView DIV[class~="event"].starts64 { top: 66.666667%; } -DIV.daysView DIV[class~="appointment"].starts65 +DIV#daysView DIV[class~="event"].starts65 { top: 67.708333%; } -DIV.daysView DIV[class~="appointment"].starts66 +DIV#daysView DIV[class~="event"].starts66 { top: 68.750000%; } -DIV.daysView DIV[class~="appointment"].starts67 +DIV#daysView DIV[class~="event"].starts67 { top: 69.791667%; } -DIV.daysView DIV[class~="appointment"].starts68 +DIV#daysView DIV[class~="event"].starts68 { top: 70.833333%; } -DIV.daysView DIV[class~="appointment"].starts69 +DIV#daysView DIV[class~="event"].starts69 { top: 71.875000%; } -DIV.daysView DIV[class~="appointment"].starts70 +DIV#daysView DIV[class~="event"].starts70 { top: 72.916667%; } -DIV.daysView DIV[class~="appointment"].starts71 +DIV#daysView DIV[class~="event"].starts71 { top: 73.958333%; } -DIV.daysView DIV[class~="appointment"].starts72 +DIV#daysView DIV[class~="event"].starts72 { top: 75.000000%; } -DIV.daysView DIV[class~="appointment"].starts73 +DIV#daysView DIV[class~="event"].starts73 { top: 76.041667%; } -DIV.daysView DIV[class~="appointment"].starts74 +DIV#daysView DIV[class~="event"].starts74 { top: 77.083333%; } -DIV.daysView DIV[class~="appointment"].starts75 +DIV#daysView DIV[class~="event"].starts75 { top: 78.125000%; } -DIV.daysView DIV[class~="appointment"].starts76 +DIV#daysView DIV[class~="event"].starts76 { top: 79.166667%; } -DIV.daysView DIV[class~="appointment"].starts77 +DIV#daysView DIV[class~="event"].starts77 { top: 80.208333%; } -DIV.daysView DIV[class~="appointment"].starts78 +DIV#daysView DIV[class~="event"].starts78 { top: 81.250000%; } -DIV.daysView DIV[class~="appointment"].starts79 +DIV#daysView DIV[class~="event"].starts79 { top: 82.291667%; } -DIV.daysView DIV[class~="appointment"].starts80 +DIV#daysView DIV[class~="event"].starts80 { top: 83.333333%; } -DIV.daysView DIV[class~="appointment"].starts81 +DIV#daysView DIV[class~="event"].starts81 { top: 84.375000%; } -DIV.daysView DIV[class~="appointment"].starts82 +DIV#daysView DIV[class~="event"].starts82 { top: 85.416667%; } -DIV.daysView DIV[class~="appointment"].starts83 +DIV#daysView DIV[class~="event"].starts83 { top: 86.458333%; } -DIV.daysView DIV[class~="appointment"].starts84 +DIV#daysView DIV[class~="event"].starts84 { top: 87.500000%; } -DIV.daysView DIV[class~="appointment"].starts85 +DIV#daysView DIV[class~="event"].starts85 { top: 88.541667%; } -DIV.daysView DIV[class~="appointment"].starts86 +DIV#daysView DIV[class~="event"].starts86 { top: 89.583333%; } -DIV.daysView DIV[class~="appointment"].starts87 +DIV#daysView DIV[class~="event"].starts87 { top: 90.625000%; } -DIV.daysView DIV[class~="appointment"].starts88 +DIV#daysView DIV[class~="event"].starts88 { top: 91.666667%; } -DIV.daysView DIV[class~="appointment"].starts89 +DIV#daysView DIV[class~="event"].starts89 { top: 92.708333%; } -DIV.daysView DIV[class~="appointment"].starts90 +DIV#daysView DIV[class~="event"].starts90 { top: 93.750000%; } -DIV.daysView DIV[class~="appointment"].starts91 +DIV#daysView DIV[class~="event"].starts91 { top: 94.791667%; } -DIV.daysView DIV[class~="appointment"].starts92 +DIV#daysView DIV[class~="event"].starts92 { top: 95.833333%; } -DIV.daysView DIV[class~="appointment"].starts93 +DIV#daysView DIV[class~="event"].starts93 { top: 96.875000%; } -DIV.daysView DIV[class~="appointment"].starts94 +DIV#daysView DIV[class~="event"].starts94 { top: 97.916667%; } -DIV.daysView DIV[class~="appointment"].starts95 +DIV#daysView DIV[class~="event"].starts95 { top: 98.958333%; } -DIV.daysView DIV[class~="appointment"].starts96 +DIV#daysView DIV[class~="event"].starts96 { top: 100.000000%; } -DIV.daysView DIV[class~="appointment"].lasts0 +DIV#daysView DIV[class~="event"].lasts0 { height: 0px; } -DIV.daysView DIV[class~="appointment"].lasts1 +DIV#daysView DIV[class~="event"].lasts1 { height: 1.041667%; } -DIV.daysView DIV[class~="appointment"].lasts2 +DIV#daysView DIV[class~="event"].lasts2 { height: 2.083333%; } -DIV.daysView DIV[class~="appointment"].lasts3 +DIV#daysView DIV[class~="event"].lasts3 { height: 3.125000%; } -DIV.daysView DIV[class~="appointment"].lasts4 +DIV#daysView DIV[class~="event"].lasts4 { height: 4.166667%; } -DIV.daysView DIV[class~="appointment"].lasts5 +DIV#daysView DIV[class~="event"].lasts5 { height: 5.208333%; } -DIV.daysView DIV[class~="appointment"].lasts6 +DIV#daysView DIV[class~="event"].lasts6 { height: 6.250000%; } -DIV.daysView DIV[class~="appointment"].lasts7 +DIV#daysView DIV[class~="event"].lasts7 { height: 7.291667%; } -DIV.daysView DIV[class~="appointment"].lasts8 +DIV#daysView DIV[class~="event"].lasts8 { height: 8.333333%; } -DIV.daysView DIV[class~="appointment"].lasts9 +DIV#daysView DIV[class~="event"].lasts9 { height: 9.375000%; } -DIV.daysView DIV[class~="appointment"].lasts10 +DIV#daysView DIV[class~="event"].lasts10 { height: 10.416667%; } -DIV.daysView DIV[class~="appointment"].lasts11 +DIV#daysView DIV[class~="event"].lasts11 { height: 11.458333%; } -DIV.daysView DIV[class~="appointment"].lasts12 +DIV#daysView DIV[class~="event"].lasts12 { height: 12.500000%; } -DIV.daysView DIV[class~="appointment"].lasts13 +DIV#daysView DIV[class~="event"].lasts13 { height: 13.541667%; } -DIV.daysView DIV[class~="appointment"].lasts14 +DIV#daysView DIV[class~="event"].lasts14 { height: 14.583333%; } -DIV.daysView DIV[class~="appointment"].lasts15 +DIV#daysView DIV[class~="event"].lasts15 { height: 15.625000%; } -DIV.daysView DIV[class~="appointment"].lasts16 +DIV#daysView DIV[class~="event"].lasts16 { height: 16.666667%; } -DIV.daysView DIV[class~="appointment"].lasts17 +DIV#daysView DIV[class~="event"].lasts17 { height: 17.708333%; } -DIV.daysView DIV[class~="appointment"].lasts18 +DIV#daysView DIV[class~="event"].lasts18 { height: 18.750000%; } -DIV.daysView DIV[class~="appointment"].lasts19 +DIV#daysView DIV[class~="event"].lasts19 { height: 19.791667%; } -DIV.daysView DIV[class~="appointment"].lasts20 +DIV#daysView DIV[class~="event"].lasts20 { height: 20.833333%; } -DIV.daysView DIV[class~="appointment"].lasts21 +DIV#daysView DIV[class~="event"].lasts21 { height: 21.875000%; } -DIV.daysView DIV[class~="appointment"].lasts22 +DIV#daysView DIV[class~="event"].lasts22 { height: 22.916667%; } -DIV.daysView DIV[class~="appointment"].lasts23 +DIV#daysView DIV[class~="event"].lasts23 { height: 23.958333%; } -DIV.daysView DIV[class~="appointment"].lasts24 +DIV#daysView DIV[class~="event"].lasts24 { height: 25.000000%; } -DIV.daysView DIV[class~="appointment"].lasts25 +DIV#daysView DIV[class~="event"].lasts25 { height: 26.041667%; } -DIV.daysView DIV[class~="appointment"].lasts26 +DIV#daysView DIV[class~="event"].lasts26 { height: 27.083333%; } -DIV.daysView DIV[class~="appointment"].lasts27 +DIV#daysView DIV[class~="event"].lasts27 { height: 28.125000%; } -DIV.daysView DIV[class~="appointment"].lasts28 +DIV#daysView DIV[class~="event"].lasts28 { height: 29.166667%; } -DIV.daysView DIV[class~="appointment"].lasts29 +DIV#daysView DIV[class~="event"].lasts29 { height: 30.208333%; } -DIV.daysView DIV[class~="appointment"].lasts30 +DIV#daysView DIV[class~="event"].lasts30 { height: 31.250000%; } -DIV.daysView DIV[class~="appointment"].lasts31 +DIV#daysView DIV[class~="event"].lasts31 { height: 32.291667%; } -DIV.daysView DIV[class~="appointment"].lasts32 +DIV#daysView DIV[class~="event"].lasts32 { height: 33.333333%; } -DIV.daysView DIV[class~="appointment"].lasts33 +DIV#daysView DIV[class~="event"].lasts33 { height: 34.375000%; } -DIV.daysView DIV[class~="appointment"].lasts34 +DIV#daysView DIV[class~="event"].lasts34 { height: 35.416667%; } -DIV.daysView DIV[class~="appointment"].lasts35 +DIV#daysView DIV[class~="event"].lasts35 { height: 36.458333%; } -DIV.daysView DIV[class~="appointment"].lasts36 +DIV#daysView DIV[class~="event"].lasts36 { height: 37.500000%; } -DIV.daysView DIV[class~="appointment"].lasts37 +DIV#daysView DIV[class~="event"].lasts37 { height: 38.541667%; } -DIV.daysView DIV[class~="appointment"].lasts38 +DIV#daysView DIV[class~="event"].lasts38 { height: 39.583333%; } -DIV.daysView DIV[class~="appointment"].lasts39 +DIV#daysView DIV[class~="event"].lasts39 { height: 40.625000%; } -DIV.daysView DIV[class~="appointment"].lasts40 +DIV#daysView DIV[class~="event"].lasts40 { height: 41.666667%; } -DIV.daysView DIV[class~="appointment"].lasts41 +DIV#daysView DIV[class~="event"].lasts41 { height: 42.708333%; } -DIV.daysView DIV[class~="appointment"].lasts42 +DIV#daysView DIV[class~="event"].lasts42 { height: 43.750000%; } -DIV.daysView DIV[class~="appointment"].lasts43 +DIV#daysView DIV[class~="event"].lasts43 { height: 44.791667%; } -DIV.daysView DIV[class~="appointment"].lasts44 +DIV#daysView DIV[class~="event"].lasts44 { height: 45.833333%; } -DIV.daysView DIV[class~="appointment"].lasts45 +DIV#daysView DIV[class~="event"].lasts45 { height: 46.875000%; } -DIV.daysView DIV[class~="appointment"].lasts46 +DIV#daysView DIV[class~="event"].lasts46 { height: 47.916667%; } -DIV.daysView DIV[class~="appointment"].lasts47 +DIV#daysView DIV[class~="event"].lasts47 { height: 48.958333%; } -DIV.daysView DIV[class~="appointment"].lasts48 +DIV#daysView DIV[class~="event"].lasts48 { height: 50.000000%; } -DIV.daysView DIV[class~="appointment"].lasts49 +DIV#daysView DIV[class~="event"].lasts49 { height: 51.041667%; } -DIV.daysView DIV[class~="appointment"].lasts50 +DIV#daysView DIV[class~="event"].lasts50 { height: 52.083333%; } -DIV.daysView DIV[class~="appointment"].lasts51 +DIV#daysView DIV[class~="event"].lasts51 { height: 53.125000%; } -DIV.daysView DIV[class~="appointment"].lasts52 +DIV#daysView DIV[class~="event"].lasts52 { height: 54.166667%; } -DIV.daysView DIV[class~="appointment"].lasts53 +DIV#daysView DIV[class~="event"].lasts53 { height: 55.208333%; } -DIV.daysView DIV[class~="appointment"].lasts54 +DIV#daysView DIV[class~="event"].lasts54 { height: 56.250000%; } -DIV.daysView DIV[class~="appointment"].lasts55 +DIV#daysView DIV[class~="event"].lasts55 { height: 57.291667%; } -DIV.daysView DIV[class~="appointment"].lasts56 +DIV#daysView DIV[class~="event"].lasts56 { height: 58.333333%; } -DIV.daysView DIV[class~="appointment"].lasts57 +DIV#daysView DIV[class~="event"].lasts57 { height: 59.375000%; } -DIV.daysView DIV[class~="appointment"].lasts58 +DIV#daysView DIV[class~="event"].lasts58 { height: 60.416667%; } -DIV.daysView DIV[class~="appointment"].lasts59 +DIV#daysView DIV[class~="event"].lasts59 { height: 61.458333%; } -DIV.daysView DIV[class~="appointment"].lasts60 +DIV#daysView DIV[class~="event"].lasts60 { height: 62.500000%; } -DIV.daysView DIV[class~="appointment"].lasts61 +DIV#daysView DIV[class~="event"].lasts61 { height: 63.541667%; } -DIV.daysView DIV[class~="appointment"].lasts62 +DIV#daysView DIV[class~="event"].lasts62 { height: 64.583333%; } -DIV.daysView DIV[class~="appointment"].lasts63 +DIV#daysView DIV[class~="event"].lasts63 { height: 65.625000%; } -DIV.daysView DIV[class~="appointment"].lasts64 +DIV#daysView DIV[class~="event"].lasts64 { height: 66.666667%; } -DIV.daysView DIV[class~="appointment"].lasts65 +DIV#daysView DIV[class~="event"].lasts65 { height: 67.708333%; } -DIV.daysView DIV[class~="appointment"].lasts66 +DIV#daysView DIV[class~="event"].lasts66 { height: 68.750000%; } -DIV.daysView DIV[class~="appointment"].lasts67 +DIV#daysView DIV[class~="event"].lasts67 { height: 69.791667%; } -DIV.daysView DIV[class~="appointment"].lasts68 +DIV#daysView DIV[class~="event"].lasts68 { height: 70.833333%; } -DIV.daysView DIV[class~="appointment"].lasts69 +DIV#daysView DIV[class~="event"].lasts69 { height: 71.875000%; } -DIV.daysView DIV[class~="appointment"].lasts70 +DIV#daysView DIV[class~="event"].lasts70 { height: 72.916667%; } -DIV.daysView DIV[class~="appointment"].lasts71 +DIV#daysView DIV[class~="event"].lasts71 { height: 73.958333%; } -DIV.daysView DIV[class~="appointment"].lasts72 +DIV#daysView DIV[class~="event"].lasts72 { height: 75.000000%; } -DIV.daysView DIV[class~="appointment"].lasts73 +DIV#daysView DIV[class~="event"].lasts73 { height: 76.041667%; } -DIV.daysView DIV[class~="appointment"].lasts74 +DIV#daysView DIV[class~="event"].lasts74 { height: 77.083333%; } -DIV.daysView DIV[class~="appointment"].lasts75 +DIV#daysView DIV[class~="event"].lasts75 { height: 78.125000%; } -DIV.daysView DIV[class~="appointment"].lasts76 +DIV#daysView DIV[class~="event"].lasts76 { height: 79.166667%; } -DIV.daysView DIV[class~="appointment"].lasts77 +DIV#daysView DIV[class~="event"].lasts77 { height: 80.208333%; } -DIV.daysView DIV[class~="appointment"].lasts78 +DIV#daysView DIV[class~="event"].lasts78 { height: 81.250000%; } -DIV.daysView DIV[class~="appointment"].lasts79 +DIV#daysView DIV[class~="event"].lasts79 { height: 82.291667%; } -DIV.daysView DIV[class~="appointment"].lasts80 +DIV#daysView DIV[class~="event"].lasts80 { height: 83.333333%; } -DIV.daysView DIV[class~="appointment"].lasts81 +DIV#daysView DIV[class~="event"].lasts81 { height: 84.375000%; } -DIV.daysView DIV[class~="appointment"].lasts82 +DIV#daysView DIV[class~="event"].lasts82 { height: 85.416667%; } -DIV.daysView DIV[class~="appointment"].lasts83 +DIV#daysView DIV[class~="event"].lasts83 { height: 86.458333%; } -DIV.daysView DIV[class~="appointment"].lasts84 +DIV#daysView DIV[class~="event"].lasts84 { height: 87.500000%; } -DIV.daysView DIV[class~="appointment"].lasts85 +DIV#daysView DIV[class~="event"].lasts85 { height: 88.541667%; } -DIV.daysView DIV[class~="appointment"].lasts86 +DIV#daysView DIV[class~="event"].lasts86 { height: 89.583333%; } -DIV.daysView DIV[class~="appointment"].lasts87 +DIV#daysView DIV[class~="event"].lasts87 { height: 90.625000%; } -DIV.daysView DIV[class~="appointment"].lasts88 +DIV#daysView DIV[class~="event"].lasts88 { height: 91.666667%; } -DIV.daysView DIV[class~="appointment"].lasts89 +DIV#daysView DIV[class~="event"].lasts89 { height: 92.708333%; } -DIV.daysView DIV[class~="appointment"].lasts90 +DIV#daysView DIV[class~="event"].lasts90 { height: 93.750000%; } -DIV.daysView DIV[class~="appointment"].lasts91 +DIV#daysView DIV[class~="event"].lasts91 { height: 94.791667%; } -DIV.daysView DIV[class~="appointment"].lasts92 +DIV#daysView DIV[class~="event"].lasts92 { height: 95.833333%; } -DIV.daysView DIV[class~="appointment"].lasts93 +DIV#daysView DIV[class~="event"].lasts93 { height: 96.875000%; } -DIV.daysView DIV[class~="appointment"].lasts94 +DIV#daysView DIV[class~="event"].lasts94 { height: 97.916667%; } -DIV.daysView DIV[class~="appointment"].lasts95 +DIV#daysView DIV[class~="event"].lasts95 { height: 98.958333%; } -DIV.daysView DIV[class~="appointment"].lasts96 +DIV#daysView DIV[class~="event"].lasts96 { height: 100.000000%; } diff --git a/UI/WebServerResources/SchedulerUI.js b/UI/WebServerResources/SchedulerUI.js index 5ca05b18..2f717ac7 100644 --- a/UI/WebServerResources/SchedulerUI.js +++ b/UI/WebServerResources/SchedulerUI.js @@ -23,7 +23,7 @@ var usersRightsWindowHeight = 250; var usersRightsWindowWidth = 502; function newEvent(sender, type) { - var day = sender.getAttribute("day"); + var day = sender.day; if (!day) day = currentDay; @@ -32,7 +32,9 @@ function newEvent(sender, type) { && currentView == "multicolumndayview" && type == "event") user = sender.parentNode.parentNode.getAttribute("user"); - var hour = sender.getAttribute("hour"); + var hour = sender.hour; + if (!hour) + hour = sender.getAttribute("hour"); var urlstr = UserFolderURL + "../" + user + "/Calendar/new" + type; var params = new Array(); if (day) @@ -62,8 +64,8 @@ function _editEventId(id, owner) { urlBase += "Calendar/" var urlstr = urlBase + id + "/edit"; - - var win = window.open(urlstr, "SOGo_edit_" + id, + var targetname = "SOGo_edit_" + id; + var win = window.open(urlstr, "_blank", "width=490,height=470,resizable=0"); win.focus(); } @@ -74,10 +76,10 @@ function editEvent() { for (var i = 0; i < nodes.length; i++) _editEventId(nodes[i].getAttribute("id"), - nodes[i].getAttribute("owner")); + nodes[i].owner); } else if (selectedCalendarCell) { - _editEventId(selectedCalendarCell.getAttribute("aptCName"), - selectedCalendarCell.getAttribute("owner")); + _editEventId(selectedCalendarCell[0].cname, + selectedCalendarCell[0].owner); } return false; /* stop following the link */ @@ -102,7 +104,7 @@ function deleteEvent() { if (listOfSelection == $("tasksList")) label = labels["taskDeleteConfirmation"].decodeEntities(); else - label = labels["appointmentDeleteConfirmation"].decodeEntities(); + label = labels["eventDeleteConfirmation"].decodeEntities(); if (confirm(label)) { if (document.deleteEventAjaxRequest) { @@ -113,12 +115,12 @@ function deleteEvent() { var owners = new Array(); for (var i = 0; i < nodes.length; i++) { - var owner = nodes[i].getAttribute("owner"); + var owner = nodes[i].owner; if (!sortedNodes[owner]) { sortedNodes[owner] = new Array(); owners.push(owner); } - sortedNodes[owner].push(nodes[i].getAttribute("id")); + sortedNodes[owner].push(nodes[i].cname); } for (var i = 0; i < owners.length; i++) { ownersOfEventsToDelete.push(owners[i]); @@ -129,14 +131,14 @@ function deleteEvent() { } } else if (selectedCalendarCell) { - var label = labels["appointmentDeleteConfirmation"].decodeEntities(); + var label = labels["eventDeleteConfirmation"].decodeEntities(); if (confirm(label)) { if (document.deleteEventAjaxRequest) { document.deleteEventAjaxRequest.aborted = true; document.deleteEventAjaxRequest.abort(); } - eventsToDelete.push([selectedCalendarCell.getAttribute("aptCName")]); - ownersOfEventsToDelete.push(selectedCalendarCell.getAttribute("owner")); + eventsToDelete.push([selectedCalendarCell[0].cname]); + ownersOfEventsToDelete.push(selectedCalendarCell[0].owner); _batchDeleteEvents(); } } @@ -177,12 +179,12 @@ function modifyEventCallback(http) { if (queryParameters["mail-invitation"].toLowerCase() == "yes") closeInvitationWindow(); else { - window.opener.setTimeout("refreshAppointmentsAndDisplay();", 100); + window.opener.setTimeout("refreshEventsAndDisplay();", 100); window.setTimeout("window.close();", 100); } } else { - log("showing alert..."); +// log("showing alert..."); window.alert(labels["eventPartStatModificationError"]); } document.modifyEventAjaxRequest = null; @@ -202,46 +204,36 @@ function deleteEventCallback(http) { _batchDeleteEvents(); else { document.deleteEventAjaxRequest = null; - refreshAppointments(); + refreshEvents(); refreshTasks(); changeCalendarDisplay(); } } else - log ("ajax fuckage"); + log ("deleteEventCallback Ajax error"); } -function editDoubleClickedEvent(node) { - _editEventId(node.getAttribute("id"), - node.getAttribute("owner")); - - return false; +function editDoubleClickedEvent(event) { + _editEventId(this.cname, this.owner); + + preventDefault(event); + event.cancelBubble = true; } function onSelectAll() { - var list = $("appointmentsList"); - list.selectRowsMatchingClass("appointmentRow"); + var list = $("eventsList"); + list.selectRowsMatchingClass("eventRow"); return false; } -function displayAppointment(event) { - _editEventId(this.getAttribute("aptCName"), - this.getAttribute("owner")); - - preventDefault(event); - event.stopPropagation(); - event.cancelBubble = true; - event.returnValue = false; -} - function onDaySelect(node) { - var day = node.getAttribute("day"); + var day = node.getAttribute('day'); var needRefresh = (listFilter == 'view_selectedday' && day != currentDay); - var td = node.getParentWithTagName("td"); - var table = td.getParentWithTagName("table"); + var td = $(node).getParentWithTagName("td"); + var table = $(td).getParentWithTagName("table"); // log ("table.selected: " + table.selected); @@ -253,7 +245,7 @@ function onDaySelect(node) { changeCalendarDisplay( { "day": day } ); if (needRefresh) - refreshAppointments(); + refreshEvents(); return false; } @@ -299,25 +291,62 @@ function dateSelectorCallback(http) { cachedDateSelectors[http.callbackData] = content; } else - log ("ajax fuckage"); + log ("dateSelectorCallback Ajax error"); } -function appointmentsListCallback(http) { - var div = $("appointmentsListView"); - +function eventsListCallback(http) { if (http.readyState == 4 && http.status == 200) { - document.appointmentsListAjaxRequest = null; - div.innerHTML = http.responseText; + var div = $("eventsListView"); + + document.eventsListAjaxRequest = null; + var table = $("eventsList").tBodies[0]; var params = parseQueryParameters(http.callbackData); sortKey = params["sort"]; sortOrder = params["desc"]; - var list = $("appointmentsList"); - Event.observe(list, "selectionchange", onAppointmentsSelectionChange.bindAsEventListener(list), true); configureSortableTableHeaders(); + + var data = http.responseText.evalJSON(true); + for (var i = 0; i < data.length; i++) { + var row = document.createElement("tr"); + table.appendChild(row); + $(row).addClassName("eventRow"); + row.setAttribute("id", data[i][0]); + row.cname = data[i][0]; + row.owner = data[i][1]; + + var startDate = new Date(); + startDate.setTime(data[i][4] * 1000); + row.day = startDate.getDayString(); + row.hour = startDate.getHourString(); + Event.observe(row, "click", onEventClick.bindAsEventListener(row)); + Event.observe(row, "dblclick", editDoubleClickedEvent.bindAsEventListener(row)); + Event.observe(row, "contextmenu", + onEventContextMenu.bindAsEventListener(row)); + + var td = document.createElement("td"); + row.appendChild(td); + Event.observe(td, "mousedown", listRowMouseDownHandler, true); + td.appendChild(document.createTextNode(data[i][3])); + + td = document.createElement("td"); + row.appendChild(td); + Event.observe(td, "mousedown", listRowMouseDownHandler, true); + td.appendChild(document.createTextNode(data[i][8])); + + td = document.createElement("td"); + row.appendChild(td); + Event.observe(td, "mousedown", listRowMouseDownHandler, true); + td.appendChild(document.createTextNode(data[i][9])); + + td = document.createElement("td"); + row.appendChild(td); + Event.observe(td, "mousedown", listRowMouseDownHandler, true); + td.appendChild(document.createTextNode(data[i][6])); + } } else - log ("ajax fuckage"); + log ("eventsListCallback Ajax error"); } function tasksListCallback(http) { @@ -327,19 +356,46 @@ function tasksListCallback(http) { && http.status == 200) { document.tasksListAjaxRequest = null; var list = $("tasksList"); - var scroll = list.scrollTop; - div.innerHTML = http.responseText; - list = $("tasksList"); - Event.observe(list, "selectionchange", onTasksSelectionChange.bindAsEventListener(list), true); - list.scrollTop = scroll; + var data = http.responseText.evalJSON(true); + + for (var i = 0; i < data.length; i++) { + //log(i + " = " + data[i][3]); + var listItem = document.createElement("li"); + list.appendChild(listItem); + Event.observe(listItem, "mousedown", listRowMouseDownHandler); // causes problem with Safari + Event.observe(listItem, "click", onRowClick); + Event.observe(listItem, "dblclick", editDoubleClickedEvent.bindAsEventListener(listItem)); + listItem.setAttribute("id", data[i][0]); + $(listItem).addClassName(data[i][5]); + var owner = data[i][1]; + listItem.owner = owner; + $(listItem).addClassName("ownerIs" + owner); + listItem.cname = data[i][0]; + var input = document.createElement("input"); + input.setAttribute("type", "checkbox"); + listItem.appendChild(input); + Event.observe(input, "click", updateTaskStatus.bindAsEventListener(input), true); + input.setAttribute("value", "1"); + if (data[i][2] == 1) + input.setAttribute("checked", "checked"); + $(input).addClassName("checkBox"); + listItem.appendChild(document.createTextNode(data[i][3])); + } + + list.scrollTop = list.previousScroll; + if (http.callbackData) { var selectedNodesId = http.callbackData; - for (var i = 0; i < selectedNodesId.length; i++) + for (var i = 0; i < selectedNodesId.length; i++) { +// log(selectedNodesId[i] + " (" + i + ") is selected"); $(selectedNodesId[i]).select(); + } } + else + log ("tasksListCallback: no data"); } else - log ("ajax fuckage"); + log ("tasksListCallback Ajax error"); } function restoreCurrentDaySelection(div) { @@ -348,14 +404,14 @@ function restoreCurrentDaySelection(div) { var i = 9; while (!day && i < elements.length) { - day = elements[i].getAttribute("day"); + day = elements[i].day; i++; } if (day && day.substr(0, 6) == currentDay.substr(0, 6)) { for (i = 0; i < elements.length; i++) { - day = elements[i].getAttribute("day"); + day = elements[i].day; if (day && day == currentDay) { var td = elements[i].getParentWithTagName("td"); if (document.selectedDate) @@ -421,11 +477,9 @@ function changeCalendarDisplay(time, newView) { document.dayDisplayAjaxRequest.aborted = true; document.dayDisplayAjaxRequest.abort(); } - document.dayDisplayAjaxRequest = triggerAjaxRequest(url, - calendarDisplayCallback, - { "view": newView, - "day": day, - "hour": hour }); + document.dayDisplayAjaxRequest + = triggerAjaxRequest(url, calendarDisplayCallback, + { "view": newView, "day": day, "hour": hour }); return false; } @@ -468,9 +522,10 @@ function scrollDayView(hour) { rowNumber = 8; var daysView = $("daysView"); - var hours = $(daysView.childNodesWithTag("div")[0]).childNodesWithTag("div"); + var hours = + $(daysView.childNodesWithTag("div")[0]).childNodesWithTag("div"); if (hours.length > 0) - daysView.parentNode.scrollTop = hours[rowNumber + 1].offsetTop; + daysView.scrollTop = hours[rowNumber].offsetTop; } function onClickableCellsDblClick(event) { @@ -480,10 +535,217 @@ function onClickableCellsDblClick(event) { event.returnValue = false; } +function refreshCalendarEvents() { + var todayDate = new Date(); + var sd; + var ed; + if (currentView == "dayview") { + if (currentDay) + sd = currentDay; + else + sd = todayDate.getDayString(); + ed = sd; + } + else if (currentView == "weekview") { + var startDate; + if (currentDay) + startDate = currentDay.asDate(); + else + startDate = todayDate; + startDate = startDate.beginOfWeek(); + sd = startDate.getDayString(); + var endDate = new Date(); + endDate.setTime(startDate.getTime()); + endDate.addDays(6); + ed = endDate.getDayString(); + } + else { + var monthDate; + if (currentDay) + monthDate = currentDay.asDate(); + else + monthDate = todayDate; + monthDate.setDate(1); + sd = monthDate.beginOfWeek().getDayString(); + + var lastMonthDate = new Date(); + lastMonthDate.setTime(monthDate.getTime()); + lastMonthDate.setMonth(monthDate.getMonth() + 1); + lastMonthDate.addDays(-1); + ed = lastMonthDate.endOfWeek().getDayString(); + } + if (document.refreshCalendarEventsAjaxRequest) { + document.refreshCalendarEventsAjaxRequest.aborted = true; + document.refreshCalendarEventsAjaxRequest.abort(); + } + var url = ApplicationBaseURL + "eventslist?sd=" + sd + "&ed=" + ed; + document.refreshCalendarEventsAjaxRequest + = triggerAjaxRequest(url, refreshCalendarEventsCallback, + {"startDate": sd, "endDate": ed}); +} + +function refreshCalendarEventsCallback(http) { + if (http.readyState == 4 + && http.status == 200) { + var data = http.responseText.evalJSON(true); +// log("refresh calendar events: " + data.length); + for (var i = 0; i < data.length; i++) + drawCalendarEvent(data[i], + http.callbackData["startDate"], + http.callbackData["endDate"]); + } + else + log("AJAX error when refreshing calendar events"); +} + +function drawCalendarEvent(eventData, sd, ed) { + var viewStartDate = sd.asDate(); + var viewEndDate = ed.asDate(); + + var startDate = new Date(); + startDate.setTime(eventData[4] * 1000); + var endDate = new Date(); + endDate.setTime(eventData[5] * 1000); + + var days = startDate.daysUpTo(endDate); + + var divs = new Array(); + + var title = eventData[3]; +// 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.getHours() * 4 + + Math.floor(startDate.getMinutes() / 15)); + starts = quarters; + startHour = startDate.getDisplayHoursString(); + endHour = endDate.getDisplayHoursString(); + } + else + starts = 0; + + var ends; + var lasts; + if (i == days.length - 1) { + var quarters = (endDate.getHours() * 4 + + Math.ceil(endDate.getMinutes() / 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; + 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); + } +} + +function newEventDIV(cname, owner, starts, lasts, + startHour, endHour, title) { + var eventDiv = document.createElement("div"); + eventDiv.cname = cname; + eventDiv.owner = owner; + eventDiv.addClassName("event"); + eventDiv.addClassName("starts" + starts); + eventDiv.addClassName("lasts" + lasts); + 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("ownerIs" + owner); + + 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(title)); + + Event.observe(eventDiv, "mousedown", listRowMouseDownHandler); + Event.observe(eventDiv, "click", + onCalendarSelectEvent.bindAsEventListener(eventDiv)); + Event.observe(eventDiv, "dblclick", + editDoubleClickedEvent.bindAsEventListener(eventDiv)); + + return eventDiv; +} + function calendarDisplayCallback(http) { var div = $("calendarView"); - //log ("calendarDisplayCallback: " + div); if (http.readyState == 4 && http.status == 200) { document.dayDisplayAjaxRequest = null; @@ -502,30 +764,36 @@ function calendarDisplayCallback(http) { scrollDayView(hour); contentView = $("daysView"); } - var appointments = document.getElementsByClassName("appointment", contentView); - for (var i = 0; i < appointments.length; i++) { - Event.observe(appointments[i], "mousedown", listRowMouseDownHandler); - Event.observe(appointments[i], "click", onCalendarSelectAppointment.bindAsEventListener(appointments[i])); - Event.observe(appointments[i], "dblclick", displayAppointment.bindAsEventListener(appointments[i])); - } + refreshCalendarEvents(); var days = document.getElementsByClassName("day", contentView); if (currentView == "monthview") for (var i = 0; i < days.length; i++) { Event.observe(days[i], "click", onCalendarSelectDay.bindAsEventListener(days[i])); Event.observe(days[i], "dblclick", onClickableCellsDblClick.bindAsEventListener(days[i])); } - else - for (var i = 0; i < days.length; i++) { - Event.observe(days[i], "click", onCalendarSelectDay.bindAsEventListener(days[i])); - var clickableCells = document.getElementsByClassName("clickableHourCell", - days[i]); - for (var j = 0; j < clickableCells.length; j++) - Event.observe(clickableCells[j], "dblclick", onClickableCellsDblClick.bindAsEventListener(clickableCells[j])); - } -// log("cbtest1"); + else { + var headerDivs = $("calendarHeader").childNodesWithTag("div"); + var headerDaysLabels = document.getElementsByClassName("day", headerDivs[0]); + var headerDays = document.getElementsByClassName("day", headerDivs[1]); + for (var i = 0; i < days.length; i++) { + headerDays[i].hour = "allday"; + Event.observe(headerDaysLabels[i], "mousedown", listRowMouseDownHandler); + Event.observe(headerDays[i], "click", + onCalendarSelectDay.bindAsEventListener(days[i])); + Event.observe(headerDays[i], "dblclick", + onClickableCellsDblClick.bindAsEventListener(headerDays[i])); + Event.observe(days[i], "click", + onCalendarSelectDay.bindAsEventListener(days[i])); + var clickableCells = document.getElementsByClassName("clickableHourCell", + days[i]); + for (var j = 0; j < clickableCells.length; j++) + Event.observe(clickableCells[j], "dblclick", + onClickableCellsDblClick.bindAsEventListener(clickableCells[j])); + } + } } else - log ("ajax fuckage"); + log ("calendarDisplayCallback Ajax error (" + http.readyState + "/" + http.status + ")"); } function assignCalendar(name) { @@ -548,27 +816,27 @@ function popupCalendar(node) { return false; } -function onAppointmentContextMenu(event, element) { - var topNode = $("appointmentsList"); +function onEventContextMenu(event) { + var topNode = $("eventsList"); // log(topNode); - var menu = $("appointmentsListMenu"); + var menu = $("eventsListMenu"); - Event.observe(menu, "hideMenu", onAppointmentContextMenuHide); - popupMenu(event, "appointmentsListMenu", element); + Event.observe(menu, "hideMenu", onEventContextMenuHide); + popupMenu(event, "eventsListMenu", this); - var topNode = $("appointmentsList"); + var topNode = $("eventsList"); var selectedNodes = topNode.getSelectedRows(); topNode.menuSelectedRows = selectedNodes; for (var i = 0; i < selectedNodes.length; i++) selectedNodes[i].deselect(); - topNode.menuSelectedEntry = element; - element.select(); + topNode.menuSelectedEntry = this; + this.select(); } -function onAppointmentContextMenuHide(event) { - var topNode = $("appointmentsList"); +function onEventContextMenuHide(event) { + var topNode = $("eventsList"); if (topNode.menuSelectedEntry) { topNode.menuSelectedEntry.deselect(); @@ -584,7 +852,7 @@ function onAppointmentContextMenuHide(event) { } } -function onAppointmentsSelectionChange() { +function onEventsSelectionChange() { listOfSelection = this; this.removeClassName("_unfocused"); $("tasksList").addClassName("_unfocused"); @@ -593,17 +861,21 @@ function onAppointmentsSelectionChange() { function onTasksSelectionChange() { listOfSelection = this; this.removeClassName("_unfocused"); - $("appointmentsList").addClassName("_unfocused"); + $("eventsList").addClassName("_unfocused"); } -function _loadAppointmentHref(href) { - if (document.appointmentsListAjaxRequest) { - document.appointmentsListAjaxRequest.aborted = true; - document.appointmentsListAjaxRequest.abort(); +function _loadEventHref(href) { + if (document.eventsListAjaxRequest) { + document.eventsListAjaxRequest.aborted = true; + document.eventsListAjaxRequest.abort(); } var url = ApplicationBaseURL + href; - document.appointmentsListAjaxRequest - = triggerAjaxRequest(url, appointmentsListCallback, href); + document.eventsListAjaxRequest + = triggerAjaxRequest(url, eventsListCallback, href); + + var table = $("eventsList").tBodies[0]; + while (table.rows.length > 1) + table.removeChild(table.rows[1]); return false; } @@ -615,33 +887,42 @@ function _loadTasksHref(href) { } url = ApplicationBaseURL + href; - var selectedIds = $("tasksList").getSelectedNodesId(); + var tasksList = $("tasksList"); + var selectedIds; + if (tasksList) + selectedIds = tasksList.getSelectedNodesId(); + else + selectedIds = null; document.tasksListAjaxRequest = triggerAjaxRequest(url, tasksListCallback, selectedIds); - return false; + tasksList.previousScroll = tasksList.scrollTop; + while (tasksList.childNodes.length) + tasksList.removeChild(tasksList.childNodes[0]); + + return true; } function onHeaderClick(event) { // log("onHeaderClick: " + this.link); - _loadAppointmentHref(this.link); + _loadEventHref(this.link); preventDefault(event); } -function refreshAppointments() { - return _loadAppointmentHref("aptlist?desc=" + sortOrder - + "&sort=" + sortKey - + "&day=" + currentDay - + "&filterpopup=" + listFilter); +function refreshEvents() { + return _loadEventHref("eventslist?desc=" + sortOrder + + "&sort=" + sortKey + + "&day=" + currentDay + + "&filterpopup=" + listFilter); } function refreshTasks() { return _loadTasksHref("taskslist?show-completed=" + showCompletedTasks); } -function refreshAppointmentsAndDisplay() { - refreshAppointments(); +function refreshEventsAndDisplay() { + refreshEvents(); changeCalendarDisplay(); } @@ -651,14 +932,14 @@ function onListFilterChange() { listFilter = node.value; // log ("listFilter = " + listFilter); - return refreshAppointments(); + return refreshEvents(); } -function onAppointmentClick(event) { +function onEventClick(event) { var target = getTarget(event); var node = target.getParentWithTagName("tr"); - var day = node.getAttribute("day"); - var hour = node.getAttribute("hour"); + var day = node.day; + var hour = node.hour; changeCalendarDisplay( { "day": day, "hour": hour} ); changeDateSelectorDisplay(day); @@ -726,8 +1007,6 @@ function onMonthMenuItemClick(event) { var year = '' + $("yearLabel").innerHTML; changeDateSelectorDisplay(year + month + "01", true); - -// event.cancelBubble(); } function onYearMenuItemClick(event) { @@ -743,16 +1022,18 @@ function onSearchFormSubmit() { return false; } -function onCalendarSelectAppointment() { - var list = $("appointmentsList"); +function onCalendarSelectEvent() { + var list = $("eventsList"); list.deselectAll(); - var aptCName = this.getAttribute("aptCName"); if (selectedCalendarCell) - selectedCalendarCell.deselect(); - this.select(); - selectedCalendarCell = this; - var row = $(aptCName); + for (var i = 0; i < selectedCalendarCell.length; i++) + selectedCalendarCell[i].deselect(); + + for (var i = 0; i < this.siblings.length; i++) + this.siblings[i].select(); + selectedCalendarCell = this.siblings; + var row = $(this.cname); if (row) { var div = row.parentNode.parentNode.parentNode; div.scrollTop = row.offsetTop - (div.offsetHeight / 2); @@ -763,7 +1044,7 @@ function onCalendarSelectAppointment() { function onCalendarSelectDay(event) { var day; if (currentView == "multicolumndayview") - day = this.parentNode.getAttribute("day"); + day = this.getAttribute("day"); else day = this.getAttribute("day"); var needRefresh = (listFilter == 'view_selectedday' @@ -781,17 +1062,26 @@ function onCalendarSelectDay(event) { } if (needRefresh) - refreshAppointments(); + refreshEvents(); } function changeWeekCalendarDisplayOfSelectedDay(node) { var days = document.getElementsByClassName("day", node.parentNode); + var headerDiv = $("calendarHeader").childNodesWithTag("div")[1]; + var headerDays = document.getElementsByClassName("day", headerDiv); +// log ("days: " + days.length + "; headerDays: " + headerDays.length); for (var i = 0; i < days.length; i++) - if (days[i] != node) - days[i].removeClassName("selectedDay"); - - node.addClassName("selectedDay"); + if (days[i] != node) { +// log("unselect day : " + i); + headerDays[i].removeClassName("selectedDay"); + days[i].removeClassName("selectedDay"); + } + else { +// log("selected day : " + i); + headerDays[i].addClassName("selectedDay"); + days[i].addClassName("selectedDay"); + } } function findMonthCalendarSelectedCell(daysContainer) { @@ -821,28 +1111,30 @@ function changeMonthCalendarDisplayOfSelectedDay(node) { node.addClassName("selectedDay"); } -function onShowCompletedTasks(node) { - showCompletedTasks = (node.checked ? 1 : 0); +function onShowCompletedTasks(event) { + showCompletedTasks = (this.checked ? 1 : 0); - return refreshTasks(); + return refreshTasks(); } -function updateTaskStatus(node) { - var taskId = node.parentNode.getAttribute("id"); - var taskOwner = node.parentNode.getAttribute("owner"); - var newStatus = (node.checked ? 1 : 0); -// log ("update task status: " + taskId); - +function updateTaskStatus(event) { + var taskId = this.parentNode.getAttribute("id"); + var taskOwner = this.parentNode.owner; + var newStatus = (this.checked ? 1 : 0); var http = createHTTPClient(); - - url = (UserFolderURL + "../" + taskOwner + "/Calendar/" - + taskId + "/changeStatus?status=" + newStatus); + +// log("update task status: " + taskId + " to " + this.checked); + event.cancelBubble = true; + + url = (UserFolderURL + "../" + taskOwner + + "/Calendar/" + taskId + + "/changeStatus?status=" + newStatus); if (http) { // log ("url: " + url); // TODO: add parameter to signal that we are only interested in OK + http.open("POST", url, false /* not async */); http.url = url; - http.open("GET", url, false /* not async */); http.send(""); if (http.status == 200) refreshTasks(); @@ -879,14 +1171,15 @@ function updateCalendarStatus(event) { var folderID = this.parentNode.getAttribute("id"); var urlstr = URLForFolderID(folderID); if (this.checked) - urlstr += "/activateFolder"; + urlstr += "/activateFolder"; else - urlstr += "/deactivateFolder"; + urlstr += "/deactivateFolder"; + //log("updateCalendarStatus: ajax request = " + urlstr + ", folderID = " + folderID); triggerAjaxRequest(urlstr, calendarStatusCallback, folderID); } else { updateCalendarsList(); - refreshAppointments(); + refreshEvents(); refreshTasks(); changeCalendarDisplay(); } @@ -895,18 +1188,20 @@ function updateCalendarStatus(event) { } function calendarStatusCallback(http) { - if (http.readyState == 4) { - if (http.status == 204) { - refreshAppointments(); + if (http.readyState == 4) { + if (isHttpStatus204(http.status)) { + refreshEvents(); refreshTasks(); changeCalendarDisplay(); } else { - var folder = $(http.callbackData); + var folder = $(http.callbackData); var input = folder.childNodesWithTag("input")[0]; - input.checked = (!input.checked); + input.checked = (!input.checked); } } + else + log("calendarStatusCallback Ajax error"); } function calendarEntryCallback(http) { @@ -987,7 +1282,7 @@ function getMenus() { dateMenu.push(onYearMenuItemClick); menus["yearListMenu"] = dateMenu; - menus["appointmentsListMenu"] = new Array(onMenuNewEventClick, "-", + menus["eventsListMenu"] = new Array(onMenuNewEventClick, "-", onMenuNewTaskClick, editEvent, deleteEvent, "-", onSelectAll, "-", @@ -1023,7 +1318,7 @@ function configureDragHandles() { handle = $("rightDragHandle"); if (handle) { handle.addInterface(SOGoDragHandlesInterface); - handle.upperBlock=$("appointmentsListView"); + handle.upperBlock=$("eventsListView"); handle.lowerBlock=$("calendarView"); } } @@ -1036,8 +1331,8 @@ function initCalendarSelector() { var list = $("calendarList").childNodesWithTag("li"); for (var i = 0; i < list.length; i++) { var input = list[i].childNodesWithTag("input")[0]; - Event.observe(input, "change", updateCalendarStatus.bindAsEventListener(input)); - Event.observe(list[i], "mousedown", listRowMouseDownHandler); + Event.observe(input, "click", updateCalendarStatus.bindAsEventListener(input)); // not registered in IE? + //Event.observe(list[i], "mousedown", listRowMouseDownHandler, true); // problem with Safari Event.observe(list[i], "click", onRowClick); } @@ -1057,27 +1352,32 @@ function appendCalendar(folderName, folder) { var lis = calendarList.childNodesWithTag("li"); var color = indexColor(lis.length); log ("color: " + color); + var li = document.createElement("li"); - li.setAttribute("id", folder); - Event.observe(li, "mousedown", listRowMouseDownHandler); - Event.observe(li, "click", onRowClick); + calendarList.appendChild(li); + var checkBox = document.createElement("input"); - checkBox.addClassName("checkBox"); - checkBox.type = "checkbox"; - Event.observe(checkBox, "change", updateCalendarStatus); li.appendChild(checkBox); + li.appendChild(document.createTextNode(" ")); + var colorBox = document.createElement("div"); + li.appendChild(colorBox); + li.appendChild(document.createTextNode(" " + folderName)); colorBox.appendChild(document.createTextNode("OO")); + + li.setAttribute("id", folder); + Event.observe(li, "mousedown", listRowMouseDownHandler); + Event.observe(li, "click", onRowClick); + checkBox.addClassName("checkBox"); + checkBox.type = "checkbox"; + Event.observe(checkBox, "click", updateCalendarStatus.bindAsEventListener(checkBox)); + colorBox.addClassName("colorBox"); if (color) { colorBox.setStyle({ color: color, backgroundColor: color }); } - li.appendChild(colorBox); - li.appendChild(document.createTextNode(" " + folderName)); - - calendarList.appendChild(li); var contactId = folder.split(":")[0]; var styles = document.getElementsByTagName("style"); @@ -1126,10 +1426,30 @@ function configureSearchField() { Event.observe(searchValue, "keydown", onSearchKeyDown.bindAsEventListener(searchValue)); } +function configureLists() { + var list = $("tasksList"); + list.multiselect = true; + Event.observe(list, "mousedown", + onTasksSelectionChange.bindAsEventListener(list)); + + var input = $("showHideCompletedTasks"); + Event.observe(input, "click", + onShowCompletedTasks.bindAsEventListener(input)); + + list = $("eventsList"); + list.multiselect = true; + Event.observe(list, "mousedown", + onEventsSelectionChange.bindAsEventListener(list)); + var div = list.parentNode; + Event.observe(div, "contextmenu", + onEventContextMenu.bindAsEventListener(div)); +} + function initCalendars() { if (!document.body.hasClassName("popup")) { initCalendarSelector(); configureSearchField(); + configureLists(); var selector = $("calendarSelector"); if (selector) selector.attachMenu("calendarsMenu"); diff --git a/UI/WebServerResources/UIxAppointmentEditor.js b/UI/WebServerResources/UIxAppointmentEditor.js index 9995a1ba..91c58eca 100644 --- a/UI/WebServerResources/UIxAppointmentEditor.js +++ b/UI/WebServerResources/UIxAppointmentEditor.js @@ -181,7 +181,7 @@ function endDayAsShortString() { return $('endTime_date').valueAsShortDateString(); } -this._getDate = function(which) { +function _getDate(which) { var date = window.timeWidgets[which]['date'].valueAsDate(); date.setHours( window.timeWidgets[which]['hour'].value ); date.setMinutes( window.timeWidgets[which]['minute'].value ); @@ -189,7 +189,7 @@ this._getDate = function(which) { return date; } -this._getShadowDate = function(which) { +function _getShadowDate(which) { var date = window.timeWidgets[which]['date'].getAttribute("shadow-value").asDate(); var intValue = parseInt(window.timeWidgets[which]['hour'].getAttribute("shadow-value")); date.setHours(intValue); @@ -200,23 +200,23 @@ this._getShadowDate = function(which) { return date; } -this.getStartDate = function() { +function getStartDate() { return this._getDate('start'); } -this.getEndDate = function() { +function getEndDate() { return this._getDate('end'); } -this.getShadowStartDate = function() { +function getShadowStartDate() { return this._getShadowDate('start'); } -this.getShadowEndDate = function() { +function getShadowEndDate() { return this._getShadowDate('end'); } -this._setDate = function(which, newDate) { +function _setDate(which, newDate) { window.timeWidgets[which]['date'].setValueAsDate(newDate); window.timeWidgets[which]['hour'].value = newDate.getHours(); var minutes = newDate.getMinutes(); @@ -225,16 +225,16 @@ this._setDate = function(which, newDate) { window.timeWidgets[which]['minute'].value = minutes; } -this.setStartDate = function(newStartDate) { +function setStartDate(newStartDate) { this._setDate('start', newStartDate); } -this.setEndDate = function(newEndDate) { +function setEndDate(newEndDate) { // window.alert(newEndDate); this._setDate('end', newEndDate); } -this.onAdjustEndTime = function(event) { +function onAdjustEndTime(event) { var dateDelta = (window.getStartDate().valueOf() - window.getShadowStartDate().valueOf()); // window.alert(window.getEndDate().valueOf() + ' ' + dateDelta); @@ -245,10 +245,39 @@ this.onAdjustEndTime = function(event) { window.timeWidgets['start']['minute'].updateShadowValue(); } -this.initTimeWidgets = function (widgets) { +function onAllDayChanged(event) { + for (var type in window.timeWidgets) { + window.timeWidgets[type]['hour'].disabled = this.checked; + window.timeWidgets[type]['minute'].disabled = this.checked; + } +} + +function initTimeWidgets(widgets) { this.timeWidgets = widgets; Event.observe(widgets['start']['date'], "change", this.onAdjustEndTime, false); Event.observe(widgets['start']['hour'], "change", this.onAdjustEndTime, false); Event.observe(widgets['start']['minute'], "change", this.onAdjustEndTime, false); + + var allDayLabel = $("allDay"); + var input = $(allDayLabel).childNodesWithTag("input")[0]; + Event.observe(input, "change", onAllDayChanged.bindAsEventListener(input)); + if (input.checked) { + for (var type in widgets) { + widgets[type]['hour'].disabled = true; + widgets[type]['minute'].disabled = true; + } + } } + +function onAppointmentEditorLoad() { + var widgets = {'start': {'date': $("startTime_date"), + 'hour': $("startTime_time_hour"), + 'minute': $("startTime_time_minute")}, + 'end': {'date': $("endTime_date"), + 'hour': $("endTime_time_hour"), + 'minute': $("endTime_time_minute")}}; + initTimeWidgets(widgets); +} + +addEvent(window, 'load', onAppointmentEditorLoad); diff --git a/UI/WebServerResources/UIxComponentEditor.js b/UI/WebServerResources/UIxComponentEditor.js index 32347213..c14f0f19 100644 --- a/UI/WebServerResources/UIxComponentEditor.js +++ b/UI/WebServerResources/UIxComponentEditor.js @@ -1,6 +1,6 @@ function onPopupAttendeesWindow(event) { if (event) - event.preventDefault(); + preventDefault(event); window.open(ApplicationBaseURL + "editAttendees", null, "width=803,height=573"); @@ -15,7 +15,7 @@ function onSelectPrivacy(event) { function onPopupUrlWindow(event) { if (event) - event.preventDefault(); + preventDefault(event); var urlInput = document.getElementById("url"); var newUrl = window.prompt(labels["Target:"].decodeEntities(), urlInput.value); @@ -99,7 +99,7 @@ function initializeAttendeesHref() { var attendeesLabel = $("attendeesLabel"); var attendeesNames = $("attendeesNames"); - attendeesHref.addEventListener("click", onPopupAttendeesWindow, false); + Event.observe(attendeesHref, "click", onPopupAttendeesWindow, false); if (attendeesNames.value.length > 0) { attendeesHref.setStyle({ textDecoration: "underline", color: "#00f" }); attendeesHref.appendChild(document.createTextNode(attendeesNames.value)); @@ -112,7 +112,7 @@ function initializeDocumentHref() { var documentLabel = $("documentLabel"); var documentUrl = $("url"); - documentHref.addEventListener("click", onPopupDocumentWindow, false); + Event.observe(documentHref, "click", onPopupDocumentWindow, false); documentHref.setStyle({ textDecoration: "underline", color: "#00f" }); if (documentUrl.value.length > 0) { documentHref.appendChild(document.createTextNode(documentUrl.value)); @@ -120,7 +120,7 @@ function initializeDocumentHref() { } var changeUrlButton = $("changeUrlButton"); - changeUrlButton.addEventListener("click", onPopupUrlWindow, false); + Event.observe(changeUrlButton, "click", onPopupUrlWindow, false); } function initializePrivacyMenu() { @@ -146,14 +146,19 @@ function onComponentEditorLoad(event) { initializeDocumentHref(); initializePrivacyMenu(); var list = $("calendarList"); - list.addEventListener("change", onChangeCalendar, false); - var onSelectionChangeEvent = document.createEvent("Event"); - onSelectionChangeEvent.initEvent("change", false, false); - list.dispatchEvent(onSelectionChangeEvent); + Event.observe(list, "change", onChangeCalendar.bindAsEventListener(list), false); + if (document.createEvent) { + var onSelectionChangeEvent = document.createEvent("Event"); + onSelectionChangeEvent.initEvent("change", false, false); + list.dispatchEvent(onSelectionChangeEvent); + } + else { + list.fireEvent("onchange"); // IE + } var menuItems = $("itemPrivacyList").childNodesWithTag("li"); for (var i = 0; i < menuItems.length; i++) - menuItems[i].addEventListener("mouseup", onMenuSetClassification, false); + Event.observe(menuItems[i], "mouseup", onMenuSetClassification.bindAsEventListener(menuItems[i]), false); } addEvent(window, 'load', onComponentEditorLoad); diff --git a/UI/WebServerResources/UIxMailEditor.css b/UI/WebServerResources/UIxMailEditor.css index 5bfb95e2..201b11d1 100644 --- a/UI/WebServerResources/UIxMailEditor.css +++ b/UI/WebServerResources/UIxMailEditor.css @@ -15,8 +15,7 @@ TABLE#compose_label } DIV#addressList -{ - height: 8em; +{ height: 8em; margin-bottom: .25em; overflow-y: auto; overflow-x: hidden; @@ -24,23 +23,20 @@ DIV#addressList DIV.addressListElement { margin: 0px; - margin-right: 8em; padding: 0px; } SPAN.headerField -{ display: block; - float: left; - line-height: 1.8em; +{ line-height: 1.8em; width: 5em; text-align: right; } -SPAN.headerInput > INPUT +SPAN.headerInput INPUT { width: 100%; padding-left: 24px; background-image: url('/SOGo.woa/WebServerResources/abcard.gif'); background-repeat: no-repeat; background-position: 2px center; - margin-right: -9em; } + margin-right: -12em; } DIV#subjectRow INPUT { background-image: none; @@ -85,9 +81,10 @@ div#compose_attachments_list -moz-border-left-colors: #9c9a94 #000 transparent; } -TEXTAREA +DIV.pageContent TEXTAREA { position: absolute; left: 0em; right: 0em; bottom: 0em; top: 17em; } + diff --git a/UI/WebServerResources/generic.css b/UI/WebServerResources/generic.css index 33953e89..2ca3eef8 100644 --- a/UI/WebServerResources/generic.css +++ b/UI/WebServerResources/generic.css @@ -56,10 +56,12 @@ LABEL TABLE { display: block; table-layout: fixed; - border-spacing: 0px; - padding: 0px; - margin: 0px; - border: 0px; } + border-spacing: 0px; } + +TABLE TD +{ white-space: nowrap; + padding-left: .25em; + padding-right: .25em; } a:link { color: #0033CC; } @@ -214,7 +216,6 @@ DIV#toolbar border-bottom: 1px solid #848284; margin: 0px; padding: 0px; - background-color: #d4d0c8; white-space: nowrap; overflow: auto; } @@ -353,9 +354,6 @@ DIV#logConsole overflow: auto; display: none; z-index: 1000; - -moz-opacity: 0.7; - opacity: 0.7; - filter: alpha(opacity=70); border-top: 2px solid #fff; border-left: 2px solid #fff; border-right: 2px solid #999; @@ -363,17 +361,19 @@ DIV#logConsole -moz-border-top-colors: #000 #9c9a94 transparent; -moz-border-left-colors: #000 #9c9a94 transparent; font-family: monospace; - font-weight: bold; - background-color: #000; - color: #ddd; + font-size: 12pt; + padding: .25em; + background-color: #fff; + overflow-y: scroll; + color: #222; top: 1em; left: 0px; right: 0px; height: 15em; } -DIV#logConsole > DIV.highlighted -{ background-color: #333; } - +/* DIV#logConsole > DIV.highlighted +{ background-color: #ddf; } + */ /* content lists */ td.tbtv_actcell { border-width: 1px; @@ -387,6 +387,7 @@ td.tbtv_actcell padding-left: 4px; padding-right: 4px; } +TD.headerCell, TD.tbtv_headercell, TD.tbtv_navcell { background-color: #d4d0c8; @@ -397,12 +398,14 @@ TD.tbtv_navcell -moz-border-bottom-colors: #000 #9c9a94 transparent; -moz-border-right-colors: #000 #9c9a94 transparent; } +TD.headerCell:active, TD.tbtv_headercell:active { background-color: #DCDAD5; border: 1px solid #9c9a94; -moz-border-bottom-colors: #9c9a94; -moz-border-right-colors: #9c9a94; } +TD.headerCell SPAN, td.tbtv_headercell SPAN { float: left; width: 100%; } @@ -422,6 +425,7 @@ td.tbtv_headercell a:hover /* background-color: #C4C0B8; */ } +TD.headerCell IMG.tbtv_sortcell, td.tbtv_headercell img.tbtv_sortcell { float: right; text-align: right; @@ -438,11 +442,15 @@ TR.tableview TD padding-left: .3em; padding-right: .3em; } -TR.tableview TD.headerDateTime -{ width: 18em; } +TD.headerDateTime +{ width: 30em; + min-width: 30em; } + +TD.headerTitle +{ width: 30%; } -TR.tableview TD.headerLocation -{ width: 10em; } +TD.headerLocation +{ min-width: 20em; } td img.tbtv_sortcell { float: right; @@ -667,12 +675,14 @@ DIV.tabsContainer > DIV.tab bottom: .5em; display: none; } +DIV.tabsContainer DIV.active +{ display: block; } + DIV.tabsContainer > DIV[class~="active"].tab { display: block !important; } INPUT.checkBox -{ border: 2px solid #000; - vertical-align: middle; +{ vertical-align: middle; -moz-border-top-colors: #000 #fff; -moz-border-left-colors: #000 #fff; -moz-border-bottom-colors: #000 #fff; diff --git a/UI/WebServerResources/generic.js b/UI/WebServerResources/generic.js index 1b9cf3cc..1d5428f7 100644 --- a/UI/WebServerResources/generic.js +++ b/UI/WebServerResources/generic.js @@ -30,6 +30,8 @@ var queryParameters; var activeAjaxRequests = 0; var menus = new Array(); +var weekStartIsMonday = true; + // logArea = null; var allDocumentElements = null; @@ -213,16 +215,31 @@ function createHTTPClient() { return null; } +function appendDifferentiator(url) { + var url_nocache = url; + var position = url.indexOf('?', 0); + if (position < 0) + url_nocache += '?'; + else + url_nocache += '&'; + url_nocache += 'differentiator=' + Math.floor(Math.random()*50000); + + return url_nocache; +} + function triggerAjaxRequest(url, callback, userdata) { var http = createHTTPClient(); activeAjaxRequests += 1; document.animTimer = setTimeout("checkAjaxRequestsState();", 200); + //url = appendDifferentiator(url); if (http) { + http.open("POST", url, true); + http.url = url; http.onreadystatechange = function() { -// log ("state changed (" + http.readyState + "): " + url); + //log ("state changed (" + http.readyState + "): " + url); try { if (http.readyState == 4 && activeAjaxRequests > 0) { @@ -242,9 +259,10 @@ function triggerAjaxRequest(url, callback, userdata) { log(backtrace()); } }; - http.url = url; - http.open("GET", url, true); - http.send(""); + http.send(null); + } + else { + log("triggerAjaxRequest: error creating HTTP Client!"); } return http; @@ -273,6 +291,19 @@ function checkAjaxRequestsState() { } } +function isSafari() { + //var agt = navigator.userAgent.toLowerCase(); + //var is_safari = ((agt.indexOf('safari')!=-1)&&(agt.indexOf('mac')!=-1))?true:false; + + return (navigator.vendor == "Apple Computer, Inc."); +} + +function isHttpStatus204(status) { + return (status == 204 || // Firefox + (isSafari() && typeof(status) == 'undefined') || // Safari + status == 1223); // IE +} + function getTarget(event) { event = event || window.event; if (event.target) @@ -284,8 +315,8 @@ function getTarget(event) { function preventDefault(event) { if (event.preventDefault) event.preventDefault(); // W3C DOM - else - event.returnValue = false; // IE + + event.returnValue = false; // IE } function resetSelection(win) { @@ -389,21 +420,26 @@ function deselectAll(parent) { for (var i = 0; i < parent.childNodes.length; i++) { var node = parent.childNodes.item(i); if (node.nodeType == 1) - node.deselect(); + $(node).deselect(); } } function isNodeSelected(node) { - var classStr = '' + node.getAttribute('class'); - var position = classStr.indexOf('_selected', 0); - - return (position > -1); + return $(node).hasClassName('_selected'); } function acceptMultiSelect(node) { - var accept = ('' + node.getAttribute('multiselect')).toLowerCase(); + var response = false; + var attribute = node.getAttribute('multiselect'); + if (attribute) { + log("node '" + node.getAttribute("id") + + "' is still using old-stylemultiselect!"); + response = (attribute.toLowerCase() == 'yes'); + } + else + response = node.multiselect; - return (accept == 'yes'); + return response; } function onRowClick(event) { @@ -411,37 +447,41 @@ function onRowClick(event) { if (node.tagName == 'TD') node = node.parentNode; - - var startSelection = node.parentNode.getSelectedNodes(); + var startSelection = $(node.parentNode).getSelectedNodes(); if (event.shiftKey == 1 && (acceptMultiSelect(node.parentNode) || acceptMultiSelect(node.parentNode.parentNode))) { if (isNodeSelected(node) == true) { - node.deselect(); + $(node).deselect(); } else { - node.select(); + $(node).select(); } } else { - deselectAll(node.parentNode); - node.select(); + $(node.parentNode).deselectAll(); + $(node).select(); } - if (startSelection != node.parentNode.getSelectedNodes()) { + if (startSelection != $(node.parentNode).getSelectedNodes()) { var parentNode = node.parentNode; if (parentNode.tagName == 'TBODY') parentNode = parentNode.parentNode; - log("onRowClick: parentNode = " + parentNode.tagName); + //log("onRowClick: parentNode = " + parentNode.tagName); + // parentNode is UL or TABLE if (document.createEvent) { - var onSelectionChangeEvent = document.createEvent("UIEvents"); - onSelectionChangeEvent.initEvent("selectionchange", true, true); + var onSelectionChangeEvent; + if (isSafari()) + onSelectionChangeEvent = document.createEvent("UIEvents"); + else + onSelectionChangeEvent = document.createEvent("Events"); + onSelectionChangeEvent.initEvent("mousedown", true, true); parentNode.dispatchEvent(onSelectionChangeEvent); } else if (document.createEventObject) { - // TODO: add support for IE - //parentNode.fireEvent("change"); - //parentNode is UL or TABLE + parentNode.fireEvent("onmousedown"); } } + + return true; } /* popup menus */ @@ -807,7 +847,7 @@ function initCriteria() { /* toolbar buttons */ function popupToolbarMenu(event, menuId) { var toolbar = $("toolbar"); - var node = event.target; + var node = getTarget(event); if (node.tagName != 'A') node = node.getParentWithTagName("a"); node = node.childNodesWithTag("span")[0]; @@ -907,7 +947,6 @@ function unsubscribeFromFolder(folder, refreshCallback, refreshCallbackData) { function listRowMouseDownHandler(event) { preventDefault(event); - return false; } /* tabs */ @@ -931,9 +970,10 @@ function initTabs() { if (!firstTab) firstTab = i; Event.observe(currentNode, "mousedown", - onTabMouseDown.bindAsEventListener(currentNode)); + onTabMouseDown.bindAsEventListener(currentNode)); Event.observe(currentNode, "click", onTabClick.bindAsEventListener(currentNode)); + //$(currentNode.getAttribute("target")).hide(); } } @@ -943,6 +983,7 @@ function initTabs() { var target = $(nodes[firstTab].getAttribute("target")); target.addClassName("active"); + //target.show(); } } @@ -1025,7 +1066,7 @@ function getTopWindow() { } function onTabClick(event) { - var node = getTarget(event); + var node = getTarget(event); // LI element var target = node.getAttribute("target"); @@ -1035,10 +1076,24 @@ function onTabClick(event) { var oldContent = $(oldTarget); oldContent.removeClassName("active"); - container.activeTab.removeClassName("active"); + container.activeTab.removeClassName("active"); // previous LI container.activeTab = node; - container.activeTab.addClassName("active"); + container.activeTab.addClassName("active"); // current LI content.addClassName("active"); + + // Prototype alternative + + //oldContent.removeClassName("active"); + //container.activeTab.removeClassName("active"); // previous LI + //container.activeTab = node; + //container.activeTab.addClassName("active"); // current LI + + //container.activeTab.hide(); + //oldContent.hide(); + //content.show(); + + //container.activeTab = node; + //container.activeTab.show(); return false; } @@ -1143,12 +1198,11 @@ function onBodyClickContextMenu(event) { function configureSortableTableHeaders() { var headers = document.getElementsByClassName("sortableTableHeader"); for (var i = 0; i < headers.length; i++) { - var anchor = $(headers[i]).childNodesWithTag("a")[0]; - if (!anchor.link) { - anchor.link = anchor.getAttribute("href"); - anchor.href = "#"; - Event.observe(anchor, "click", onHeaderClick.bindAsEventListener(anchor), true); - } + var header = headers[i]; + var anchor = $(header).childNodesWithTag("a")[0]; + if (anchor) + Event.observe(anchor, "click", + onHeaderClick.bindAsEventListener(anchor)); } }