diff --git a/UI/Scheduler/English.lproj/Localizable.strings b/UI/Scheduler/English.lproj/Localizable.strings index 32dc2db3d..d884803b3 100644 --- a/UI/Scheduler/English.lproj/Localizable.strings +++ b/UI/Scheduler/English.lproj/Localizable.strings @@ -155,6 +155,7 @@ "What to Print" = "What to Print"; "Options" = "Options"; "Tasks with no due date" = "Tasks with no due date"; +"Display working hours only" = "Display working hours only"; "Completed tasks" = "Completed Tasks"; /* Appointments */ @@ -313,6 +314,7 @@ "Repeat" = "Repeat"; "Daily" = "Daily"; +"Multi-Columns" = "Multi-Columns"; "Weekly" = "Weekly"; "Monthly" = "Monthly"; "Yearly" = "Yearly"; @@ -542,6 +544,12 @@ vtodo_class2 = "(Confidential task)"; "tagWasRemoved" = "If you remove this calendar from synchronization, you'll need to reload the data on your mobile device.\nContinue?"; "DestinationCalendarError" = "The source and destination calendars are the same. Please try to copy to a different calendar."; "EventCopyError" = "The copy failed. Please try to copy to a difference calendar."; +"Please select at least one calendar" = "Please select at least one calendar"; +"notice:" = "notice:"; +"error:" = "error:"; +"success:" = "success:"; +"warning:" = "warning:"; + "Open Task..." = "Open Task..."; "Mark Completed" = "Mark Completed"; diff --git a/UI/Scheduler/Toolbars/SOGoAppointmentFolders.toolbar b/UI/Scheduler/Toolbars/SOGoAppointmentFolders.toolbar index 54a5eae10..14e5fcd5e 100644 --- a/UI/Scheduler/Toolbars/SOGoAppointmentFolders.toolbar +++ b/UI/Scheduler/Toolbars/SOGoAppointmentFolders.toolbar @@ -21,12 +21,11 @@ onclick = "return onDayOverview();"; image = "day-view.png"; tooltip = "Switch to day view"; }, - /* disabled until we fix the view */ - /* { link = "#"; - label="Multicolumn Day View"; - onclick = "return onMulticolumnDayOverview();"; - image = "day-view-multicolumn.png"; - tooltip = ""; }, */ + { link = "#"; + label="Multi-Columns View"; + onclick = "return onMulticolumnDayOverview();"; + image = "day-view-multicolumn.png"; + tooltip = "Switch to multi-columns day view"; }, { link = "#"; label="Week View"; onclick = "return onWeekOverview();"; diff --git a/UI/Scheduler/UIxCalDayTable.h b/UI/Scheduler/UIxCalDayTable.h index 88ab136e8..57d91e846 100644 --- a/UI/Scheduler/UIxCalDayTable.h +++ b/UI/Scheduler/UIxCalDayTable.h @@ -35,27 +35,27 @@ @interface UIxCalDayTable : UIxCalView { - unsigned int numberOfDays; - NSCalendarDate *startDate; - NSCalendarDate *currentTableDay; - NSString *currentTableHour; - NSMutableArray *daysToDisplay; - NSMutableArray *hoursToDisplay; - NSArray *weekDays; SOGoDateFormatter *dateFormatter; - NSString *timeFormat; + NSArray *weekDays; + NSString *currentView, *timeFormat, *currentTableHour; + NSCalendarDate *startDate, *currentTableDay; + NSMutableArray *daysToDisplay, *calendarsToDisplay, *currentCalendar, *hoursToDisplay; + unsigned int numberOfDays; } - (void) setNumberOfDays: (NSNumber *) aNumber; - (NSNumber *) numberOfDays; +- (NSString *) currentView; - (void) setStartDate: (NSCalendarDate *) aStartDate; - (NSCalendarDate *) startDate; - (NSCalendarDate *) endDate; - (NSArray *) daysToDisplay; +- (NSArray *) calendarsToDisplay; - (void) setCurrentTableDay: (NSCalendarDate *) aTableDay; - (NSCalendarDate *) currentTableDay; +- (NSMutableArray *) currentCalendar; @end diff --git a/UI/Scheduler/UIxCalDayTable.m b/UI/Scheduler/UIxCalDayTable.m index 174e1d1ea..799d55f57 100644 --- a/UI/Scheduler/UIxCalDayTable.m +++ b/UI/Scheduler/UIxCalDayTable.m @@ -55,9 +55,12 @@ ASSIGN (timeFormat, [ud timeFormat]); daysToDisplay = nil; + calendarsToDisplay = nil; hoursToDisplay = nil; numberOfDays = 1; startDate = nil; + currentView = nil; + currentCalendar = nil; currentTableDay = nil; currentTableHour = nil; weekDays = [locale objectForKey: NSShortWeekDayNameArray]; @@ -75,6 +78,8 @@ // [allAppointments release]; [weekDays release]; [daysToDisplay release]; + [calendarsToDisplay release]; + [currentView release]; [hoursToDisplay release]; [dateFormatter release]; [timeFormat release]; @@ -119,6 +124,16 @@ return [endDate endOfDay]; } +- (void) setCurrentView: (NSString *) aView +{ + ASSIGN(currentView, aView); +} + +- (NSString *) currentView +{ + return currentView; +} + - (NSArray *) hoursToDisplay { unsigned int currentHour, lastHour; @@ -148,22 +163,68 @@ { NSCalendarDate *currentDate; int count; - + if (!daysToDisplay) + { + daysToDisplay = [NSMutableArray new]; + currentDate = [[self startDate] hour: [self dayStartHour] + minute: 0]; + + for (count = 0; count < numberOfDays; count++) { - daysToDisplay = [NSMutableArray new]; - currentDate = [[self startDate] hour: [self dayStartHour] - minute: 0]; - for (count = 0; count < numberOfDays; count++) - { - [daysToDisplay addObject: currentDate]; - currentDate = [currentDate tomorrow]; - } + [daysToDisplay addObject: currentDate]; + currentDate = [currentDate tomorrow]; } - + } + return daysToDisplay; } +- (NSArray *) calendarsToDisplay +{ + if (!calendarsToDisplay) + { + int max=0, i; + NSArray *folders; + SOGoAppointmentFolders *co; + SOGoAppointmentFolder *folder; + NSMutableDictionary *calendar; + unsigned int count, foldersCount; + NSString *folderName, *fDisplayName; + NSNumber *isActive; + + co = [self clientObject]; + folders = [co subFolders]; + foldersCount = [folders count]; + calendarsToDisplay = [[NSMutableArray alloc] initWithCapacity: foldersCount]; + for (count = 0; count < foldersCount; count++) + { + folder = [folders objectAtIndex: count]; + isActive = [NSNumber numberWithBool: [folder isActive]]; + if ([isActive intValue] != 0) { + calendar = [NSMutableDictionary dictionary]; + folderName = [folder nameInContainer]; + fDisplayName = [folder displayName]; + if (fDisplayName == nil) + fDisplayName = @""; + if ([fDisplayName isEqualToString: [co defaultFolderName]]) + fDisplayName = [self labelForKey: fDisplayName]; + [calendar setObject: [NSString stringWithFormat: @"/%@", folderName] + forKey: @"id"]; + [calendar setObject: fDisplayName forKey: @"displayName"]; + [calendar setObject: folderName forKey: @"folder"]; + [calendar setObject: [folder calendarColor] forKey: @"color"]; + [calendar setObject: isActive forKey: @"active"]; + [calendar setObject: [folder ownerInContext: context] + forKey: @"owner"]; + [calendarsToDisplay addObject: calendar]; + } + } + } + + return calendarsToDisplay; +} + - (void) setCurrentTableDay: (NSCalendarDate *) aTableDay { currentTableDay = aTableDay; @@ -174,6 +235,16 @@ return currentTableDay; } +- (void) setCurrentCalendar: (NSMutableArray *) aCalendar +{ + ASSIGN(currentCalendar, aCalendar); +} + +- (NSMutableArray *) currentCalendar +{ + return currentCalendar; +} + - (void) setCurrentTableHour: (NSString *) aTableHour { currentTableHour = aTableHour; @@ -226,6 +297,16 @@ return [dateFormatter shortFormattedDate: currentTableDay]; } +- (NSString *) labelForCalendar +{ + return [currentCalendar objectForKey: @"displayName"]; +} + +- (NSString *) colorForCalendar +{ + return [currentCalendar objectForKey:@"color"]; +} + // - (NSDictionary *) _adjustedAppointment: (NSDictionary *) anAppointment // forStart: (NSCalendarDate *) start // andEnd: (NSCalendarDate *) end @@ -318,7 +399,15 @@ - (NSString *) daysViewClasses { - return [NSString stringWithFormat: @"daysView daysViewFor%dDays", numberOfDays]; + NSString *daysView; + + if ([currentView isEqualToString:@"multicolumndayview"]) + daysView = @"daysView daysViewForMultipleDays"; + + else + daysView = [NSString stringWithFormat: @"daysView daysViewFor%dDays", numberOfDays]; + + return daysView; } - (NSString *) dayClasses @@ -326,19 +415,24 @@ NSMutableString *classes; unsigned int currentDayNbr, realDayOfWeek; - currentDayNbr = [daysToDisplay indexOfObject: currentTableDay]; - realDayOfWeek = [currentTableDay dayOfWeek]; - classes = [NSMutableString string]; - [classes appendFormat: @"day day%d", currentDayNbr]; - if (numberOfDays > 1) + if ([currentView isEqualToString:@"multicolumndayview"]) + [classes appendFormat:@"day dayColumn"]; + else { + currentDayNbr = [daysToDisplay indexOfObject: currentTableDay]; + realDayOfWeek = [currentTableDay dayOfWeek]; + + [classes appendFormat: @"day day%d", currentDayNbr]; + + if (numberOfDays > 1) { if (realDayOfWeek == 0 || realDayOfWeek == 6) [classes appendString: @" weekEndDay"]; if ([currentTableDay isToday]) [classes appendString: @" dayOfToday"]; } - + } + return classes; } @@ -358,4 +452,20 @@ return cellClass; } +- (BOOL) isMultiColumnView +{ + if ([currentView isEqualToString:@"multicolumndayview"]) + return YES; + + return NO; +} + +- (BOOL) isNotMultiColumnView +{ + if ([currentView isEqualToString:@"dayview"] || [currentView isEqualToString:@"weekview"]) + return YES; + + return NO; +} + @end diff --git a/UI/Scheduler/UIxCalListingActions.h b/UI/Scheduler/UIxCalListingActions.h index 4f12d8cfe..41c27cecd 100644 --- a/UI/Scheduler/UIxCalListingActions.h +++ b/UI/Scheduler/UIxCalListingActions.h @@ -43,6 +43,7 @@ NSString *value; NSString *criteria; NSString *userLogin; + NSString *currentView; BOOL dayBasedView; WORequest *request; SOGoDateFormatter *dateFormatter; diff --git a/UI/Scheduler/UIxCalListingActions.m b/UI/Scheduler/UIxCalListingActions.m index 2a579be5f..7c34b8f71 100644 --- a/UI/Scheduler/UIxCalListingActions.m +++ b/UI/Scheduler/UIxCalListingActions.m @@ -75,6 +75,8 @@ static NSArray *tasksFields = nil; #define maxBlocks (offsetBlocks * 2) // maximum number of blocks to search // for a free slot (10 days) +@class SOGoAppointment; + @implementation UIxCalListingActions + (void) initialize @@ -118,6 +120,7 @@ static NSArray *tasksFields = nil; ASSIGN (dateFormatter, [user dateFormatterInContext: context]); ASSIGN (userTimeZone, [[user userDefaults] timeZone]); dayBasedView = NO; + currentView = nil; } return self; @@ -236,6 +239,7 @@ static NSArray *tasksFields = nil; endDate = nil; param = [request formValueForKey: @"view"]; + currentView = param; dayBasedView = ![param isEqualToString: @"monthview"]; } } @@ -1041,47 +1045,117 @@ _computeBlocksPosition (NSArray *blocks) /* ... _computeBlocksMultiplier() ... */ } +- (NSArray *) _selectedCalendars +{ + SOGoAppointmentFolders *co; + SOGoAppointmentFolder *folder; + NSMutableArray *selectedCalendars; + NSArray *folders; + NSString *fDisplayName; + NSNumber *isActive; + unsigned int count, foldersCount; + int max=0, i; + + co = [self clientObject]; + folders = [co subFolders]; + foldersCount = [folders count]; + selectedCalendars = [[NSMutableArray alloc] initWithCapacity: foldersCount]; + for (count = 0; count < foldersCount; count++) + { + folder = [folders objectAtIndex: count]; + isActive = [NSNumber numberWithBool: [folder isActive]]; + if ([isActive intValue] != 0) { + fDisplayName = [folder displayName]; + if (fDisplayName == nil) + fDisplayName = @""; + if ([fDisplayName isEqualToString: [co defaultFolderName]]) + fDisplayName = [self labelForKey: fDisplayName]; + [selectedCalendars addObject: fDisplayName]; + } + } + return selectedCalendars; +} + - (WOResponse *) eventsBlocksAction { int count, max; NSArray *events, *event, *eventsBlocks; - NSMutableArray *allDayBlocks, *blocks, *currentDay; + NSMutableArray *allDayBlocks, *blocks, *currentDay, *calendars, *eventsByCalendars, *eventsForCalendar; NSNumber *eventNbr; BOOL isAllDay; + int i, j; [self _setupContext]; - [self _prepareEventBlocks: &blocks withAllDays: &allDayBlocks]; - events = [self _fetchFields: eventsFields - forComponentOfType: @"vevent"]; - eventsBlocks = [NSArray arrayWithObjects: events, allDayBlocks, blocks, nil]; - max = [events count]; - for (count = 0; count < max; count++) - { - event = [events objectAtIndex: count]; - // NSLog(@"***[UIxCalListingActions eventsBlocksAction] %i = %@ : %@ / %@ / %@", count, - // [event objectAtIndex: eventTitleIndex], - // [event objectAtIndex: eventStartDateIndex], - // [event objectAtIndex: eventEndDateIndex], - // [event objectAtIndex: eventRecurrenceIdIndex]); - eventNbr = [NSNumber numberWithUnsignedInt: count]; - isAllDay = [[event objectAtIndex: eventIsAllDayIndex] boolValue]; - if (dayBasedView && isAllDay) - [self _fillBlocks: allDayBlocks withEvent: event withNumber: eventNbr]; - else - [self _fillBlocks: blocks withEvent: event withNumber: eventNbr]; - } + events = [self _fetchFields: eventsFields forComponentOfType: @"vevent"]; - max = [blocks count]; - for (count = 0; count < max; count++) + if ([currentView isEqualToString: @"multicolumndayview"]) { - currentDay = [blocks objectAtIndex: count]; - [currentDay sortUsingSelector: @selector (compareEventByStart:)]; - [self _addBlocksWidth: currentDay]; + calendars = [self _selectedCalendars]; + eventsByCalendars = [NSMutableArray arrayWithCapacity:[calendars count]]; + for (i = 0; i < [calendars count]; i++) // For each calendar + { + eventsForCalendar = [NSMutableArray array]; + [self _prepareEventBlocks: &blocks withAllDays: &allDayBlocks]; + for (j = 0; j < [events count]; j++) { + if ([[[events objectAtIndex:j] objectAtIndex:2] isEqualToString:[calendars objectAtIndex:i]]) { + [eventsForCalendar addObject: [events objectAtIndex:j]]; + } + } + eventsBlocks = [NSArray arrayWithObjects:eventsForCalendar, allDayBlocks, blocks, nil]; + max = [eventsForCalendar count]; + for (count = 0; count < max; count++) + { + event = [eventsForCalendar objectAtIndex: count]; + eventNbr = [NSNumber numberWithUnsignedInt: count]; + isAllDay = [[event objectAtIndex: eventIsAllDayIndex] boolValue]; + if (dayBasedView && isAllDay) + [self _fillBlocks: allDayBlocks withEvent: event withNumber: eventNbr]; + else + [self _fillBlocks: blocks withEvent: event withNumber: eventNbr]; + } + max = [blocks count]; + for (count = 0; count < max; count++) + { + currentDay = [blocks objectAtIndex: count]; + [currentDay sortUsingSelector: @selector (compareEventByStart:)]; + [self _addBlocksWidth: currentDay]; + } + + [eventsByCalendars insertObject:eventsBlocks atIndex:i]; + } + return [self _responseWithData: eventsByCalendars]; + } + else + { + [self _prepareEventBlocks: &blocks withAllDays: &allDayBlocks]; + eventsBlocks = [NSArray arrayWithObjects: events, allDayBlocks, blocks, nil]; + max = [events count]; + for (count = 0; count < max; count++) + { + event = [events objectAtIndex: count]; + // NSLog(@"***[UIxCalListingActions eventsBlocksAction] %i = %@ : %@ / %@ / %@", count, + // [event objectAtIndex: eventTitleIndex], + // [event objectAtIndex: eventStartDateIndex], + // [event objectAtIndex: eventEndDateIndex], + // [event objectAtIndex: eventRecurrenceIdIndex]); + eventNbr = [NSNumber numberWithUnsignedInt: count]; + isAllDay = [[event objectAtIndex: eventIsAllDayIndex] boolValue]; + if (dayBasedView && isAllDay) + [self _fillBlocks: allDayBlocks withEvent: event withNumber: eventNbr]; + else + [self _fillBlocks: blocks withEvent: event withNumber: eventNbr]; + } + + max = [blocks count]; + for (count = 0; count < max; count++) + { + currentDay = [blocks objectAtIndex: count]; + [currentDay sortUsingSelector: @selector (compareEventByStart:)]; + [self _addBlocksWidth: currentDay]; + } + return [self _responseWithData: eventsBlocks]; } - - return [self _responseWithData: eventsBlocks]; - // timeIntervalSinceDate: } - (NSString *) _getStatusClassForStatusCode: (int) statusCode diff --git a/UI/Scheduler/UIxCalMulticolumnDayView.m b/UI/Scheduler/UIxCalMulticolumnDayView.m index 6c1683d1a..b96241686 100644 --- a/UI/Scheduler/UIxCalMulticolumnDayView.m +++ b/UI/Scheduler/UIxCalMulticolumnDayView.m @@ -39,25 +39,25 @@ - (id) init { if ((self = [super init])) - { -// allAppointments = nil; - subscriptionUsers = nil; - hoursToDisplay = nil; - currentTableUser = nil; - currentTableHour = nil; -// dateFormatter = [[SOGoDateFormatter alloc] -// initWithLocale: [self locale]]; - } - + { + // allAppointments = nil; + subscriptionUsers = nil; + hoursToDisplay = nil; + currentTableUser = nil; + currentTableHour = nil; + // dateFormatter = [[SOGoDateFormatter alloc] + // initWithLocale: [self locale]]; + } + return self; } - (void) dealloc { -// [allAppointments release]; + // [allAppointments release]; [subscriptionUsers release]; [hoursToDisplay release]; -// [dateFormatter release]; + // [dateFormatter release]; [super dealloc]; } @@ -188,16 +188,6 @@ /* fetching */ -// - (NSCalendarDate *) startDate -// { -// return [[self selectedDate] beginOfDay]; -// } - -// - (NSCalendarDate *) endDate -// { -// return [[self selectedDate] endOfDay]; -// } - // - (NSArray *) appointmentsForCurrentUser // { // NSMutableArray *filteredAppointments; @@ -292,4 +282,11 @@ * (100.0 / [users count]))]; } +- (id ) defaultAction +{ + [super setCurrentView: @"multicolumndayview"]; + + return self; +} + @end diff --git a/UI/Scheduler/UIxCalViewPrint.h b/UI/Scheduler/UIxCalViewPrint.h index ac3de23a8..a0977d594 100644 --- a/UI/Scheduler/UIxCalViewPrint.h +++ b/UI/Scheduler/UIxCalViewPrint.h @@ -24,6 +24,7 @@ @interface UIxCalViewPrint : UIxComponent { id item; + SOGoUserSettings *us; } @end diff --git a/UI/Scheduler/UIxCalViewPrint.m b/UI/Scheduler/UIxCalViewPrint.m index af94b9792..d186ef4fa 100644 --- a/UI/Scheduler/UIxCalViewPrint.m +++ b/UI/Scheduler/UIxCalViewPrint.m @@ -22,6 +22,9 @@ #import #import +#import +#import + #import static NSArray *layoutItems = nil; @@ -32,21 +35,22 @@ static NSArray *layoutItems = nil; { if (!layoutItems) { - layoutItems = [NSArray arrayWithObjects: @"LIST", @"Daily", @"Weekly", nil]; + layoutItems = [NSArray arrayWithObjects: @"LIST", @"Daily", @"Multi-Columns", @"Weekly", nil]; [layoutItems retain]; } } + - (id) init { item = nil; - return [super init]; + + return self; } - (void) dealloc { [item release]; - [super dealloc]; } /****************************************************************/ @@ -72,10 +76,29 @@ static NSArray *layoutItems = nil; return [self labelForKey: [NSString stringWithFormat: item]]; } -- (NSString *) layoutSelectedByUser +- (NSString *) parentPrintLayout { - return nil; + // The objective here is to return the parent view layout and select the print layout corresponding. Default print view: list view + SOGoUser *activeUser; + NSString *parentView; + + activeUser = [context activeUser]; + us = [activeUser userSettings]; + parentView = [[us objectForKey:@"Calendar"] objectForKey:@"View" ]; + + if ([parentView isEqualToString:@"dayview"]) + return @"Daily"; + + else if ([parentView isEqualToString:@"weekview"]) + return @"Weekly"; + + else if ([parentView isEqualToString:@"multicolumndayview"]) + return @"Multi-Columns"; + + else + return @"LIST"; } + /******************************************************************/ /* */ diff --git a/UI/Templates/SchedulerUI/UIxCalDayTable.wox b/UI/Templates/SchedulerUI/UIxCalDayTable.wox index 5bb9f63ee..3f488286d 100644 --- a/UI/Templates/SchedulerUI/UIxCalDayTable.wox +++ b/UI/Templates/SchedulerUI/UIxCalDayTable.wox @@ -7,51 +7,105 @@ xmlns:rsrc="OGo:url" xmlns:label="OGo:label">
-

-
-
+ + + + +
+ +
+ +
+
+
+ + +
+ +
+
+ +
+
+
+ + +
+ + +
+
+
+
+
+ + + + +
+ +
+
+ +
+
+
+ + +
+ +
+
+
+
- + + +
-
-
- -
-
-
-
- - - -
-
+
+ +
+
+
+ + + + +
+
+ +
+ + + +
+
+
+
+
+
+
+
+ + +
+
+ +
+ + + +
+
+
+
+
+
+
+
diff --git a/UI/Templates/SchedulerUI/UIxCalDayView.wox b/UI/Templates/SchedulerUI/UIxCalDayView.wox index 676d65d54..83cf7c21c 100644 --- a/UI/Templates/SchedulerUI/UIxCalDayView.wox +++ b/UI/Templates/SchedulerUI/UIxCalDayView.wox @@ -40,6 +40,7 @@ className="UIxCalDayTable" startDate="startDate" const:CSSClass="dayOverview" - const:numberOfDays="1" /> + const:numberOfDays="1" + const:currentView="dayview"/>
diff --git a/UI/Templates/SchedulerUI/UIxCalMulticolumnDayView.wox b/UI/Templates/SchedulerUI/UIxCalMulticolumnDayView.wox index 62ee604e3..862a0026b 100644 --- a/UI/Templates/SchedulerUI/UIxCalMulticolumnDayView.wox +++ b/UI/Templates/SchedulerUI/UIxCalMulticolumnDayView.wox @@ -5,40 +5,33 @@ xmlns:const="http://www.skyrix.com/od/constant" xmlns:rsrc="OGo:url" xmlns:label="OGo:label"> - + + + - - + + + + + + + + + + - + +
-
-
-
:00
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
+
- + \ No newline at end of file diff --git a/UI/Templates/SchedulerUI/UIxCalViewPrint.wox b/UI/Templates/SchedulerUI/UIxCalViewPrint.wox index cbee832c1..f8370f0f5 100644 --- a/UI/Templates/SchedulerUI/UIxCalViewPrint.wox +++ b/UI/Templates/SchedulerUI/UIxCalViewPrint.wox @@ -25,10 +25,10 @@ + string="itemPrintLayoutText" selection="parentPrintLayout" /> - + @@ -81,6 +81,16 @@
+ + + + +
+
+