merge of '2b69d044a61bdcebe73dd14659a3edfec3fd3530'

and '99cc1bb593f4002d820b712345f3e8c1c9ba44ba'

Monotone-Parent: 2b69d044a61bdcebe73dd14659a3edfec3fd3530
Monotone-Parent: 99cc1bb593f4002d820b712345f3e8c1c9ba44ba
Monotone-Revision: 350058ff37111e646407d97db552b5f4c9e96f90

Monotone-Author: ludovic@Sophos.ca
Monotone-Date: 2008-09-02T22:25:01
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Ludovic Marcotte 2008-09-02 22:25:01 +00:00
commit 5e55bdea7d
18 changed files with 1318 additions and 107 deletions

View file

@ -1,3 +1,51 @@
2008-09-02 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* SoObjects/Mailer/SOGoMailManager.m ([NGImap
-copyMailURL:toFolderURL:password:]): do not compare the urls
based on the instance that NGImap4ConnectionManager returns,
because disabling the pooling will generate a bad result, even
though the host:port pairs are the same.
2008-09-01 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/MailerUI/UIxMailView.m ([UIxMailView
-appendToResponse:_responseinContext:_ctx]): no longer invoke
[NGImap4Client logout], since this is now handled by the
NGImap4Connection manager (or not).
* UI/MailerUI/UIxMailActions.m ([UIxMailActions
-markMessageUnreadAction]): no longer make use of [SOGoMailFolder
unselect].
([UIxMailActions -markMessageReadAction]): idem.
* SoObjects/Mailer/SOGoMailFolder.m ([-unselect]): removed method
since we no longer need it.
* SoObjects/Mailer/SOGoMailBaseObject.m ([SOGoMailBaseObject
-dealloc]): release "imap4". If the IMAP4 connection pooling is
disabled, the object will otherwise never be released.
* SoObjects/Mailer/SOGoMailAccount.m ([SOGoMailAccount
+initialize]): use the user default "SOGoFallbackIMAP4Server" to
override the value of "serverName" from the actual user settings.
Fallback to "localhost" if value is unset.
* SoObjects/Mailer/SOGoMailAccount.m ([SOGoMailAccount
-imap4URLString]): use the value of SOGoFallbackIMAP4Server, as
mentionne above.
* UI/MailerUI/UIxMailEditor.m ([UIxMailEditor -from]): retain the
initialized value of from, otherwise we create a future zombie.
* SoObjects/SOGo/SOGoObject.m ([SOGoObject
-initWithName:_nameinContainer:_container]): we no longer retain
the context, to avoid making a circular reference.
* SoObjects/SOGo/SOGoUser.m ([SOGoUser
-initWithLogin:newLoginroles:newRoles]): moved the core from init
here.
([-init]): removed method.
2008-08-29 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/MailerUI/UIxMailView.m ([UIxMailView

File diff suppressed because it is too large Load diff

View file

@ -57,6 +57,9 @@ static NSString *trashFolderName = nil;
static NSString *sharedFolderName = @""; // TODO: add English default
static NSString *otherUsersFolderName = @""; // TODO: add English default
// this is temporary, until we allow users to manage their own accounts
static NSString *fallbackIMAP4Server = nil;
+ (void) initialize
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
@ -95,7 +98,16 @@ static NSString *otherUsersFolderName = @""; // TODO: add English default
else
rootFolderNames = [[NSArray alloc] initWithObjects:
draftsFolderName,
nil];
nil];
if (!fallbackIMAP4Server)
{
fallbackIMAP4Server = [ud stringForKey: @"SOGoFallbackIMAP4Server"];
if (fallbackIMAP4Server)
[fallbackIMAP4Server retain];
else
fallbackIMAP4Server = @"localhost";
}
}
- (id) init
@ -258,8 +270,14 @@ static NSString *otherUsersFolderName = @""; // TODO: add English default
escUsername
= [[username stringByEscapingURL] stringByReplacingString: @"@"
withString: @"%40"];
#if 0
// see comment about fallbackIMAP4Server above
hostString = [NSString stringWithFormat: @"%@@%@", escUsername,
[mailAccount objectForKey: @"serverName"]];
#else
hostString = [NSString stringWithFormat: @"%@@%@", escUsername,
fallbackIMAP4Server];
#endif
}
else
hostString = @"localhost";

View file

@ -57,6 +57,7 @@ static BOOL debugOn = YES;
- (void) dealloc
{
[imap4URL release];
[imap4 release];
[super dealloc];
}
@ -121,7 +122,7 @@ static BOOL debugOn = YES;
imap4 = [[self mailManager] connectionForURL: [self imap4URL]
password: [self imap4Password]];
if (imap4)
[imap4 retain];
[imap4 retain];
else
[self errorWithFormat:@"Could not connect IMAP4."];
}

View file

@ -64,7 +64,6 @@ typedef enum {
- (void) expungeLastMarkedFolder;
- (NSException *) expunge;
- (NSException *) unselect;
/* flags */

View file

@ -283,16 +283,6 @@ static BOOL aclConformsToIMAPExt = NO;
return [[self imap4Connection] expungeAtURL: [self imap4URL]];
}
- (NSException *) unselect
{
NGImap4Client *client;
client = [[self imap4Connection] client];
[client unselect];
return nil;
}
- (void) markForExpunge
{
NSUserDefaults *ud;

View file

@ -20,6 +20,8 @@
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSValue.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGExtensions/NSNull+misc.h>
@ -194,20 +196,25 @@
password:(NSString *)_pwd
{
NGImap4Connection *entry;
NSNumber *destPort, *srcPort;
/* check connection cache */
if ((entry = [self connectionForURL:_srcurl password:_pwd]) == nil)
return [self errorForMissingEntryAtURL:_srcurl];
/* check whether URLs are on different servers */
if ([self connectionForURL:_desturl password:_pwd] != entry) {
srcPort = [_srcurl port];
destPort = [_desturl port];
if (!([[_desturl host] isEqualToString: [_srcurl host]]
&& (srcPort == destPort
|| [destPort isEqualToNumber: srcPort]))) {
// TODO: find a better error code
return [NSException exceptionWithHTTPStatus:502 /* Bad Gateway */
reason:@"source and destination on different servers"];
}
}
return [entry copyMailURL:_srcurl toFolderURL:_desturl];
}

View file

@ -87,7 +87,8 @@ static BOOL forceImapLoginWithEmail = NO;
if (sourceID)
[sources setObject: ldapSource forKey: sourceID];
else
NSLog(@"LDAPUserManager.m: WARNING: id field missing in a LDAP source, check the SOGoLDAPSources default");
[self errorWithFormat: @"id field missing in a LDAP source,"
@" check the SOGoLDAPSources defaults"];
metadata = [NSMutableDictionary dictionary];
value = [udSource objectForKey: @"canAuthenticate"];
if (value)
@ -121,6 +122,7 @@ static BOOL forceImapLoginWithEmail = NO;
- (id) init
{
NSUserDefaults *ud;
NSString *cleanupSetting;
if ((self = [super init]))
{
@ -129,14 +131,24 @@ static BOOL forceImapLoginWithEmail = NO;
sources = nil;
sourcesMetadata = nil;
users = [NSMutableDictionary new];
cleanupInterval
= [ud integerForKey: @"SOGoLDAPUserManagerCleanupInterval"];
if (cleanupInterval)
cleanupTimer = [NSTimer scheduledTimerWithTimeInterval: cleanupInterval
target: self
selector: @selector(cleanupSources)
userInfo: nil
repeats: YES];
cleanupSetting
= [ud objectForKey: @"SOGoLDAPUserManagerCleanupInterval"];
if (cleanupSetting)
cleanupInterval = [cleanupSetting doubleValue];
else
cleanupInterval = 0.0;
if (cleanupInterval > 0.0)
{
cleanupTimer = [NSTimer scheduledTimerWithTimeInterval: cleanupInterval
target: self
selector: @selector (_cleanupSources)
userInfo: nil
repeats: YES];
[self logWithFormat: @"cleanup interval set every %f seconds",
cleanupInterval];
}
else
[self logWithFormat: @"no cleanup interval set: memory usage will grow"];
[self _prepareLDAPSourcesWithDefaults: ud];
}
@ -384,12 +396,8 @@ static BOOL forceImapLoginWithEmail = NO;
if (key)
[users setObject: newUser forKey: key];
emails = [[newUser objectForKey: @"emails"] objectEnumerator];
key = [emails nextObject];
while (key)
{
[users setObject: newUser forKey: key];
key = [emails nextObject];
}
while ((key = [emails nextObject]))
[users setObject: newUser forKey: key];
}
- (NSDictionary *) contactInfosForUserWithUIDorEmail: (NSString *) uid
@ -532,22 +540,32 @@ static BOOL forceImapLoginWithEmail = NO;
matching: filter];
}
- (void) cleanupSources
- (void) _cleanupSources
{
NSEnumerator *userIDs;
NSString *currentID;
NSDictionary *currentUser;
NSDate *now;
unsigned int count;
now = [NSDate date];
count = 0;
userIDs = [[users allKeys] objectEnumerator];
while ((currentID = [userIDs nextObject]))
{
currentUser = [users objectForKey: currentID];
if ([now earlierDate:
[currentUser objectForKey: @"cleanupDate"]] == now)
[users removeObjectForKey: currentID];
{
[users removeObjectForKey: currentID];
count++;
}
}
if (count)
[self logWithFormat: @"cleaned %d users records from cache", count];
}
@end

View file

@ -270,7 +270,6 @@ SEL SOGoSelectorForPropertySetter (NSString *property)
if ((self = [self init]))
{
context = [[WOApplication application] context];
[context retain];
nameInContainer = [_name copy];
container = _container;
if ([self doesRetainContainer])
@ -285,7 +284,6 @@ SEL SOGoSelectorForPropertySetter (NSString *property)
- (void) dealloc
{
[context release];
[owner release];
if ([self doesRetainContainer])
[container release];
@ -402,7 +400,7 @@ SEL SOGoSelectorForPropertySetter (NSString *property)
{
obj = [[self soClass] lookupKey: lookupName inContext: localContext];
if (obj)
[obj bindToObject: self inContext: localContext];
obj = [obj bindToObject: self inContext: localContext];
}
if (obj)

View file

@ -201,7 +201,7 @@ _timeValue (NSString *key)
if (user)
{
[user autorelease];
[cache registerUser: user];
[cache registerUser: user];
}
}
[user setPrimaryRoles: newRoles];
@ -209,25 +209,6 @@ _timeValue (NSString *key)
return user;
}
- (id) init
{
if ((self = [super init]))
{
userDefaults = nil;
userSettings = nil;
allEmails = nil;
language = nil;
currentPassword = nil;
dateFormatter = nil;
homeFolder = nil;
cn = nil;
userTimeZone = nil;
mailAccounts = nil;
}
return self;
}
- (id) initWithLogin: (NSString *) newLogin
roles: (NSArray *) newRoles
{
@ -247,7 +228,21 @@ _timeValue (NSString *key)
}
if ([realUID length])
self = [super initWithLogin: realUID roles: newRoles];
{
if ((self = [super initWithLogin: realUID roles: newRoles]))
{
userDefaults = nil;
userSettings = nil;
allEmails = nil;
language = nil;
currentPassword = nil;
dateFormatter = nil;
homeFolder = nil;
cn = nil;
userTimeZone = nil;
mailAccounts = nil;
}
}
else
{
[self release];

View file

@ -151,7 +151,6 @@
if (!response)
{
mailFolder = [[self clientObject] container];
[mailFolder unselect];
response = [self responseWith204];
}
@ -167,7 +166,6 @@
if (!response)
{
mailFolder = [[self clientObject] container];
[mailFolder unselect];
response = [self responseWith204];
}

View file

@ -135,6 +135,7 @@ static NSArray *infoKeys = nil;
{
identity = [[context activeUser] primaryIdentity];
from = [identity keysWithFormat: @"%{fullName} <%{email}>"];
[from retain];
}
return from;

View file

@ -211,7 +211,6 @@ static NSString *mailETag = nil;
inContext: (WOContext *) _ctx
{
UIxMailRenderingContext *mctx;
NGImap4Connection *conn;
if (mailETag != nil)
[[_ctx response] setHeader:mailETag forKey:@"etag"];
@ -225,9 +224,6 @@ static NSString *mailETag = nil;
[super appendToResponse: _response inContext: _ctx];
[[_ctx popMailRenderingContext] reset];
conn = [[self clientObject] imap4Connection];
[[conn client] logout];
}
@end /* UIxMailView */

View file

@ -130,6 +130,7 @@ static BOOL uixDebugEnabled = NO;
if ((self = [super init]))
{
_selectedDate = nil;
queryParameters = nil;
}
return self;

View file

@ -262,7 +262,7 @@ function deleteSelectedMessagesCallback(http) {
if (!nextRow)
nextRow = row.previous("tr");
// row.addClassName("deleted"); // when we'll offer "mark as deleted"
if (deleteMessageRequestCount == 0) {
if (nextRow) {
Mailer.currentMessages[Mailer.currentMailbox] = nextRow.getAttribute("id").substr(4);
@ -1567,8 +1567,12 @@ function getFoldersStateCallback(http) {
function saveFoldersState() {
if (mailAccounts.length > 0) {
var foldersState = mailboxTree.getFoldersState();
var urlstr = ApplicationBaseURL + "saveFoldersState" + "?expandedFolders=" + foldersState;
triggerAjaxRequest(urlstr, saveFoldersStateCallback);
var urlstr = ApplicationBaseURL + "saveFoldersState";
var parameters = "expandedFolders=" + foldersState;
triggerAjaxRequest(urlstr, saveFoldersStateCallback, null, parameters,
{ "Content-type": "application/x-www-form-urlencoded",
"Content-length": parameters.length,
"Connection": "close" });
}
}

View file

@ -153,5 +153,5 @@ UL#attachments LI IMG
left: 0em;
right: 0em;
bottom: 0em;
top: 13em;
top: 999em;
width: 99%; }

View file

@ -8,7 +8,7 @@ var MailEditor = {
addressBook: null,
currentField: null,
selectedIndex: -1,
delay: 500,
delay: 750,
delayedSearch: false
};
@ -273,7 +273,7 @@ function onTextFocus() {
}
function onTextKeyDown(event) {
if (event.keyCode == 9) {
if (event.keyCode == Event.KEY_TAB) {
if (event.shiftKey) {
var nodes = $("subjectRow").childNodesWithTag("input");
var objectInput = $(nodes[0]);
@ -341,39 +341,39 @@ function onContactKeydown(event) {
this.focussed = true;
return;
}
if (event.keyCode == 9) { // Tab
if (event.keyCode == Event.KEY_TAB) {
if (this.confirmedValue)
this.value = this.confirmedValue;
if (document.currentPopupMenu)
hideMenu(document.currentPopupMenu);
}
else if (event.keyCode == 0
|| event.keyCode == 8 // Backspace
|| event.keyCode == Event.KEY_BACKSPACE
|| event.keyCode == 32 // Space
|| event.keyCode > 47) {
this.confirmedValue = null;
MailEditor.selectedIndex = -1;
MailEditor.currentField = this;
if (this.value.length > 0 && !MailEditor.delayedSearch) {
MailEditor.delayedSearch = true;
setTimeout("performSearch()", MailEditor.delay);
if (this.value.length > 1) {
if (MailEditor.delayedSearch) window.clearTimeout(MailEditor.delayedSearch);
MailEditor.delayedSearch = window.setTimeout("performSearch()", MailEditor.delay);
}
else if (this.value.length == 0) {
else if (this.value.length <= 1) {
if (document.currentPopupMenu)
hideMenu(document.currentPopupMenu);
}
}
else if (event.keyCode == 13) {
else if (event.keyCode == Event.KEY_RETURN) {
preventDefault(event);
if (this.confirmedValue)
this.value = this.confirmedValue;
$(this).selectText(0, this.value.length);
$(this).select();
if (document.currentPopupMenu)
hideMenu(document.currentPopupMenu);
MailEditor.selectedIndex = -1;
}
else if ($('contactsMenu').getStyle('visibility') == 'visible') {
if (event.keyCode == 38) { // Up arrow
if (event.keyCode == Event.KEY_UP) { // Up arrow
if (MailEditor.selectedIndex > 0) {
var contacts = $('contactsMenu').select("li");
contacts[MailEditor.selectedIndex--].removeClassName("selected");
@ -381,7 +381,7 @@ function onContactKeydown(event) {
contacts[MailEditor.selectedIndex].addClassName("selected");
}
}
else if (event.keyCode == 40) { // Down arrow
else if (event.keyCode == Event.KEY_DOWN) { // Down arrow
var contacts = $('contactsMenu').select("li");
if (contacts.size() - 1 > MailEditor.selectedIndex) {
if (MailEditor.selectedIndex >= 0)
@ -402,14 +402,13 @@ function performSearch() {
document.contactLookupAjaxRequest.aborted = true;
document.contactLookupAjaxRequest.abort();
}
if (MailEditor.currentField.value.trim().length > 0) {
if (MailEditor.currentField.value.trim().length > 1) {
var urlstr = ( UserFolderURL + "Contacts/allContactSearch?search="
+ MailEditor.currentField.value );
document.contactLookupAjaxRequest =
triggerAjaxRequest(urlstr, performSearchCallback, MailEditor.currentField);
}
}
MailEditor.delayedSearch = false;
}
function performSearchCallback(http) {
@ -543,7 +542,8 @@ function initMailEditor() {
textarea.observe(ieEvents[i], onTextIEUpdateCursorPos, false);
}
initTabIndex($("addressList"), $$("div#subjectRow input").first(), textarea);
var subjectField = $$("div#subjectRow input").first();
initTabIndex($("addressList"), subjectField, textarea);
onWindowResize(null);
Event.observe(window, "resize", onWindowResize);
@ -632,10 +632,11 @@ function onWindowResize(event) {
addresslist.setStyle({ width: ($(this).width() - attachmentswidth - 10) + 'px' });
// Set textarea position
textarea.setStyle({ 'top': headerarea.select("hr").first().offsetTop + 'px' });
var hr = headerarea.select("hr").first();
textarea.setStyle({ 'top': hr.offsetTop + 'px' });
// Resize the textarea (message content)
textarea.rows = Math.round((window.height() - textarea.offsetTop) / rowheight);
textarea.rows = Math.floor((window.height() - textarea.offsetTop) / rowheight);
}
function onMailEditorClose(event) {

View file

@ -29,7 +29,8 @@ function onICalendarButtonClick(event) {
function onMenuDeleteMessage(event) {
if (window.opener && window.opener.open && !window.opener.closed) {
var rowId = window.name.substr(9);
var rowId_index = window.name.search(/[0-9]+$/);
var rowId = window.name.substr(rowId_index);
var messageId = window.opener.Mailer.currentMailbox + "/" + rowId;
var url = ApplicationBaseURL + messageId + "/trash";