parent
3c6da09ff8
commit
c5eeadf041
1
NEWS
1
NEWS
|
@ -7,6 +7,7 @@ New features
|
|||
- [web] toolbar of all-day events can be expanded to display all events
|
||||
- [web] added AngularJS's XSRF support (#3246)
|
||||
- [web] calendars list can be reordered and filtered
|
||||
- [web] user can limit the calendars view to specific week days (#1841)
|
||||
|
||||
Enhancements
|
||||
- [web] updated Angular Material to version 1.0.6
|
||||
|
|
|
@ -199,6 +199,9 @@ extern NSString *SOGoWeekStartFirstFullWeek;
|
|||
- (void) setCalendarShouldDisplayWeekend: (BOOL) newValue;
|
||||
- (BOOL) calendarShouldDisplayWeekend;
|
||||
|
||||
- (void) setCalendarWeekdays: (NSArray *) newValues;
|
||||
- (NSArray *) calendarWeekdays;
|
||||
|
||||
- (void) setCalendarEventsDefaultClassification: (NSString *) newValue;
|
||||
- (NSString *) calendarEventsDefaultClassification;
|
||||
|
||||
|
|
|
@ -741,6 +741,16 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek";
|
|||
return [self objectForKey: @"SOGoCalendarCategoriesColors"];
|
||||
}
|
||||
|
||||
- (void) setCalendarWeekdays: (NSArray *) newValues
|
||||
{
|
||||
[self setObject: newValues forKey: @"SOGoCalendarWeekdays"];
|
||||
}
|
||||
|
||||
- (NSArray *) calendarWeekdays
|
||||
{
|
||||
return [self stringArrayForKey: @"SOGoCalendarWeekdays"];
|
||||
}
|
||||
|
||||
- (void) setCalendarShouldDisplayWeekend: (BOOL) newValue
|
||||
{
|
||||
[self setBool: newValue forKey: @"SOGoCalendarShouldDisplayWeekend"];
|
||||
|
|
|
@ -107,6 +107,7 @@
|
|||
"Day start time" = "Day start time";
|
||||
"Day end time" = "Day end time";
|
||||
"Day start time must be prior to day end time." = "Day start time must be prior to day end time.";
|
||||
"Week days to display" = "Week days to display";
|
||||
"Show time as busy outside working hours" = "Show time as busy outside working hours";
|
||||
"First week of year" = "First week of year";
|
||||
"Enable reminders for Calendar items" = "Enable reminders for Calendar items";
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import <SOPE/NGCards/iCalRecurrenceRule.h>
|
||||
|
||||
#import <SOGo/NSObject+Utilities.h>
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
|
@ -123,6 +125,9 @@ static SoProduct *preferencesProduct = nil;
|
|||
if (![[defaults source] objectForKey: @"SOGoDayEndTime"])
|
||||
[[defaults source] setObject: [NSString stringWithFormat: @"%02d:00", [defaults dayEndHour]] forKey: @"SOGoDayEndTime"];
|
||||
|
||||
if (![[defaults source] objectForKey: @"SOGoCalendarWeekdays"])
|
||||
[[defaults source] setObject: [NSArray arrayWithObjects: iCalWeekDayString count: 7] forKey: @"SOGoCalendarWeekdays"];
|
||||
|
||||
if (![[defaults source] objectForKey: @"SOGoFirstWeekOfYear"])
|
||||
[[defaults source] setObject: [defaults firstWeekOfYear] forKey: @"SOGoFirstWeekOfYear"];
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* UIxPreferences.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007-2015 Inverse inc.
|
||||
* Copyright (C) 2007-2016 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
|
@ -30,6 +30,8 @@
|
|||
|
||||
#import <NGCards/iCalTimeZone.h>
|
||||
|
||||
#import <SOPE/NGCards/iCalRecurrenceRule.h>
|
||||
|
||||
#import <SOGo/NSArray+Utilities.h>
|
||||
#import <SOGo/NSDictionary+Utilities.h>
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
|
@ -721,6 +723,28 @@ static NSArray *reminderValues = nil;
|
|||
// return [[moduleSettings objectForKey: @"PreventInvitations"] boolValue];
|
||||
// }
|
||||
|
||||
- (NSArray *) shortWeekDaysList
|
||||
{
|
||||
static NSArray *shortWeekDaysList = nil;
|
||||
|
||||
if (!shortWeekDaysList)
|
||||
{
|
||||
shortWeekDaysList = [locale objectForKey: NSShortWeekDayNameArray];
|
||||
[shortWeekDaysList retain];
|
||||
}
|
||||
|
||||
return shortWeekDaysList;
|
||||
}
|
||||
|
||||
- (NSString *) valueForWeekDay
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
i = [[self shortWeekDaysList] indexOfObject: item];
|
||||
|
||||
return iCalWeekDayString[i];
|
||||
}
|
||||
|
||||
//
|
||||
// Used by wox template
|
||||
//
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
NSMutableArray *daysToDisplay, *calendarsToDisplay, *hoursToDisplay;
|
||||
NSMutableDictionary *currentCalendar;
|
||||
unsigned int numberOfDays;
|
||||
unsigned int *daysNumbersToDisplay;
|
||||
}
|
||||
|
||||
- (void) setNumberOfDays: (NSNumber *) aNumber;
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
/* UIxCalDayTable.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006-2009 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2006-2016 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
|
@ -26,6 +24,8 @@
|
|||
|
||||
#import <NGExtensions/NSCalendarDate+misc.h>
|
||||
|
||||
#import <SOPE/NGCards/iCalRecurrenceRule.h>
|
||||
|
||||
#import <SOGo/NSCalendarDate+SOGo.h>
|
||||
#import <SOGo/SOGoDateFormatter.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
|
@ -61,7 +61,7 @@
|
|||
currentCalendar = nil;
|
||||
currentTableDay = nil;
|
||||
currentTableHour = nil;
|
||||
weekDays = [locale objectForKey: NSShortWeekDayNameArray];
|
||||
weekDays = [locale objectForKey: NSWeekDayNameArray];
|
||||
[weekDays retain];
|
||||
dateFormatter = [user dateFormatterInContext: context];
|
||||
[dateFormatter retain];
|
||||
|
@ -81,6 +81,7 @@
|
|||
[hoursToDisplay release];
|
||||
[dateFormatter release];
|
||||
[timeFormat release];
|
||||
free(daysNumbersToDisplay);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -135,7 +136,7 @@
|
|||
- (NSArray *) hoursToDisplay
|
||||
{
|
||||
unsigned int currentHour, lastHour;
|
||||
|
||||
|
||||
if (!hoursToDisplay)
|
||||
{
|
||||
hoursToDisplay = [NSMutableArray new];
|
||||
|
@ -157,24 +158,36 @@
|
|||
return [NSString stringWithFormat: @"hour%d", [currentTableHour intValue]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of NSCalendarDate instances matching the requested time period
|
||||
* and the week days enabled in the user's defaults.
|
||||
*/
|
||||
- (NSArray *) daysToDisplay
|
||||
{
|
||||
NSCalendarDate *currentDate;
|
||||
int count;
|
||||
|
||||
NSString *weekDay;
|
||||
int count, enabledCount;
|
||||
|
||||
if (!daysToDisplay)
|
||||
{
|
||||
daysToDisplay = [NSMutableArray new];
|
||||
daysNumbersToDisplay = malloc (numberOfDays * sizeof (unsigned int));
|
||||
currentDate = [[self startDate] hour: [self dayStartHour]
|
||||
minute: 0];
|
||||
|
||||
for (count = 0; count < numberOfDays; count++)
|
||||
|
||||
for (count = 0, enabledCount = 0; count < numberOfDays; count++)
|
||||
{
|
||||
[daysToDisplay addObject: currentDate];
|
||||
weekDay = iCalWeekDayString[[currentDate dayOfWeek]];
|
||||
if ([enabledWeekDays count] == 0 || [enabledWeekDays containsObject: weekDay])
|
||||
{
|
||||
[daysToDisplay addObject: currentDate];
|
||||
daysNumbersToDisplay[enabledCount] = count;
|
||||
enabledCount++;
|
||||
}
|
||||
currentDate = [currentDate tomorrow];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return daysToDisplay;
|
||||
}
|
||||
|
||||
|
@ -218,7 +231,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return calendarsToDisplay;
|
||||
}
|
||||
|
||||
|
@ -276,7 +289,9 @@
|
|||
|
||||
- (int) currentDayNumber
|
||||
{
|
||||
return [daysToDisplay indexOfObject: currentTableDay];
|
||||
int i = [daysToDisplay indexOfObject: currentTableDay];
|
||||
|
||||
return daysNumbersToDisplay[i];
|
||||
}
|
||||
|
||||
- (NSNumber *) currentAppointmentHour
|
||||
|
@ -354,7 +369,7 @@
|
|||
// {
|
||||
// newMutableAppointment
|
||||
// = [NSMutableDictionary dictionaryWithDictionary: anAppointment];
|
||||
|
||||
|
||||
// if (startIsEarlier)
|
||||
// [newMutableAppointment setObject: start
|
||||
// forKey: @"startDate"];
|
||||
|
@ -430,13 +445,13 @@
|
|||
// - (NSString *) daysViewClasses
|
||||
// {
|
||||
// NSString *daysView;
|
||||
|
||||
|
||||
// if ([currentView isEqualToString:@"multicolumndayview"])
|
||||
// daysView = @"daysView daysViewForMultipleDays";
|
||||
|
||||
// else
|
||||
// daysView = [NSString stringWithFormat: @"daysView daysViewFor%dDays", numberOfDays];
|
||||
|
||||
|
||||
// return daysView;
|
||||
//}
|
||||
|
||||
|
@ -448,14 +463,11 @@
|
|||
- (NSString *) dayClasses
|
||||
{
|
||||
NSMutableString *classes;
|
||||
unsigned int currentDayNbr, realDayOfWeek;
|
||||
|
||||
classes = [NSMutableString string];
|
||||
currentDayNbr = [daysToDisplay indexOfObject: currentTableDay];
|
||||
unsigned int realDayOfWeek;
|
||||
|
||||
classes = [NSMutableString stringWithString: @"day"];
|
||||
realDayOfWeek = [currentTableDay dayOfWeek];
|
||||
|
||||
[classes appendFormat: @"day day%d", currentDayNbr];
|
||||
|
||||
|
||||
if (numberOfDays > 1)
|
||||
{
|
||||
if (realDayOfWeek == 0 || realDayOfWeek == 6)
|
||||
|
@ -463,7 +475,7 @@
|
|||
if ([currentTableDay isToday])
|
||||
[classes appendString: @" dayOfToday"];
|
||||
}
|
||||
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
|
@ -487,7 +499,7 @@
|
|||
{
|
||||
if ([currentView isEqualToString:@"multicolumndayview"])
|
||||
return YES;
|
||||
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
@ -495,7 +507,7 @@
|
|||
{
|
||||
if ([currentView isEqualToString:@"dayview"] || [currentView isEqualToString:@"weekview"])
|
||||
return YES;
|
||||
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
Copyright (C) 2004 SKYRIX Software AG
|
||||
Copyright (C) 2006-2016 Inverse inc.
|
||||
|
||||
This file is part of OpenGroupware.org.
|
||||
|
||||
OGo is free software; you can redistribute it and/or modify it under
|
||||
SOGo 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
|
||||
SOGo 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
|
||||
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.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSDictionary.h>
|
||||
|
||||
|
||||
#import <NGExtensions/NSCalendarDate+misc.h>
|
||||
|
||||
|
||||
#import "UIxCalDayView.h"
|
||||
|
||||
// @interface UIxCalDayView (PrivateAPI)
|
||||
|
@ -66,7 +63,7 @@
|
|||
// {
|
||||
// NSCalendarDate *dateStart, *dateEnd, *aptStart, *aptEnd;
|
||||
// NGCalendarDateRange *dateRange, *aptRange;
|
||||
|
||||
|
||||
// dateStart = self->currentDate;
|
||||
// dateEnd = [dateStart dateByAddingYears:0 months:0 days:0
|
||||
// hours:1 minutes:0 seconds:0];
|
||||
|
@ -104,7 +101,7 @@
|
|||
// if ([d isDateOnSameDay:max])
|
||||
// max = (NSCalendarDate *)[d laterDate:max];
|
||||
// }
|
||||
|
||||
|
||||
// return [self _getDatesFrom:min to:max];
|
||||
// }
|
||||
|
||||
|
@ -119,7 +116,7 @@
|
|||
// dates = [[NSMutableArray alloc] initWithCapacity:count];
|
||||
// for(i = 0; i < count; i++) {
|
||||
// NSCalendarDate *date;
|
||||
|
||||
|
||||
// date = [_from hour:offset + i minute:0];
|
||||
// [dates addObject:date];
|
||||
// }
|
||||
|
@ -135,12 +132,12 @@
|
|||
|
||||
- (NSDictionary *) prevDayQueryParameters
|
||||
{
|
||||
return [self _dateQueryParametersWithOffset: -1];
|
||||
return [self _dateQueryParametersWithOffset: [self _nextValidOffset: -1]];
|
||||
}
|
||||
|
||||
- (NSDictionary *) nextDayQueryParameters
|
||||
{
|
||||
return [self _dateQueryParametersWithOffset: 1];
|
||||
return [self _dateQueryParametersWithOffset: [self _nextValidOffset: +1]];
|
||||
}
|
||||
|
||||
- (NSDictionary *) dayAfterNextDayQueryParameters
|
||||
|
@ -153,7 +150,7 @@
|
|||
NSMutableDictionary *qp;
|
||||
NSString *hmString;
|
||||
NSCalendarDate *date;
|
||||
|
||||
|
||||
date = [self selectedDate];
|
||||
hmString = [NSString stringWithFormat:@"%.2d%.2d",
|
||||
(int)[date hourOfDay], (int)[date minuteOfHour]];
|
||||
|
@ -177,7 +174,7 @@
|
|||
// NSArray *apts;
|
||||
// NSMutableArray *filtered;
|
||||
// unsigned i, count;
|
||||
|
||||
|
||||
// if (self->allDayApts)
|
||||
// return self->allDayApts;
|
||||
|
||||
|
@ -188,7 +185,7 @@
|
|||
// for (i = 0; i < count; i++) {
|
||||
// id apt;
|
||||
// NSNumber *bv;
|
||||
|
||||
|
||||
// apt = [apts objectAtIndex:i];
|
||||
// bv = [apt valueForKey:@"isallday"];
|
||||
// if ([bv boolValue]) {
|
||||
|
@ -203,7 +200,7 @@
|
|||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// ASSIGN(self->allDayApts, filtered);
|
||||
// [filtered release];
|
||||
// return self->allDayApts;
|
||||
|
@ -219,8 +216,8 @@
|
|||
NSCalendarDate *date;
|
||||
|
||||
date = [[self selectedDate] dateByAddingYears: 0
|
||||
months: 0
|
||||
days: offset];
|
||||
months: 0
|
||||
days: offset];
|
||||
|
||||
return [self localizedNameForDayOfWeek: [date dayOfWeek]];
|
||||
}
|
||||
|
@ -232,7 +229,7 @@
|
|||
|
||||
- (NSString *) yesterdayName
|
||||
{
|
||||
return [self _dayNameWithOffsetFromToday: -1];
|
||||
return [self _dayNameWithOffsetFromToday: [self _nextValidOffset: -1]];
|
||||
}
|
||||
|
||||
- (NSString *) currentDayName
|
||||
|
@ -242,7 +239,7 @@
|
|||
|
||||
- (NSString *) tomorrowName
|
||||
{
|
||||
return [self _dayNameWithOffsetFromToday: 1];
|
||||
return [self _dayNameWithOffsetFromToday: [self _nextValidOffset: +1]];
|
||||
}
|
||||
|
||||
- (NSString *) dayAfterTomorrowName
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
@interface UIxCalListingActions : SOGoDirectAction
|
||||
{
|
||||
NSArray *enabledWeekDays;
|
||||
NSMutableDictionary *componentsData;
|
||||
NSCalendarDate *startDate;
|
||||
NSCalendarDate *endDate;
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <NGExtensions/NSString+misc.h>
|
||||
|
||||
#import <SOPE/NGCards/iCalRecurrenceRule.h>
|
||||
|
||||
#import <SOGo/SOGoDateFormatter.h>
|
||||
#import <SOGo/SOGoPermissions.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
|
@ -114,6 +116,7 @@ static NSArray *tasksFields = nil;
|
|||
ASSIGN (userTimeZone, [[user userDefaults] timeZone]);
|
||||
dayBasedView = NO;
|
||||
currentView = nil;
|
||||
ASSIGN (enabledWeekDays, [[user userDefaults] calendarWeekdays]);
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -125,6 +128,7 @@ static NSArray *tasksFields = nil;
|
|||
[request release];
|
||||
[componentsData release];
|
||||
[userTimeZone release];
|
||||
[enabledWeekDays release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -350,7 +354,7 @@ static NSArray *tasksFields = nil;
|
|||
NSMutableDictionary *newInfo;
|
||||
NSMutableArray *infos, *quickInfos, *allInfos, *quickInfosName;
|
||||
NSNull *marker;
|
||||
NSString *owner, *role, *calendarName, *iCalString, *recurrenceTime, *categories;
|
||||
NSString *owner, *role, *calendarName, *iCalString, *recurrenceTime, *categories, *weekDay;
|
||||
NSRange match;
|
||||
iCalCalendar *calendar;
|
||||
iCalEntityObject *master;
|
||||
|
@ -451,6 +455,11 @@ static NSArray *tasksFields = nil;
|
|||
|
||||
while ((newInfo = [currentInfos nextObject]))
|
||||
{
|
||||
// Skip components that appear on disabled weekdays
|
||||
weekDay = iCalWeekDayString[[[newInfo objectForKey: @"startDate"] dayOfWeek]];
|
||||
if ([enabledWeekDays count] && ![enabledWeekDays containsObject: weekDay])
|
||||
continue;
|
||||
|
||||
if ([fields containsObject: @"viewable"])
|
||||
{
|
||||
if ([owner isEqualToString: userLogin])
|
||||
|
@ -770,26 +779,35 @@ static NSArray *tasksFields = nil;
|
|||
*/
|
||||
- (WOResponse *) eventsListAction
|
||||
{
|
||||
BOOL isAllDay;
|
||||
NSArray *oldEvent;
|
||||
NSCalendarDate *date;
|
||||
NSDictionary *data;
|
||||
NSEnumerator *events;
|
||||
NSMutableArray *fields, *newEvents, *newEvent;
|
||||
NSString *sort, *ascending, *weekDay;
|
||||
unsigned int interval;
|
||||
BOOL isAllDay;
|
||||
NSString *sort, *ascending;
|
||||
|
||||
[self _setupContext];
|
||||
[self saveFilterValue: @"EventsFilterState"];
|
||||
[self saveSortValue: @"EventsSortingState"];
|
||||
|
||||
|
||||
newEvents = [NSMutableArray array];
|
||||
events = [[self _fetchFields: eventsFields
|
||||
forComponentOfType: @"vevent"] objectEnumerator];
|
||||
while ((oldEvent = [events nextObject]))
|
||||
{
|
||||
interval = [[oldEvent objectAtIndex: eventStartDateIndex] intValue];
|
||||
date = [NSCalendarDate dateWithTimeIntervalSince1970: interval];
|
||||
[date setTimeZone: userTimeZone];
|
||||
|
||||
// Skip components that appear on disabled weekdays
|
||||
weekDay = iCalWeekDayString[[date dayOfWeek]];
|
||||
if ([enabledWeekDays count] && ![enabledWeekDays containsObject: weekDay])
|
||||
continue;
|
||||
|
||||
newEvent = [NSMutableArray arrayWithArray: oldEvent];
|
||||
isAllDay = [[oldEvent objectAtIndex: eventIsAllDayIndex] boolValue];
|
||||
interval = [[oldEvent objectAtIndex: eventStartDateIndex] intValue];
|
||||
[newEvent addObject: [self _formattedDateForSeconds: interval
|
||||
forAllDay: isAllDay]];
|
||||
interval = [[oldEvent objectAtIndex: eventEndDateIndex] intValue];
|
||||
|
@ -967,8 +985,7 @@ static inline NSString* _userStateInEvent (NSArray *event)
|
|||
offset = 0;
|
||||
}
|
||||
else
|
||||
offset = ((currentStart - startSecs)
|
||||
/ dayLength);
|
||||
offset = ((currentStart - startSecs) / dayLength);
|
||||
if (offset >= [blocks count])
|
||||
[self errorWithFormat: @"event '%@' has a computed offset that"
|
||||
@" overflows the amount of blocks (skipped)",
|
||||
|
@ -1309,15 +1326,16 @@ _computeBlocksPosition (NSArray *blocks)
|
|||
{
|
||||
int count, max;
|
||||
NSArray *events, *event, *calendars;
|
||||
NSCalendarDate *currentDate;
|
||||
NSDictionary *eventsBlocks, *calendar;
|
||||
NSMutableArray *allDayBlocks, *blocks, *currentDay, *eventsForCalendar, *eventsByCalendars;
|
||||
NSMutableArray *allDayBlocks, *blocks, *days, *currentDay, *eventsForCalendar, *eventsByCalendars;
|
||||
NSNumber *eventNbr;
|
||||
NSString *calendarName, *calendarId;
|
||||
BOOL isAllDay;
|
||||
int i, j;
|
||||
|
||||
[self _setupContext];
|
||||
|
||||
|
||||
events = [self _fetchFields: eventsFields forComponentOfType: @"vevent"];
|
||||
|
||||
if ([currentView isEqualToString: @"multicolumndayview"])
|
||||
|
@ -1329,6 +1347,7 @@ _computeBlocksPosition (NSArray *blocks)
|
|||
calendar = [calendars objectAtIndex:i];
|
||||
calendarName = [calendar objectForKey: @"name"];
|
||||
calendarId = [calendar objectForKey: @"id"];
|
||||
days = [NSMutableArray array];
|
||||
eventsForCalendar = [NSMutableArray array];
|
||||
[self _prepareEventBlocks: &blocks withAllDays: &allDayBlocks];
|
||||
for (j = 0; j < [events count]; j++) {
|
||||
|
@ -1343,7 +1362,8 @@ _computeBlocksPosition (NSArray *blocks)
|
|||
eventsFields, @"eventsFields",
|
||||
eventsForCalendar, @"events",
|
||||
allDayBlocks, @"allDayBlocks",
|
||||
blocks, @"blocks", nil];
|
||||
blocks, @"blocks",
|
||||
days, @"days", nil];
|
||||
max = [eventsForCalendar count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
|
@ -1355,12 +1375,20 @@ _computeBlocksPosition (NSArray *blocks)
|
|||
else
|
||||
[self _fillBlocks: blocks withEvent: event withNumber: eventNbr];
|
||||
}
|
||||
|
||||
currentDate = [[startDate copy] autorelease];
|
||||
[currentDate setTimeZone: userTimeZone];
|
||||
max = [blocks count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
currentDay = [blocks objectAtIndex: count];
|
||||
[currentDay sortUsingSelector: @selector (compareEventByStart:)];
|
||||
[self _addBlocksWidth: currentDay];
|
||||
|
||||
[days addObject: [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[currentDate shortDateString], @"date",
|
||||
[NSNumber numberWithInt: count], @"number", nil]];
|
||||
currentDate = [currentDate addYear:0 month:0 day:1 hour:0 minute:0 second:0];
|
||||
}
|
||||
[eventsByCalendars addObject: eventsBlocks];
|
||||
}
|
||||
|
@ -1368,12 +1396,14 @@ _computeBlocksPosition (NSArray *blocks)
|
|||
}
|
||||
else
|
||||
{
|
||||
days = [NSMutableArray array];
|
||||
[self _prepareEventBlocks: &blocks withAllDays: &allDayBlocks];
|
||||
eventsBlocks = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
eventsFields, @"eventsFields",
|
||||
events, @"events",
|
||||
allDayBlocks, @"allDayBlocks",
|
||||
blocks, @"blocks", nil];
|
||||
blocks, @"blocks",
|
||||
days, @"days", nil];
|
||||
max = [events count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
|
@ -1390,14 +1420,44 @@ _computeBlocksPosition (NSArray *blocks)
|
|||
else
|
||||
[self _fillBlocks: blocks withEvent: event withNumber: eventNbr];
|
||||
}
|
||||
|
||||
|
||||
currentDate = [[startDate copy] autorelease];
|
||||
[ setTimeZone: userTimeZone];
|
||||
max = [blocks count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
currentDay = [blocks objectAtIndex: count];
|
||||
[currentDay sortUsingSelector: @selector (compareEventByStart:)];
|
||||
[self _addBlocksWidth: currentDay];
|
||||
|
||||
[days addObject: [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[currentDate shortDateString], @"date",
|
||||
[NSNumber numberWithInt: count], @"number", nil]];
|
||||
currentDate = [currentDate addYear:0 month:0 day:1 hour:0 minute:0 second:0];
|
||||
}
|
||||
|
||||
if ([enabledWeekDays count] > 0 && [enabledWeekDays count] < 7)
|
||||
{
|
||||
// Remove the days that are disabled in the user's defaults
|
||||
int weekDay, weekDayCount;
|
||||
|
||||
weekDayCount= [currentDate dayOfWeek];
|
||||
for (count = max - 1; count >= 0; count--)
|
||||
{
|
||||
weekDayCount--;
|
||||
if (weekDayCount < 0)
|
||||
weekDay = ((weekDayCount % 7) + 7) % 7;
|
||||
else
|
||||
weekDay = weekDayCount;
|
||||
if (![enabledWeekDays containsObject: iCalWeekDayString[weekDay]])
|
||||
{
|
||||
[allDayBlocks removeObjectAtIndex: count];
|
||||
[blocks removeObjectAtIndex: count];
|
||||
[days removeObjectAtIndex: count];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [self _responseWithData: [NSArray arrayWithObject: eventsBlocks]];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* UIxCalMonthView.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006-2015 Inverse inc.
|
||||
* Copyright (C) 2006-2016 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
|
@ -44,6 +44,8 @@
|
|||
|
||||
NSArray *dayNames;
|
||||
NSArray *monthNames;
|
||||
|
||||
unsigned int *daysNumbersToDisplay;
|
||||
}
|
||||
|
||||
- (NSDictionary *) monthBeforePrevMonthQueryParameters;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* UIxCalMonthView.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006-2015 Inverse inc.
|
||||
* Copyright (C) 2006-2016 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
|
@ -23,8 +23,11 @@
|
|||
#import <NGExtensions/NSCalendarDate+misc.h>
|
||||
#import <SoObjects/SOGo/NSCalendarDate+SOGo.h>
|
||||
|
||||
#import <SOPE/NGCards/iCalRecurrenceRule.h>
|
||||
|
||||
#import <SOGoUI/SOGoAptFormatter.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/SOGoUserDefaults.h>
|
||||
#import <SOGo/WOResourceManager+SOGo.h>
|
||||
|
||||
#import "UIxCalMonthView.h"
|
||||
|
@ -59,6 +62,8 @@
|
|||
[weeksToDisplay release];
|
||||
[currentTableDay release];
|
||||
[currentWeek release];
|
||||
[enabledWeekDays release];
|
||||
free(daysNumbersToDisplay);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -71,16 +76,19 @@
|
|||
|
||||
- (NSArray *) headerDaysToDisplay
|
||||
{
|
||||
NSMutableArray *headerDaysToDisplay;
|
||||
unsigned int counter;
|
||||
NSCalendarDate *currentDate;
|
||||
NSMutableArray *headerDaysToDisplay;
|
||||
NSString *weekDay;
|
||||
unsigned int counter;
|
||||
|
||||
headerDaysToDisplay = [NSMutableArray arrayWithCapacity: 7];
|
||||
currentDate
|
||||
= [[context activeUser] firstDayOfWeekForDate: [self selectedDate]];
|
||||
currentDate = [[context activeUser] firstDayOfWeekForDate: [self selectedDate]];
|
||||
for (counter = 0; counter < 7; counter++)
|
||||
{
|
||||
[headerDaysToDisplay addObject: currentDate];
|
||||
// Skip days that match disabled weekdays in user's defaults
|
||||
weekDay = iCalWeekDayString[[currentDate dayOfWeek]];
|
||||
if ([enabledWeekDays count] == 0 || [enabledWeekDays containsObject: weekDay])
|
||||
[headerDaysToDisplay addObject: currentDate];
|
||||
currentDate = [currentDate tomorrow];
|
||||
}
|
||||
|
||||
|
@ -89,31 +97,37 @@
|
|||
|
||||
- (NSArray *) weeksToDisplay
|
||||
{
|
||||
NSMutableArray *week;
|
||||
unsigned int counter, day;
|
||||
NSCalendarDate *currentDate, *selectedDate, *lastDayOfMonth, *firstOfAllDays;
|
||||
NSMutableArray *week;
|
||||
NSString *weekDay;
|
||||
unsigned int counter, day, enabledCounter;
|
||||
unsigned int firstToLast, weeks;
|
||||
|
||||
if (!weeksToDisplay)
|
||||
{
|
||||
selectedDate = [self selectedDate];
|
||||
firstOfAllDays
|
||||
= [[context activeUser] firstDayOfWeekForDate:
|
||||
[selectedDate firstDayOfMonth]];
|
||||
firstOfAllDays = [[context activeUser] firstDayOfWeekForDate:
|
||||
[selectedDate firstDayOfMonth]];
|
||||
lastDayOfMonth = [selectedDate lastDayOfMonth];
|
||||
firstToLast = ([lastDayOfMonth timeIntervalSinceDate: firstOfAllDays]
|
||||
/ 86400) + 1;
|
||||
firstToLast = ([lastDayOfMonth timeIntervalSinceDate: firstOfAllDays] / 86400) + 1;
|
||||
weeks = firstToLast / 7;
|
||||
if ((firstToLast % 7))
|
||||
weeks++;
|
||||
weeksToDisplay = [NSMutableArray arrayWithCapacity: weeks];
|
||||
daysNumbersToDisplay = malloc (weeks * 7 * sizeof (unsigned int));
|
||||
currentDate = firstOfAllDays;
|
||||
for (counter = 0; counter < weeks; counter++)
|
||||
for (counter = 0, enabledCounter = 0; counter < weeks; counter++)
|
||||
{
|
||||
week = [NSMutableArray arrayWithCapacity: 7];
|
||||
for (day = 0; day < 7; day++)
|
||||
{
|
||||
[week addObject: currentDate];
|
||||
weekDay = iCalWeekDayString[[currentDate dayOfWeek]];
|
||||
if ([enabledWeekDays count] == 0 || [enabledWeekDays containsObject: weekDay])
|
||||
{
|
||||
[week addObject: currentDate];
|
||||
daysNumbersToDisplay[enabledCounter] = (counter * 7) + day;
|
||||
enabledCounter++;
|
||||
}
|
||||
currentDate = [currentDate tomorrow];
|
||||
}
|
||||
[weeksToDisplay addObject: week];
|
||||
|
@ -137,7 +151,7 @@
|
|||
date = [firstDay dateByAddingYears: 0 months: monthsOffset
|
||||
days: 0 hours: 0 minutes: 0 seconds: 0];
|
||||
|
||||
return [self queryParametersBySettingSelectedDate: date];
|
||||
return [self queryParametersBySettingSelectedDate: [self _nextValidDate: date]];
|
||||
}
|
||||
|
||||
- (NSDictionary *) monthBeforePrevMonthQueryParameters
|
||||
|
@ -214,8 +228,10 @@
|
|||
|
||||
- (int) currentDayNumber
|
||||
{
|
||||
return ([currentWeek indexOfObject: currentTableDay]
|
||||
+ [weeksToDisplay indexOfObject: currentWeek] * 7);
|
||||
int i = [currentWeek indexOfObject: currentTableDay] +
|
||||
([weeksToDisplay indexOfObject: currentWeek] * [currentWeek count]);
|
||||
|
||||
return daysNumbersToDisplay[i];
|
||||
}
|
||||
|
||||
- (void) setCurrentWeek: (NSArray *) newCurrentWeek
|
||||
|
@ -285,8 +301,9 @@
|
|||
NSCalendarDate *firstDayOfMonth;
|
||||
|
||||
firstDayOfMonth = [[self selectedDate] firstDayOfMonth];
|
||||
firstDayOfMonth = [[context activeUser] firstDayOfWeekForDate: firstDayOfMonth];
|
||||
|
||||
return [[context activeUser] firstDayOfWeekForDate: firstDayOfMonth];
|
||||
return [self _nextValidDate: firstDayOfMonth];
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) endDate
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
/* UIxCalView.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006-2009 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2006-2016 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
|
@ -48,6 +46,7 @@
|
|||
NSMutableDictionary *componentsData;
|
||||
NSArray *tasks;
|
||||
NSArray *allDayApts;
|
||||
NSArray *enabledWeekDays;
|
||||
id appointment;
|
||||
NSCalendarDate *currentDay;
|
||||
NSTimeZone *timeZone;
|
||||
|
@ -130,6 +129,8 @@
|
|||
- (NSString *) aptStyle;
|
||||
|
||||
/* protected methods */
|
||||
- (NSCalendarDate *) _nextValidDate: (NSCalendarDate *) date;
|
||||
- (int) _nextValidOffset: (int) daysOffset;
|
||||
- (NSDictionary *) _dateQueryParametersWithOffset: (int) daysOffset;
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* UIxCalView.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006-2015 Inverse inc.
|
||||
* Copyright (C) 2006-2016 Inverse inc.
|
||||
*
|
||||
* 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
|
||||
|
@ -26,6 +26,8 @@
|
|||
#import <NGExtensions/NSString+misc.h>
|
||||
#import <NGCards/NGCards.h>
|
||||
|
||||
#import <SOPE/NGCards/iCalRecurrenceRule.h>
|
||||
|
||||
#import <Appointments/SOGoAppointmentFolder.h>
|
||||
#import <Appointments/SOGoAppointmentFolders.h>
|
||||
#import <SOGo/NSArray+Utilities.h>
|
||||
|
@ -55,6 +57,7 @@
|
|||
{
|
||||
ud = [[context activeUser] userDefaults];
|
||||
ASSIGN (timeZone, [ud timeZone]);
|
||||
ASSIGN (enabledWeekDays, [ud calendarWeekdays]);
|
||||
aptFormatter
|
||||
= [[SOGoAptFormatter alloc] initWithDisplayTimeZone: timeZone];
|
||||
aptTooltipFormatter
|
||||
|
@ -253,7 +256,7 @@
|
|||
title = [appointment valueForKey: @"title"];
|
||||
if ([title length] > 12)
|
||||
title = [[title substringToIndex: 11] stringByAppendingString: @"..."];
|
||||
|
||||
|
||||
return title;
|
||||
}
|
||||
|
||||
|
@ -396,7 +399,7 @@
|
|||
if ([bv boolValue])
|
||||
[filtered addObject: apt];
|
||||
}
|
||||
|
||||
|
||||
ASSIGN(allDayApts, filtered);
|
||||
[filtered release];
|
||||
return allDayApts;
|
||||
|
@ -448,10 +451,10 @@
|
|||
- (NSString *) appointmentViewURL
|
||||
{
|
||||
id pkey;
|
||||
|
||||
|
||||
if (![(pkey = [[self appointment] valueForKey: @"uid"]) isNotNull])
|
||||
return nil;
|
||||
|
||||
|
||||
return [[[self clientObject] baseURLForAptWithUID: [pkey stringValue]
|
||||
inContext: [self context]]
|
||||
stringByAppendingString: @"/view"];
|
||||
|
@ -474,7 +477,7 @@
|
|||
- (BOOL) shouldDisplayRejectedAppointments
|
||||
{
|
||||
NSString *bv;
|
||||
|
||||
|
||||
bv = [self queryParameterForKey: @"dr"];
|
||||
if (!bv) return NO;
|
||||
return [bv boolValue];
|
||||
|
@ -484,7 +487,7 @@
|
|||
{
|
||||
NSMutableDictionary *qp;
|
||||
BOOL shouldDisplay;
|
||||
|
||||
|
||||
shouldDisplay = ![self shouldDisplayRejectedAppointments];
|
||||
qp = [[[self queryParameters] mutableCopy] autorelease];
|
||||
[qp setObject: shouldDisplay ? @"1" : @"0" forKey: @"dr"];
|
||||
|
@ -500,19 +503,68 @@
|
|||
|
||||
/* date selection & conversion */
|
||||
|
||||
- (NSCalendarDate *) _nextValidDate: (NSCalendarDate *) date
|
||||
{
|
||||
NSCalendarDate *validDate;
|
||||
NSString *weekDay;
|
||||
|
||||
validDate = [[date copy] autorelease];
|
||||
if ([enabledWeekDays count])
|
||||
{
|
||||
weekDay = iCalWeekDayString[[validDate dayOfWeek]];
|
||||
while (![enabledWeekDays containsObject: weekDay])
|
||||
{
|
||||
validDate = [validDate dateByAddingYears:0 months:0 days:1 hours:0 minutes:0 seconds:0];
|
||||
weekDay = iCalWeekDayString[[validDate dayOfWeek]];
|
||||
}
|
||||
}
|
||||
|
||||
return validDate;
|
||||
}
|
||||
|
||||
- (int) _nextValidOffset: (int) daysOffset
|
||||
{
|
||||
NSCalendarDate *date;
|
||||
NSString *weekDay;
|
||||
int count, offset;
|
||||
|
||||
count = (daysOffset < 0)? -1 : +1;
|
||||
offset = daysOffset;
|
||||
|
||||
if ([enabledWeekDays count])
|
||||
{
|
||||
date = [[self startDate] dateByAddingYears:0 months:0 days:offset hours:0 minutes:0 seconds:0];
|
||||
weekDay = iCalWeekDayString[[date dayOfWeek]];
|
||||
while (![enabledWeekDays containsObject: weekDay])
|
||||
{
|
||||
offset += count;
|
||||
date = [date dateByAddingYears:0 months:0 days:count hours:0 minutes:0 seconds:0];
|
||||
weekDay = iCalWeekDayString[[date dayOfWeek]];
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
- (NSDictionary *) _dateQueryParametersWithOffset: (int) daysOffset
|
||||
{
|
||||
NSCalendarDate *date;
|
||||
|
||||
|
||||
date = [[self startDate] dateByAddingYears: 0 months: 0
|
||||
days: daysOffset
|
||||
hours: 0 minutes: 0 seconds: 0];
|
||||
|
||||
return [self queryParametersBySettingSelectedDate: date];
|
||||
}
|
||||
|
||||
- (NSDictionary *) todayQueryParameters
|
||||
{
|
||||
return [self queryParametersBySettingSelectedDate: [NSCalendarDate date]];
|
||||
NSCalendarDate *today;
|
||||
|
||||
today = [NSCalendarDate date];
|
||||
[today setTimeZone: timeZone];
|
||||
|
||||
return [self queryParametersBySettingSelectedDate: [self _nextValidDate: today]];
|
||||
}
|
||||
|
||||
- (NSDictionary *) currentDayQueryParameters
|
||||
|
@ -581,7 +633,7 @@
|
|||
&& (![userFolderID isEqualToString: uidsString])))
|
||||
{
|
||||
NSRange r;
|
||||
|
||||
|
||||
/* uri ends with an '/', so we have to adjust the range a little */
|
||||
r = NSMakeRange(0, [uri length] - 1);
|
||||
r = [uri rangeOfString: @"/"
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
date = [[context activeUser] firstDayOfWeekForDate: [super startDate]];
|
||||
|
||||
return [date beginOfDay];
|
||||
return [self _nextValidDate: [date beginOfDay]];
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) endDate
|
||||
|
|
|
@ -290,7 +290,19 @@
|
|||
</md-input-container>
|
||||
</div>
|
||||
|
||||
<md-checkbox
|
||||
<div class="pseudo-input-container"
|
||||
layout="row" layout-align="center center">
|
||||
<label class="pseudo-input-label"><var:string label:value="Week days to display"/></label>
|
||||
<md-grid-list md-cols="7" md-row-height="2em" md-gutter="0.5em"
|
||||
flex="50" flex-sm="80" flex-xs="100"
|
||||
sg-toggle-grid="app.preferences.defaults.SOGoCalendarWeekdays">
|
||||
<var:foreach list="shortWeekDaysList" item="item">
|
||||
<md-grid-tile var:value="valueForWeekDay"><var:string value="item"/></md-grid-tile>
|
||||
</var:foreach>
|
||||
</md-grid-list>
|
||||
</div>
|
||||
|
||||
<md-checkbox layout-padding="layout-padding"
|
||||
ng-model="app.preferences.defaults.SOGoBusyOffHours"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0">
|
||||
|
|
|
@ -61,8 +61,8 @@
|
|||
<div class="days" sg-calendar-scroll-view="multiday-allday">
|
||||
<var:foreach list="daysToDisplay" item="currentTableDay">
|
||||
<sg-calendar-day var:class="dayClasses"
|
||||
var:day="currentTableDay.shortDateString"
|
||||
var:id="currentAllDayId"
|
||||
var:day="currentTableDay.shortDateString"
|
||||
hour="allday"
|
||||
var:sg-day-number="currentDayNumber"
|
||||
var:sg-day="currentTableDay.shortDateString"
|
||||
|
@ -118,9 +118,8 @@
|
|||
</div>
|
||||
</var:foreach>
|
||||
<sg-calendar-day-table
|
||||
sg-click="list.openEvent(event, component)"
|
||||
sg-blocks="view.blocks"
|
||||
var:sg-day-number="currentDayNumber"
|
||||
sg-click="list.openEvent(event, component)"
|
||||
var:sg-day="currentTableDay.shortDateString"><!-- blocks for current day --></sg-calendar-day-table>
|
||||
<sg-calendar-day-block
|
||||
sg-calendar-ghost="sg-calendar-ghost"
|
||||
|
|
|
@ -10,17 +10,18 @@
|
|||
<md-card>
|
||||
<md-card-actions flex-none="flex-none" layout="row" layout-align="start center">
|
||||
<md-button class="md-icon-button"
|
||||
label:aria-label="Previous Day"
|
||||
var:aria-label="yesterdayName"
|
||||
var:date="prevDayQueryParameters.day"
|
||||
ng-click="calendar.changeDate($event)"><md-icon>chevron_left</md-icon></md-button>
|
||||
<md-button class="md-icon-button"
|
||||
label:aria-label="Next Day"
|
||||
var:aria-label="tomorrowName"
|
||||
var:date="nextDayQueryParameters.day"
|
||||
ng-click="calendar.changeDate($event)"><md-icon>chevron_right</md-icon></md-button>
|
||||
<div class="md-flex"><var:string value="currentDayName" /></div>
|
||||
<md-button class="md-icon-button md-accent"
|
||||
label:aria-label="Today"
|
||||
ng-click="app.today()">
|
||||
var:date="todayQueryParameters.day"
|
||||
ng-click="calendar.changeDate($event)">
|
||||
<md-tooltip><var:string label:value="Today"/></md-tooltip>
|
||||
<md-icon>today</md-icon>
|
||||
</md-button>
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
<div class="md-flex"><var:string value="monthNameOfThisMonth" /> <var:string value="selectedDate.yearOfCommonEra" /></div>
|
||||
<md-button class="md-icon-button md-accent"
|
||||
label:aria-label="Today"
|
||||
ng-click="app.today()">
|
||||
var:date="todayQueryParameters.day"
|
||||
ng-click="calendar.changeDate($event)">
|
||||
<md-tooltip><var:string label:value="Today"/></md-tooltip>
|
||||
<md-icon>today</md-icon>
|
||||
</md-button>
|
||||
|
@ -51,7 +52,7 @@
|
|||
<md-content class="md-flex" sg-calendar-scroll-view="monthly">
|
||||
<div class="calendarView monthView">
|
||||
<md-grid-list
|
||||
md-cols="7"
|
||||
var:md-cols="headerDaysToDisplay.count"
|
||||
md-row-height="1:1"
|
||||
md-gutter="0">
|
||||
<var:foreach list="weeksToDisplay" item="currentWeek">
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
<md-card>
|
||||
<md-card-actions flex-none="flex-none" layout="row" layout-align="start center">
|
||||
<md-button class="md-icon-button"
|
||||
label:aria-label="Previous Day"
|
||||
var:aria-label="yesterdayName"
|
||||
var:date="prevDayQueryParameters.day"
|
||||
ng-click="calendar.changeDate($event)"><md-icon>chevron_left</md-icon></md-button>
|
||||
<md-button class="md-icon-button"
|
||||
label:aria-label="Next Day"
|
||||
var:aria-label="tomorrowName"
|
||||
var:date="nextDayQueryParameters.day"
|
||||
ng-click="calendar.changeDate($event)"><md-icon>chevron_right</md-icon></md-button>
|
||||
<div class="md-flex"><var:string value="currentDayName" /></div>
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
<div class="md-flex"><var:string value="currentWeekName" /></div>
|
||||
<md-button class="md-icon-button md-accent"
|
||||
label:aria-label="Today"
|
||||
ng-click="app.today()">
|
||||
var:date="todayQueryParameters.day"
|
||||
ng-click="calendar.changeDate($event)">
|
||||
<md-tooltip><var:string label:value="Today"/></md-tooltip>
|
||||
<md-icon>today</md-icon>
|
||||
</md-button>
|
||||
|
|
|
@ -51,8 +51,8 @@
|
|||
}
|
||||
angular.module('SOGo.SchedulerUI')
|
||||
.value('CalendarSettings', {
|
||||
EventDragDayLength: 24 * 4,
|
||||
EventDragHorizontalOffset: 3
|
||||
EventDragDayLength: 24 * 4, // hour quarters
|
||||
EventDragHorizontalOffset: 3 // pixels
|
||||
})
|
||||
.factory('Calendar', Calendar.$factory);
|
||||
|
||||
|
|
|
@ -281,7 +281,7 @@
|
|||
* @returns a promise of a collection of objects describing the events blocks
|
||||
*/
|
||||
Component.$eventsBlocks = function(view, startDate, endDate) {
|
||||
var params, futureComponentData, i, j, dates = [],
|
||||
var params, futureComponentData, i, j, dayDates = [], dayNumbers = [],
|
||||
deferred = Component.$q.defer();
|
||||
|
||||
params = { view: view.toLowerCase(), sd: startDate.getDayString(), ed: endDate.getDayString() };
|
||||
|
@ -306,7 +306,7 @@
|
|||
|
||||
Component.$views = [];
|
||||
Component.$timeout(function() {
|
||||
_.forEach(views, function(data) {
|
||||
_.forEach(views, function(data, viewIndex) {
|
||||
var components = [], blocks = {}, allDayBlocks = {}, viewData;
|
||||
|
||||
// Change some attributes names
|
||||
|
@ -325,24 +325,27 @@
|
|||
_.forEach(_.flatten(data.allDayBlocks), _.bind(associateComponent, components));
|
||||
|
||||
// Build array of dates
|
||||
if (dates.length === 0)
|
||||
for (i = 0; i < data.blocks.length; i++) {
|
||||
dates.push(startDate.getDayString());
|
||||
startDate.addDays(1);
|
||||
}
|
||||
if (dayDates.length === 0) {
|
||||
dayDates = _.flatMap(data.days, 'date');
|
||||
dayNumbers = _.flatMap(data.days, 'number');
|
||||
}
|
||||
|
||||
// Convert array of blocks to object with days as keys
|
||||
// Convert array of blocks to an object literal with date strings as keys
|
||||
for (i = 0; i < data.blocks.length; i++) {
|
||||
for (j = 0; j < data.blocks[i].length; j++)
|
||||
data.blocks[i][j].dayNumber = i;
|
||||
blocks[dates[i]] = data.blocks[i];
|
||||
for (j = 0; j < data.blocks[i].length; j++) {
|
||||
data.blocks[i][j].dayIndex = i + (viewIndex * data.blocks.length);
|
||||
data.blocks[i][j].dayNumber = dayNumbers[i];
|
||||
}
|
||||
blocks[dayDates[i]] = data.blocks[i];
|
||||
}
|
||||
|
||||
// Convert array of all-day blocks to object with days as keys
|
||||
for (i = 0; i < data.allDayBlocks.length; i++) {
|
||||
for (j = 0; j < data.allDayBlocks[i].length; j++)
|
||||
data.allDayBlocks[i][j].dayNumber = i;
|
||||
allDayBlocks[dates[i]] = data.allDayBlocks[i];
|
||||
for (j = 0; j < data.allDayBlocks[i].length; j++) {
|
||||
data.allDayBlocks[i][j].dayIndex = i + (viewIndex * data.allDayBlocks.length);
|
||||
data.allDayBlocks[i][j].dayNumber = dayNumbers[i];
|
||||
}
|
||||
allDayBlocks[dayDates[i]] = data.allDayBlocks[i];
|
||||
}
|
||||
|
||||
// "blocks" is now an object literal with the following structure:
|
||||
|
@ -1057,7 +1060,7 @@
|
|||
var _this = this, options, path, component, date, dlp;
|
||||
|
||||
component = this.$omit();
|
||||
dlp = Component.$Preferences.constructor.$mdDateLocaleProvider;
|
||||
dlp = Component.$Preferences.$mdDateLocaleProvider;
|
||||
|
||||
// Format dates and times
|
||||
component.startDate = component.start ? component.start.format(dlp, '%Y-%m-%d') : '';
|
||||
|
|
|
@ -123,6 +123,17 @@
|
|||
url += view[1];
|
||||
else
|
||||
url += 'week';
|
||||
// Append today's date or next enabled weekday
|
||||
var now = new Date();
|
||||
if (Preferences.defaults.SOGoCalendarWeekdays) {
|
||||
var weekDays = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'];
|
||||
var weekDay = weekDays[now.getDay()];
|
||||
while (Preferences.defaults.SOGoCalendarWeekdays.indexOf(weekDay) < 0) {
|
||||
now.addDays(1);
|
||||
weekDay = weekDays[now.getDay()];
|
||||
}
|
||||
}
|
||||
url += '/' + now.getDayString();
|
||||
$location.replace().url(url);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
|
||||
function updateGhost() {
|
||||
// From SOGoEventDragGhostController._updateGhosts
|
||||
var showGhost, isRelative, originalDay, currentDay, wasOtherBlock,
|
||||
var showGhost, isRelative, currentDay, wasOtherBlock,
|
||||
start, duration, durationLeft, maxDuration, enableTransition;
|
||||
|
||||
showGhost = false;
|
||||
|
@ -95,7 +95,6 @@
|
|||
// The view of the dragging block is the scrolling view of this ghost block
|
||||
|
||||
isRelative = scrollViewCtrl.type === 'multiday-allday';
|
||||
originalDay = scope.block.pointerHandler.originalEventCoordinates.dayNumber;
|
||||
currentDay = scope.block.pointerHandler.currentEventCoordinates.dayNumber;
|
||||
start = scope.block.pointerHandler.currentEventCoordinates.start;
|
||||
durationLeft = scope.block.pointerHandler.currentEventCoordinates.duration;
|
||||
|
@ -103,7 +102,6 @@
|
|||
|
||||
if (angular.isUndefined(durationLeft))
|
||||
return;
|
||||
|
||||
duration = durationLeft;
|
||||
if (duration > maxDuration)
|
||||
duration = maxDuration;
|
||||
|
@ -118,7 +116,7 @@
|
|||
)) {
|
||||
// This ghost block (day) is the first of the dragging event
|
||||
showGhost = true;
|
||||
if (!isRelative) {
|
||||
if (!isRelative) {
|
||||
// Show start hour and set the vertical position
|
||||
scope.block.startHour = getStartTime(start);
|
||||
wasOtherBlock = parseInt(iElement.css('top')) === 0;
|
||||
|
|
|
@ -25,11 +25,13 @@
|
|||
},
|
||||
controller: sgCalendarScrollViewController,
|
||||
link: function(scope, element, attrs, controller) {
|
||||
var view, scrollView, type, lastScroll, deregisterDragStart, deregisterDragStop;
|
||||
var view, scrollView, type, lastScroll, days, deregisterDragStart, deregisterDragStop;
|
||||
|
||||
view = null;
|
||||
scrollView = element[0];
|
||||
type = scope.type; // multiday, multiday-allday, monthly, unknown?
|
||||
lastScroll = 0;
|
||||
days = null;
|
||||
|
||||
// Listen to dragstart and dragend events
|
||||
deregisterDragStart = $rootScope.$on('calendar:dragstart', onDragStart);
|
||||
|
@ -56,6 +58,7 @@
|
|||
type: type,
|
||||
quarterHeight: quarterHeight,
|
||||
scrollStep: 6 * quarterHeight,
|
||||
dayNumbers: getDayNumbers(),
|
||||
maxX: getMaxColumns(),
|
||||
|
||||
// Expose a reference of the view element
|
||||
|
@ -94,7 +97,7 @@
|
|||
var width, height, leftOffset, topOffset, nodes, domRect, tileHeader;
|
||||
|
||||
height = width = leftOffset = topOffset = 0;
|
||||
nodes = scrollView.getElementsByClassName('day0');
|
||||
nodes = scrollView.getElementsByClassName('day');
|
||||
|
||||
if (nodes.length > 0) {
|
||||
domRect = nodes[0].getBoundingClientRect();
|
||||
|
@ -109,6 +112,22 @@
|
|||
return { height: height, width: width, offset: { left: leftOffset, top: topOffset } };
|
||||
}
|
||||
|
||||
function getDayNumbers() {
|
||||
var viewType = null, isMultiColumn, days, total, sum;
|
||||
|
||||
if (scrollView.attributes['sg-view'])
|
||||
viewType = scrollView.attributes['sg-view'].value;
|
||||
isMultiColumn = (viewType == 'multicolumndayview');
|
||||
days = scrollView.getElementsByTagName('sg-calendar-day');
|
||||
|
||||
return _.map(days, function(element, index) {
|
||||
if (isMultiColumn)
|
||||
return index;
|
||||
else
|
||||
return parseInt(element.attributes['sg-day-number'].value);
|
||||
});
|
||||
}
|
||||
|
||||
function getMaxColumns() {
|
||||
var max = 0;
|
||||
|
||||
|
@ -153,9 +172,9 @@
|
|||
function updateFromPointerHandler() {
|
||||
var scrollStep, pointerHandler, pointerCoordinates, now, scrollY, minY, delta;
|
||||
|
||||
scrollStep = view.scrollStep;
|
||||
pointerHandler = Component.$ghost.pointerHandler;
|
||||
if (pointerHandler) {
|
||||
if (view && pointerHandler) {
|
||||
scrollStep = view.scrollStep;
|
||||
pointerCoordinates = pointerHandler.getContainerBasedCoordinates(view);
|
||||
|
||||
if (pointerCoordinates) {
|
||||
|
|
|
@ -42,12 +42,12 @@
|
|||
});
|
||||
|
||||
function initGrips() {
|
||||
var component, dayNumber, blockIndex, isFirstBlock, isLastBlock,
|
||||
var component, dayIndex, blockIndex, isFirstBlock, isLastBlock,
|
||||
dragGrip, leftGrip, rightGrip, topGrip, bottomGrip;
|
||||
|
||||
component = scope.block.component;
|
||||
dayNumber = scope.block.dayNumber;
|
||||
blockIndex = _.findIndex(component.blocks, ['dayNumber', dayNumber]);
|
||||
dayIndex = scope.block.dayIndex;
|
||||
blockIndex = _.findIndex(component.blocks, ['dayIndex', dayIndex]);
|
||||
isFirstBlock = (blockIndex === 0);
|
||||
isLastBlock = (blockIndex === component.blocks.length - 1);
|
||||
|
||||
|
@ -78,12 +78,12 @@
|
|||
}
|
||||
|
||||
function onDragDetect(ev) {
|
||||
var block, dragMode, eventType, startDate, newData, newComponent, pointerHandler;
|
||||
var dragMode, pointerHandler;
|
||||
|
||||
ev.stopPropagation();
|
||||
|
||||
dragMode = 'move-event';
|
||||
|
||||
|
||||
if (scope.block && scope.block.component) {
|
||||
// Move or resize existing component
|
||||
if (ev.target.className == 'dragGrip-top' ||
|
||||
|
@ -220,6 +220,10 @@
|
|||
delta.x = this.x - otherCoordinates.x;
|
||||
delta.y = this.y - otherCoordinates.y;
|
||||
|
||||
if (Calendar.$view) {
|
||||
delta.days = Calendar.$view.dayNumbers[this.x] - Calendar.$view.dayNumbers[otherCoordinates.x];
|
||||
}
|
||||
|
||||
return delta;
|
||||
},
|
||||
|
||||
|
@ -247,6 +251,7 @@
|
|||
|
||||
SOGoEventDragEventCoordinates.prototype = {
|
||||
dayNumber: -1,
|
||||
weekDay: -1,
|
||||
start: -1,
|
||||
duration: -1,
|
||||
|
||||
|
@ -257,21 +262,29 @@
|
|||
},
|
||||
|
||||
initFromBlock: function(block) {
|
||||
var prevDayNumber = -1;
|
||||
|
||||
if (this.eventType === 'monthly') {
|
||||
this.start = 0;
|
||||
this.duration = block.component.blocks.length * 96;
|
||||
this.duration = block.component.blocks.length * CalendarSettings.EventDragDayLength;
|
||||
}
|
||||
else {
|
||||
// Get the start (first quarter) from the event's first block
|
||||
// Compute overall length
|
||||
this.start = block.component.blocks[0].start;
|
||||
this.duration = _.sumBy(block.component.blocks, function(b) {
|
||||
return b.length;
|
||||
var delta, currentDayNumber;
|
||||
|
||||
currentDayNumber = b.dayNumber;
|
||||
if (prevDayNumber < 0)
|
||||
delta = 0;
|
||||
else
|
||||
delta = currentDayNumber - prevDayNumber - 1;
|
||||
prevDayNumber = currentDayNumber;
|
||||
|
||||
return b.length + delta * CalendarSettings.EventDragDayLength;
|
||||
});
|
||||
}
|
||||
|
||||
// Get the dayNumber from the event's first block
|
||||
this.dayNumber = block.component.blocks[0].dayNumber;
|
||||
},
|
||||
|
||||
initFromCalendar: function(calendarNumber) {
|
||||
|
@ -411,13 +424,17 @@
|
|||
|
||||
// Compute delta wrt to position of mouse at dragstart on the day/quarter grid
|
||||
var delta = this.currentViewCoordinates.getDelta(this.originalViewCoordinates);
|
||||
var deltaQuarters = delta.x * CalendarSettings.EventDragDayLength + delta.y;
|
||||
var deltaQuarters = delta.days * CalendarSettings.EventDragDayLength + delta.y;
|
||||
$log.debug('quarters delta ' + deltaQuarters);
|
||||
|
||||
if (angular.isUndefined(this.originalEventCoordinates.start)) {
|
||||
this.originalEventCoordinates.dayNumber = this.originalViewCoordinates.x;
|
||||
// Creating new appointment from DnD
|
||||
this.originalEventCoordinates.dayNumber = Calendar.$view.dayNumbers[this.originalViewCoordinates.x];
|
||||
this.originalEventCoordinates.start = this.originalViewCoordinates.y;
|
||||
}
|
||||
else if (this.originalEventCoordinates.dayNumber < 0) {
|
||||
this.originalEventCoordinates.dayNumber = Calendar.$view.dayNumbers[scope.block.component.blocks[0].dayIndex];
|
||||
}
|
||||
// if (currentView == "multicolumndayview")
|
||||
// this._updateMulticolumnViewDayNumber_SEDGC();
|
||||
// else
|
||||
|
@ -461,12 +478,9 @@
|
|||
else if (this.currentEventCoordinates.start >= CalendarSettings.EventDragDayLength) {
|
||||
deltaDays = Math.floor(this.currentEventCoordinates.start / CalendarSettings.EventDragDayLength);
|
||||
this.currentEventCoordinates.start -= deltaDays * CalendarSettings.EventDragDayLength;
|
||||
|
||||
// This dayNumber needs to be updated with the calendar number.
|
||||
// if (currentView == "multicolumndayview")
|
||||
// this._updateMulticolumnViewDayNumber_SEDGC();
|
||||
this.currentEventCoordinates.dayNumber += deltaDays;
|
||||
}
|
||||
|
||||
$log.debug('event coordinates ' + JSON.stringify(this.currentEventCoordinates));
|
||||
$rootScope.$emit('calendar:drag');
|
||||
},
|
||||
|
|
|
@ -155,6 +155,7 @@ $quarter_height: 10px;
|
|||
// Contains the toggle button to collapse/expand the toolbar
|
||||
.allDaysView--sidenav {
|
||||
border-bottom: 1px solid sg-color($sogoPaper, 300);
|
||||
min-width: $hours_margin;
|
||||
width: $hours_margin;
|
||||
.md-icon-button {
|
||||
position: absolute;
|
||||
|
|
Loading…
Reference in New Issue