merge of '36ced261cec8f0a229c4466b8b7c0a78dd1a408e'

and '9c818b369358da0b25cfcd319b9f6f2d319fb99d'

Monotone-Parent: 36ced261cec8f0a229c4466b8b7c0a78dd1a408e
Monotone-Parent: 9c818b369358da0b25cfcd319b9f6f2d319fb99d
Monotone-Revision: 3351ea272262d02bca8c04d35cc8b34b0a42118e

Monotone-Author: crobert@inverse.ca
Monotone-Date: 2009-03-25T15:15:20
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
C Robert committed 2009-03-25 15:15:20 +00:00
commit 56df95bbac
56 files changed
+1028 -597

No files matched your search

+19 -11
View File
@@ -21,6 +21,7 @@
*/
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSEnumerator.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGObjWeb/WOResponse.h>
@@ -41,6 +42,7 @@
#import <SoObjects/Appointments/SOGoAppointmentObject.h>
#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
#import <SoObjects/Mailer/SOGoMailObject.h>
#import <SoObjects/SOGo/SOGoParentFolder.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/iCalEntityObject+Utilities.h>
#import <SoObjects/Mailer/SOGoMailBodyPart.h>
@@ -69,27 +71,33 @@
- (SOGoAppointmentObject *) _eventObjectWithUID: (NSString *) uid
forUser: (SOGoUser *) user
{
SOGoAppointmentFolder *personalFolder;
SOGoAppointmentFolder *folder;
SOGoAppointmentObject *eventObject;
NSArray *folders;
NSEnumerator *e;
NSString *cname;
eventObject = nil;
#warning Should call lookupCalendarFoldersForUIDs to search among all folders
personalFolder = [user personalCalendarFolderInContext: context];
cname = [personalFolder resourceNameForEventUID: uid];
if (cname)
folders = [[user calendarsFolderInContext: context] subFolders];
e = [folders objectEnumerator];
while ( eventObject == nil && (folder = [e nextObject]) )
{
eventObject = [personalFolder lookupName: cname
inContext: context acquire: NO];
if (![eventObject isKindOfClass: [SOGoAppointmentObject class]])
eventObject = nil;
cname = [folder resourceNameForEventUID: uid];
if (cname)
{
eventObject = [folder lookupName: cname
inContext: context acquire: NO];
if (![eventObject isKindOfClass: [SOGoAppointmentObject class]])
eventObject = nil;
}
}
if (!eventObject)
{
folder = [user personalCalendarFolderInContext: context];
eventObject = [SOGoAppointmentObject objectWithName: uid
inContainer: personalFolder];
inContainer: folder];
[eventObject setIsNew: YES];
}
+36 -5
View File
@@ -164,7 +164,7 @@
return item;
}
- (NSCalendarDate *) startTime
- (NSCalendarDate *) startCalendarDate
{
NSCalendarDate *date;
NSTimeZone *timeZone;
@@ -172,11 +172,21 @@
date = [[self inEvent] startDate];
timeZone = [[context activeUser] timeZone];
[date setTimeZone: timeZone];
return date;
}
- (NSCalendarDate *) endTime
- (NSString *) startDate
{
return [[self dateFormatter] formattedDate: [self startCalendarDate]];
}
- (NSString *) startTime
{
return [[self dateFormatter] formattedTime: [self startCalendarDate]];
}
- (NSCalendarDate *) endCalendarDate
{
NSCalendarDate *date;
NSTimeZone *timeZone;
@@ -188,14 +198,35 @@
return date;
}
- (NSString *) endDate
{
NSCalendarDate *aDate;
if ([[self inEvent] isAllDay])
aDate = [[self endCalendarDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 seconds:-1];
else
aDate = [self endCalendarDate];
return [[self dateFormatter] formattedDate: aDate];
}
- (NSString *) endTime
{
return [[self dateFormatter] formattedTime: [self endCalendarDate]];
}
- (BOOL) isEndDateOnSameDay
{
return [[self startTime] isDateOnSameDay:[self endTime]];
NSCalendarDate *aDate;
if ([[self inEvent] isAllDay])
aDate = [[self endCalendarDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 seconds:-1];
else
aDate = [self endCalendarDate];
return [[self startCalendarDate] isDateOnSameDay: aDate];
}
- (NSTimeInterval) duration
{
return [[self endTime] timeIntervalSinceDate:[self startTime]];
return [[self endCalendarDate] timeIntervalSinceDate:[self startCalendarDate]];
}
/* calendar folder support */
+31 -18
View File
@@ -1,14 +1,15 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
Copyright (C) 2006-2009 Inverse inc.
This file is part of OpenGroupware.org.
This file is part of SOGo
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.
@@ -459,21 +460,26 @@
- (NSArray *) messages
{
NSMutableArray *unsortedMsgs;
NSMutableDictionary *map;
NSDictionary *msgs;
NSArray *uids;
NSDictionary *msgs, *msg;
NSEnumerator *msgsList;
NSMutableArray *unsortedMsgs, *sortedMsgs;
unsigned len, i, count;
NSRange r;
unsigned len, index;
if (!messages)
{
r = [self fetchBlock];
r = [self fetchBlock];
uids = [self sortedUIDs];
len = [uids count];
// only need to restrict if we have a lot
if (len > r.length)
/* only need to restrict if we have a lot */
{
uids = [uids subarrayWithRange: r];
len = [uids count];
}
// Don't assume the IMAP server return the messages in the
// same order as the specified list of UIDs (specially true for
@@ -481,17 +487,24 @@
msgs = (NSDictionary *) [[self clientObject] fetchUIDs: uids
parts: [self fetchKeys]];
unsortedMsgs = [msgs objectForKey: @"fetch"];
sortedMsgs = [NSMutableArray arrayWithCapacity: [unsortedMsgs count]];
msgsList = [unsortedMsgs objectEnumerator];
while ( (msg = [msgsList nextObject]) )
count = [unsortedMsgs count];
messages = [NSMutableArray arrayWithCapacity: count];
// We build our uid->message map from our FETCH response
map = [[NSMutableDictionary alloc] initWithCapacity: count];
for (i = 0; i < count; i++)
[map setObject: [unsortedMsgs objectAtIndex: i]
forKey: [[unsortedMsgs objectAtIndex: i] objectForKey: @"uid"]];
for (i = 0; i < len; i++)
{
index = [uids indexOfObject: [msg objectForKey: @"uid"]];
if (index < [sortedMsgs count])
[sortedMsgs insertObject: msg atIndex: index];
else
[sortedMsgs addObject: msg];
[(NSMutableArray *)messages addObject: [map objectForKey: [uids objectAtIndex: i]]];
}
messages = [[NSArray arrayWithArray: sortedMsgs] retain];
RELEASE(map);
RETAIN(messages);
}
return messages;
+1
View File
@@ -96,6 +96,7 @@ static NSArray *supportedLanguages = nil;
user = [SOGoUser userWithLogin: userName roles: nil];
[[user userDefaults] setObject: language forKey: @"Language"];
[[user userDefaults] synchronize];
[user invalidateLanguage];
}
}
else
+1 -1
View File
@@ -1,5 +1,5 @@
# Version file
SUBMINOR_VERSION:=0
SUBMINOR_VERSION:=1
# v0.9.1 requires Main v0.9.59
+1 -3
View File
@@ -90,7 +90,7 @@ static NSArray *tasksFields = nil;
endDate = nil;
ASSIGN (request, newRequest);
user = [[self context] activeUser];
dateFormatter = [user dateFormatterInContext: context];
ASSIGN (dateFormatter, [user dateFormatterInContext: context]);
ASSIGN (userTimeZone, [user timeZone]);
dayBasedView = NO;
}
@@ -103,8 +103,6 @@ static NSArray *tasksFields = nil;
[dateFormatter release];
[request release];
[componentsData release];
[startDate release];
[endDate release];
[userTimeZone release];
[super dealloc];
}
+6 -11
View File
@@ -40,9 +40,6 @@
#import <Appointments/SOGoAppointmentFolder.h>
static NSMutableArray *monthMenuItems = nil;
static NSMutableArray *yearMenuItems = nil;
@implementation UIxCalMainView
- (void) _setupContext
@@ -60,24 +57,22 @@ static NSMutableArray *yearMenuItems = nil;
moduleSettings = [ud objectForKey: module];
if (!moduleSettings)
{
moduleSettings = [NSMutableDictionary new];
[moduleSettings autorelease];
moduleSettings = [NSMutableDictionary dictionary];
[ud setObject: moduleSettings forKey: module];
}
[ud setObject: moduleSettings forKey: module];
}
- (NSArray *) monthMenuItems
{
static NSMutableArray *monthMenuItems = nil;
unsigned int count;
if (!monthMenuItems)
{
monthMenuItems = [NSMutableArray arrayWithCapacity: 12];
monthMenuItems = [[NSMutableArray alloc] initWithCapacity: 12];
for (count = 1; count < 13; count++)
[monthMenuItems addObject:
[NSString stringWithFormat: @"%.2d", count]];
[monthMenuItems retain];
}
return monthMenuItems;
@@ -100,15 +95,15 @@ static NSMutableArray *yearMenuItems = nil;
- (NSArray *) yearMenuItems
{
static NSMutableArray *yearMenuItems = nil;
int count, year;
if (!yearMenuItems)
{
year = [[NSCalendarDate date] yearOfCommonEra];
yearMenuItems = [NSMutableArray arrayWithCapacity: 11];
yearMenuItems = [[NSMutableArray alloc] initWithCapacity: 11];
for (count = -5; count < 6; count++)
[yearMenuItems addObject: [NSNumber numberWithInt: year + count]];
[yearMenuItems retain];
}
return yearMenuItems;
+81 -60
View File
@@ -94,16 +94,18 @@ iRANGE(2);
- (id) init
{
UIxDatePicker *datePicker;
if ((self = [super init]))
{
UIxDatePicker *datePicker;
// We must instanciate a UIxDatePicker object to retrieve
// the proper date format to use.
datePicker = [[UIxDatePicker alloc] initWithContext: context];
dateFormat = [datePicker dateFormat];
[datePicker release];
component = nil;
componentCalendar = nil;
[self setPrivacy: @"PUBLIC"];
[self setIsCycleEndNever];
componentOwner = @"";
@@ -126,8 +128,6 @@ iRANGE(2);
repeat7 = nil;
range1 = nil;
range2 = nil;
[datePicker release];
}
return self;
@@ -166,8 +166,9 @@ iRANGE(2);
[repeat7 release];
[range1 release];
[range2 release];
[component release];
[componentCalendar release];
[super dealloc];
}
@@ -180,10 +181,10 @@ iRANGE(2);
NSString *uid;
LDAPUserManager *um;
names = [NSMutableString new];
uids = [NSMutableString new];
emails = [NSMutableString new];
states = [NSMutableString new];
names = [NSMutableString string];
uids = [NSMutableString string];
emails = [NSMutableString string];
states = [NSMutableString string];
um = [LDAPUserManager sharedUserManager];
attendees = [[component attendees] objectEnumerator];
@@ -193,7 +194,7 @@ iRANGE(2);
[names appendFormat: @"%@,", [currentAttendee cn]];
else
[names appendFormat: @"%@,", [currentAttendee rfc822Email]];
[emails appendFormat: @"%@,", [currentAttendee rfc822Email]];
uid = [um getUIDForEmail: [currentAttendee rfc822Email]];
if (uid != nil)
@@ -212,9 +213,6 @@ iRANGE(2);
[emails substringToIndex: [emails length] - 1]);
ASSIGN (attendeesStates, [states substringToIndex: [states length] - 1]);
}
[names release];
[emails release];
}
- (void) _loadCategories
@@ -364,7 +362,12 @@ iRANGE(2);
[self setRange1: @"0"];
}
else
DESTROY(repeat);
{
DESTROY(repeat);
repeatType = @"0";
repeat1 = @"0";
repeat2 = @"1";
}
}
/* warning: we use this method which will be triggered by the template system
@@ -397,7 +400,7 @@ iRANGE(2);
[self _loadAttendees];
[self _loadRRules];
[componentCalendar release];
[componentCalendar release];
componentCalendar = [co container];
if ([componentCalendar isKindOfClass: [SOGoCalendarComponent class]])
componentCalendar = [componentCalendar container];
@@ -1435,19 +1438,22 @@ RANGE(2);
//
case 0:
{
[theRule setFrequency: iCalRecurrenceFrequenceDaily];
if ([[self repeat2] intValue] > 0)
{
[theRule setFrequency: iCalRecurrenceFrequenceDaily];
if ([[self repeat1] intValue] == 0)
{
[theRule setInterval: [self repeat2]];
}
else
{
[theRule setByDayMask: (iCalWeekDayMonday
|iCalWeekDayTuesday
|iCalWeekDayWednesday
|iCalWeekDayThursday
|iCalWeekDayFriday)];
if ([[self repeat1] intValue] == 0)
{
[theRule setInterval: [self repeat2]];
}
else
{
[theRule setByDayMask: (iCalWeekDayMonday
|iCalWeekDayTuesday
|iCalWeekDayWednesday
|iCalWeekDayThursday
|iCalWeekDayFriday)];
}
}
}
break;
@@ -1462,20 +1468,23 @@ RANGE(2);
// The list is separated by commas, like: 1,3,4
case 1:
{
NSArray *v;
int c, mask;
if ([[self repeat1] intValue] > 0)
{
NSArray *v;
int c, mask;
[theRule setFrequency: iCalRecurrenceFrequenceWeekly];
[theRule setInterval: [self repeat1]];
[theRule setFrequency: iCalRecurrenceFrequenceWeekly];
[theRule setInterval: [self repeat1]];
v = [[self repeat2] componentsSeparatedByString: @","];
c = [v count];
mask = 0;
v = [[self repeat2] componentsSeparatedByString: @","];
c = [v count];
mask = 0;
while (c--)
mask |= 1 << ([[v objectAtIndex: c] intValue]);
while (c--)
mask |= 1 << ([[v objectAtIndex: c] intValue]);
[theRule setByDayMask: mask];
[theRule setByDayMask: mask];
}
}
break;
@@ -1501,17 +1510,21 @@ RANGE(2);
//
case 2:
{
[theRule setFrequency: iCalRecurrenceFrequenceMonthly];
[theRule setInterval: [self repeat1]];
if ([[self repeat1] intValue] > 0)
{
[theRule setFrequency: iCalRecurrenceFrequenceMonthly];
[theRule setInterval: [self repeat1]];
// We recur on specific days...
if ([[self repeat2] intValue] == 1)
{
[theRule setNamedValue: @"bymonthday" to: [self repeat5]];
}
else
{
// TODO
// We recur on specific days...
if ([[self repeat2] intValue] == 1
&& [[self repeat5] intValue] > 0)
{
[theRule setNamedValue: @"bymonthday" to: [self repeat5]];
}
else
{
// TODO
}
}
}
break;
@@ -1535,19 +1548,27 @@ RANGE(2);
case 3:
default:
{
[theRule setFrequency: iCalRecurrenceFrequenceYearly];
[theRule setInterval: [self repeat1]];
if ([[self repeat1] intValue] > 0)
{
[theRule setFrequency: iCalRecurrenceFrequenceYearly];
[theRule setInterval: [self repeat1]];
// We recur Every .. of ..
if ([[self repeat2] intValue] == 1)
{
// TODO
}
else
{
[theRule setNamedValue: @"bymonthday" to: [self repeat3]];
[theRule setNamedValue: @"bymonth"
to: [NSString stringWithFormat: @"%d", ([[self repeat4] intValue]+1)]];
// We recur Every .. of ..
if ([[self repeat2] intValue] == 1)
{
// TODO
}
else
{
if ([[self repeat3] intValue] > 0
&& [[self repeat4] intValue] > 0)
{
[theRule setNamedValue: @"bymonthday"
to: [self repeat3]];
[theRule setNamedValue: @"bymonth"
to: [NSString stringWithFormat: @"%d", ([[self repeat4] intValue]+1)]];
}
}
}
}
break;
+1 -8
View File
@@ -29,13 +29,6 @@
@implementation UIxRecurrenceEditor
- (id) defaultAction
{
[[self parent] setToolbar: @""];
return self;
}
- (NSArray *) monthlyRepeatList
{
static NSArray *monthlyRepeatList = nil;
@@ -43,7 +36,7 @@
if (!monthlyRepeatList)
{
monthlyRepeatList = [NSArray arrayWithObjects: @"First", @"Second", @"Third",
@"Fourth", @"Fift", @"Last", nil];
@"Fourth", @"Fift", @"Last", nil];
[monthlyRepeatList retain];
}
@@ -167,9 +167,23 @@
<td><var:string label:value="Time"/>:</td>
<td>
<!-- TODO: we need a better viewer for that -->
<var:string value="startTime" formatter="dateFormatter" />
<var:string label:value="to" />
<var:string value="endTime" formatter="dateFormatter" />
<var:string value="startDate" />
<var:if condition="inEvent.isAllDay" const:negate="YES">
<var:string value="startTime" />
</var:if>
<var:if condition="isEndDateOnSameDay">
<var:if condition="inEvent.isAllDay" const:negate="YES">
<var:string label:value="to" />
<var:string value="endTime" />
</var:if>
</var:if>
<var:if condition="isEndDateOnSameDay" const:negate="YES">
<var:string label:value="to" />
<var:string value="endDate" />
<var:if condition="inEvent.isAllDay" const:negate="YES">
<var:string value="endTime" />
</var:if>
</var:if>
</td>
</tr>
+1 -1
View File
@@ -2,7 +2,7 @@
include ../common.make
WEBSERVER_RESOURCE_FILES = $(shell ls *css *ico *js *.jpg *gif *png *html *txt)
WEBSERVER_RESOURCE_FILES = $(shell ls *css *ico *js *gif *png *html *txt)
all ::
+68 -23
View File
@@ -86,10 +86,20 @@ function initializeFormValues() {
$("repeatType").value = repeatType;
// Default values
var startTimeDate = parent$("startTime_date").value.asDate();
$('yearlyDayField').value = startTimeDate.getDate();
$('yearlyMonth1').value = startTimeDate.getMonth();
$("weekDay"+startTimeDate.getDay()).addClassName("_selected");
$("monthDay"+startTimeDate.getDate()).addClassName("_selected");
$('recurrence_form').setRadioValue('dailyRadioButtonName', 0);
$('recurrence_form').setRadioValue('monthlyRadioButtonName', 0);
$('recurrence_form').setRadioValue('monthlyRadioButtonName', 1);
$('recurrence_form').setRadioValue('yearlyRadioButtonName', 0);
$('endDate_date').disabled = true;
$('dailyDaysField').value = "1";
$('weeklyWeeksField').value = "1";
$('monthlyMonthsField').value = "1";
$('yearlyYearsField').value = "1";
if (repeatType == 0) {
// Repeat daily
@@ -101,6 +111,9 @@ function initializeFormValues() {
$('weeklyWeeksField').value = parent$("repeat1").value;
// log ("div: " + weekDiv);
// log ("days: " + parent$("repeat2").value);
for (var i = 0; i < 7; i++) {
$("weekDay" + i).removeClassName("_selected");
}
var days = "" + parent$("repeat2").value;
if (days.length > 0) {
var daysArray = days.split(",");
@@ -116,6 +129,10 @@ function initializeFormValues() {
$('monthlyRepeat').value = parent$("repeat3").value;
$('monthlyDay').value = parent$("repeat4").value;
var days = "" + parent$("repeat5").value;
for (var i = 0; i < 31; i++) {
$("monthDay" + (i + 1)).removeClassName("_selected");
}
if (days.length > 0) {
var daysArray = days.split(",");
daysArray.each(function(index) {
@@ -253,37 +270,65 @@ function handleMonthlyRecurrence() {
return validate;
}
function validateYearlyRecurrence() {
var errors = ["Please specify a numerical value in the Year(s)"
+ " field greater or equal to 1.",
"Please specify a numerical value in the month day"
+ " field greater or equal to 1."];
var errorToShow = 0;
var fieldValue = "" + $('yearlyYearsField').value;
if (fieldValue.length > 0) {
// We check if the yearlyYearsField really contains an integer
var v = parseInt(fieldValue);
if (!isNaN(v) && v > 0) {
errorToShow = 1;
fieldValue = "" + $('yearlyDayField').value;
if (fieldValue.length > 0) {
// We check if the yearlyYearsField really contains an integer
var v = parseInt(fieldValue);
if (!isNaN(v) && v > 0) {
errorToShow = -1;
}
}
}
}
if (errorToShow > -1)
window.alert(errors[errorToShow]);
return (errorToShow == -1);
}
function handleYearlyRecurrence() {
var validate = false;
var radioValue = $('recurrence_form').getRadioValue('yearlyRadioButtonName');
// FIXME - right now we do not support rules
// such as Every Second Tuesday of February
if (radioValue == 1)
window.alert("This type of recurrence is currently unsupported.");
else {
var showError = true;
var fieldValue = "" + $('yearlyYearsField').value;
if (fieldValue.length > 0) {
// We check if the yearlyYearsField really contains an integer
var v = parseInt(fieldValue);
if (!isNaN(v) && v > 0) {
validate = true;
showError = false;
parent$("repeat1").value = fieldValue;
parent$("repeat2").value = radioValue;
parent$("repeat3").value = $('yearlyDayField').value;
parent$("repeat4").value = $('yearlyMonth1').value;
parent$("repeat5").value = $('yearlyRepeat').value;
parent$("repeat6").value = $('yearlyDay').value;
parent$("repeat7").value = $('yearlyMonth2').value;
}
}
if (showError)
window.alert("Please specify a numerical value in the Year(s) field greater or equal to 1.");
if (validateYearlyRecurrence()) {
var fieldValue = "" + $('yearlyYearsField').value;
if (fieldValue.length > 0) {
// We check if the yearlyYearsField really contains an integer
var v = parseInt(fieldValue);
if (!isNaN(v) && v > 0) {
validate = true;
showError = false;
parent$("repeat1").value = fieldValue;
parent$("repeat2").value = radioValue;
parent$("repeat3").value = $('yearlyDayField').value;
parent$("repeat4").value = $('yearlyMonth1').value;
parent$("repeat5").value = $('yearlyRepeat').value;
parent$("repeat6").value = $('yearlyDay').value;
parent$("repeat7").value = $('yearlyMonth2').value;
}
}
}
else
validate = false;
}
return validate;
+1
View File
@@ -1461,6 +1461,7 @@ function configureSortableTableHeaders(table) {
var headers = $(table).getElementsByClassName("sortableTableHeader");
for (var i = 0; i < headers.length; i++) {
var header = $(headers[i]);
header.stopObserving("click", onHeaderClick);
header.observe("click", onHeaderClick);
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB