mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-04-08 06:48:51 +00:00
merge of '5616899c7c44519d7ea52d68cc931f9f056b9584'
and '6c9151f261ad9f73f6614808f73d4ca224c2cb8e' Monotone-Parent: 5616899c7c44519d7ea52d68cc931f9f056b9584 Monotone-Parent: 6c9151f261ad9f73f6614808f73d4ca224c2cb8e Monotone-Revision: 06d643c3c015e84728100fb5624bf4bac033748f Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2010-11-08T19:12:46 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
48
ChangeLog
48
ChangeLog
@@ -1,3 +1,24 @@
|
||||
2010-11-08 Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
||||
* SOPE/GDLContentStore/GCSAlarmsFolder.m
|
||||
We now check for non-nil values before calling
|
||||
-timeInterval...
|
||||
* SoObjects/Mailer/SOGoMailAccount.m
|
||||
We try to fallback to the imap server prior falling
|
||||
back to localhost
|
||||
|
||||
2010-11-08 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* UI/WebServerResources/SOGoDragHandles.js (adjust): for vertical
|
||||
drag handles, prioritize the top limit rather than the bottom one.
|
||||
|
||||
* UI/WebServerResources/UIxContactEditor.js (onComboButtonClick):
|
||||
return false so the form is not submitted when the button is clicked.
|
||||
|
||||
* UI/WebServerResources/ContactsUI.js
|
||||
(onCategoriesMenuPrepareVisibility): don't verify the selection if
|
||||
the list doesn't exist (happens in the contact editor).
|
||||
|
||||
2010-11-05 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreSOGo.m: added debugging witnesses call to
|
||||
@@ -27,6 +48,33 @@
|
||||
(-getBody): invoked setupValues if values is nil to ensure that
|
||||
the timezone has been set properly.
|
||||
|
||||
2010-11-05 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* UI/MailerUI/UIxMailListActions.m (-getSortedUIDsAction): now
|
||||
accepts the form parameter "no_headers" so only the UIDs are
|
||||
returned, without the prefetched headers.
|
||||
|
||||
* UI/WebServerResources/SOGoMailDataSource.js (init): made the
|
||||
headers argument optional.
|
||||
(_loadCallback): handled the case when the server doesn't send the
|
||||
prefetched headers.
|
||||
|
||||
* UI/WebServerResources/SOGoDataTable.js (_refresh): new method to
|
||||
force the refresh of the data table with the data of the data source.
|
||||
(remove): don't update the internal variables (index and count) if
|
||||
the UID was not found in the data source.
|
||||
|
||||
* UI/WebServerResources/MailerUI.js (openMailbox): when reloading
|
||||
a mailbox, only fetch the messages UIDs (without the headers).
|
||||
(loadMessageCallback): only reload the headers if the seen state
|
||||
has changed.
|
||||
|
||||
2010-11-04 Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
||||
SoObjects/SOGo/SOGoMailer.m
|
||||
We stop when we see an invalid recipient and we inform the
|
||||
client back with what are the invalid recipients
|
||||
|
||||
2010-11-04 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* Tools/SOGoSockDOperation.m (_getFolderWithId:forUser:): invoke
|
||||
|
||||
@@ -326,8 +326,10 @@ static NSString *alarmsFolderURLString = nil;
|
||||
{
|
||||
NSNumber *tRecId, *tADate;
|
||||
|
||||
tRecId = [NSNumber numberWithInt: (int) [recId timeIntervalSince1970]];
|
||||
tADate = [NSNumber numberWithInt: (int) [alarmDate timeIntervalSince1970]];
|
||||
// We check if recId and alarmDate are nil prior calling -timeIntervalSince1970
|
||||
// Weird gcc optimizations can cause issue here.
|
||||
tRecId = [NSNumber numberWithInt: (recId ? (int)[recId timeIntervalSince1970] : 0)];
|
||||
tADate = [NSNumber numberWithInt: (alarmDate ? (int)[alarmDate timeIntervalSince1970] : 0)];
|
||||
|
||||
return [NSDictionary dictionaryWithObjectsAndKeys: cname, @"c_name",
|
||||
path, @"c_path",
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
2010-11-08 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* NSString+NGCards.m (-vCardSubvaluesWithSeparator:): now returns
|
||||
an empty array when the string is empty, instead of an array with
|
||||
an empty string.
|
||||
|
||||
2010-10-28 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* iCalRecurrenceRule.m (-isInfinite): a repeat count set to 0 is
|
||||
|
||||
@@ -322,11 +322,14 @@ static NSString *commaSeparator = nil;
|
||||
}
|
||||
}
|
||||
|
||||
substring = [[NSString alloc] initWithCharactersNoCopy: substringBuffer
|
||||
length: substringLength
|
||||
freeWhenDone: YES];
|
||||
[components addObject: substring];
|
||||
[substring release];
|
||||
if (substringLength > 0)
|
||||
{
|
||||
substring = [[NSString alloc] initWithCharactersNoCopy: substringBuffer
|
||||
length: substringLength
|
||||
freeWhenDone: YES];
|
||||
[components addObject: substring];
|
||||
[substring release];
|
||||
}
|
||||
|
||||
NSZoneFree (NULL, stringBuffer);
|
||||
|
||||
|
||||
@@ -353,7 +353,22 @@ static NSString *sieveScriptName = @"sogo";
|
||||
|
||||
if (!sieveServer)
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
sieveServer = @"localhost";
|
||||
s = [dd imapServer];
|
||||
|
||||
if (s)
|
||||
{
|
||||
NSURL *url;
|
||||
|
||||
url = [NSURL URLWithString: s];
|
||||
|
||||
if ([url host])
|
||||
sieveServer = [url host];
|
||||
else
|
||||
sieveServer = s;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SOGoMailer.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007-2009 Inverse inc.
|
||||
* Copyright (C) 2007-2010 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
@@ -96,12 +96,9 @@
|
||||
|
||||
- (NSException *) _sendMailData: (NSData *) mailData
|
||||
withClient: (NGSmtpClient *) client
|
||||
andRejections: (unsigned int) toErrors
|
||||
{
|
||||
NSException *result;
|
||||
|
||||
if (toErrors > 0)
|
||||
[self logWithFormat: @"sending email despite address rejections"];
|
||||
if ([client sendData: mailData])
|
||||
result = nil;
|
||||
else
|
||||
@@ -118,12 +115,13 @@
|
||||
{
|
||||
NGInternetSocketAddress *addr;
|
||||
NSString *currentTo, *host;
|
||||
NSMutableArray *toErrors;
|
||||
NSEnumerator *addresses;
|
||||
NGSmtpClient *client;
|
||||
NSException *result;
|
||||
NSRange r;
|
||||
|
||||
unsigned int toErrors, port;
|
||||
unsigned int port;
|
||||
|
||||
client = [NGSmtpClient smtpClient];
|
||||
host = smtpServer;
|
||||
@@ -145,7 +143,7 @@
|
||||
{
|
||||
if ([client mailFrom: sender])
|
||||
{
|
||||
toErrors = 0;
|
||||
toErrors = [NSMutableArray array];
|
||||
addresses = [recipients objectEnumerator];
|
||||
currentTo = [addresses nextObject];
|
||||
while (currentTo)
|
||||
@@ -153,17 +151,21 @@
|
||||
if (![client recipientTo: [currentTo pureEMailAddress]])
|
||||
{
|
||||
[self logWithFormat: @"error with recipient '%@'", currentTo];
|
||||
toErrors++;
|
||||
[toErrors addObject: [currentTo pureEMailAddress]];
|
||||
}
|
||||
currentTo = [addresses nextObject];
|
||||
}
|
||||
if (toErrors == [recipients count])
|
||||
if ([toErrors count] == [recipients count])
|
||||
result = [NSException exceptionWithHTTPStatus: 500
|
||||
reason: @"cannot send message:"
|
||||
@" (smtp) all recipients discarded"];
|
||||
else if ([toErrors count] > 0)
|
||||
result = [NSException exceptionWithHTTPStatus: 500
|
||||
reason: [NSString stringWithFormat:
|
||||
@"cannot send message (smtp) - recipients discarded:\n%@",
|
||||
[toErrors componentsJoinedByString: @", "]]];
|
||||
else
|
||||
result = [self _sendMailData: mailData withClient: client
|
||||
andRejections: toErrors];
|
||||
result = [self _sendMailData: mailData withClient: client];
|
||||
}
|
||||
else
|
||||
result = [NSException exceptionWithHTTPStatus: 500
|
||||
|
||||
@@ -558,17 +558,25 @@
|
||||
|
||||
- (id <WOActionResults>) getSortedUIDsAction
|
||||
{
|
||||
NSDictionary *data;
|
||||
id data;
|
||||
NSString *noHeaders;
|
||||
SOGoMailFolder *folder;
|
||||
WORequest *request;
|
||||
WOResponse *response;
|
||||
|
||||
request = [context request];
|
||||
response = [context response];
|
||||
folder = [self clientObject];
|
||||
data = [self getUIDsAndHeadersInFolder: folder];
|
||||
[response setHeader: @"text/plain; charset=utf-8"
|
||||
forKey: @"content-type"];
|
||||
folder = [self clientObject];
|
||||
noHeaders = [request formValueForKey: @"no_headers"];
|
||||
if ([noHeaders length])
|
||||
data = [self getSortedUIDsInFolder: folder];
|
||||
else
|
||||
data = [self getUIDsAndHeadersInFolder: folder];
|
||||
|
||||
[response appendContentString: [data jsonRepresentation]];
|
||||
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,17 +79,17 @@
|
||||
methods = {
|
||||
getMail = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxMailListActions";
|
||||
actionClass = "UIxMailListActions";
|
||||
actionName = "getMail";
|
||||
};
|
||||
uids = {
|
||||
protectedBy = "<public>";
|
||||
actionClass = "UIxMailListActions";
|
||||
actionClass = "UIxMailListActions";
|
||||
actionName = "getSortedUIDs";
|
||||
};
|
||||
headers = {
|
||||
protectedBy = "<public>";
|
||||
actionClass = "UIxMailListActions";
|
||||
actionClass = "UIxMailListActions";
|
||||
actionName = "getHeaders";
|
||||
};
|
||||
subscribe = {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"contacts_category_labels" = "Ami, Client, Collègue, Concurrent, Famille, Fournisseur, Partenaire d'affaire, Presse, VIP";
|
||||
|
||||
/* vacation (auto-reply) */
|
||||
"Enable vacation auto reply" = "Activer message d'absense prolongée";
|
||||
"Enable vacation auto reply" = "Activer message d'absence prolongée";
|
||||
"Auto reply message :" = "Message de réponse automatique :";
|
||||
"Email addresses (separated by commas) :" = "Adresses courriels (séparées par des virgules) :";
|
||||
"Add default email addresses" = "Ajouter les adresses par défaut";
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
xmlns:label="OGo:label"
|
||||
className="UIxPageFrame"
|
||||
title="name"
|
||||
const:userDefaultsKeys="SOGoContactsCategories"
|
||||
const:popup="YES"
|
||||
>
|
||||
<div class="menu" id="categoriesMenu">
|
||||
|
||||
@@ -1302,30 +1302,34 @@ function resetCategoriesMenu() {
|
||||
}
|
||||
|
||||
function onCategoriesMenuPrepareVisibility() {
|
||||
var rows = contactsList.getSelectedRows();
|
||||
if (rows.length > 0) {
|
||||
var catList = rows[0].getAttribute("categories");
|
||||
var catsArray;
|
||||
if (catList && catList.length > 0) {
|
||||
catsArray = catList.split(",");
|
||||
}
|
||||
else {
|
||||
catsArray = [];
|
||||
}
|
||||
|
||||
var menu = $("categoriesMenu");
|
||||
var ul = menu.down("ul");
|
||||
var listElements = ul.select("li");
|
||||
for (var i = 0; i < listElements.length; i++) {
|
||||
var li = listElements[i];
|
||||
if (catsArray.indexOf(li.category) > -1) {
|
||||
li.addClassName("_chosen");
|
||||
var contactsList = $("contactsList");
|
||||
if (contactsList) {
|
||||
var rows = contactsList.getSelectedRows();
|
||||
if (rows.length > 0) {
|
||||
var catList = rows[0].getAttribute("categories"); log ("cats = " + catList);
|
||||
var catsArray;
|
||||
if (catList && catList.length > 0) {
|
||||
catsArray = catList.split(",");
|
||||
}
|
||||
else {
|
||||
li.removeClassName("_chosen");
|
||||
catsArray = [];
|
||||
}
|
||||
|
||||
var menu = $("categoriesMenu");
|
||||
var ul = menu.down("ul");
|
||||
var listElements = ul.select("li");
|
||||
for (var i = 0; i < listElements.length; i++) {
|
||||
var li = listElements[i];
|
||||
if (catsArray.indexOf(li.category) > -1) {
|
||||
li.addClassName("_chosen");
|
||||
}
|
||||
else {
|
||||
li.removeClassName("_chosen");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function onCategoriesMenuItemClick() {
|
||||
|
||||
@@ -425,7 +425,7 @@ function deleteSelectedMessages(sender) {
|
||||
triggerAjaxRequest(url, deleteSelectedMessagesCallback, data, parameters,
|
||||
{ "Content-type": "application/x-www-form-urlencoded" });
|
||||
}
|
||||
else
|
||||
if (uids.length == 0)
|
||||
showAlertDialog(_("Please select a message."));
|
||||
|
||||
return false;
|
||||
@@ -440,7 +440,7 @@ function deleteSelectedMessagesCallback(http) {
|
||||
if (Mailer.currentMailbox == data["mailbox"]) {
|
||||
var div = $('messageContent');
|
||||
if (Mailer.currentMessages[Mailer.currentMailbox] == data["id"][i]) {
|
||||
div.update();
|
||||
div.innerHTML = '';
|
||||
Mailer.currentMessages[Mailer.currentMailbox] = null;
|
||||
}
|
||||
if (deleteMessageRequestCount == 0) {
|
||||
@@ -457,7 +457,7 @@ function deleteSelectedMessagesCallback(http) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
div.update();
|
||||
div.innerHTML = '';
|
||||
}
|
||||
Mailer.dataTable.remove(data["id"][i]);
|
||||
Mailer.dataTable.refresh();
|
||||
@@ -731,7 +731,7 @@ function openMailbox(mailbox, reload) {
|
||||
}
|
||||
|
||||
var dataSource = Mailer.dataSources.get(key);
|
||||
if (!dataSource || reload) {
|
||||
if (!dataSource) {
|
||||
dataSource = new SOGoMailDataSource(Mailer.dataTable, url);
|
||||
if (inboxData) {
|
||||
dataSource.init(inboxData['uids'], inboxData['headers']);
|
||||
@@ -742,9 +742,16 @@ function openMailbox(mailbox, reload) {
|
||||
Mailer.dataSources.set(key, dataSource);
|
||||
getUnseenCountForFolder(mailbox);
|
||||
}
|
||||
messageList.deselectAll();
|
||||
Mailer.dataTable.setSource(dataSource);
|
||||
Mailer.dataTable.render();
|
||||
else if (reload) {
|
||||
urlParams.set("no_headers", "1");
|
||||
dataSource.load(urlParams);
|
||||
}
|
||||
if (reload)
|
||||
Mailer.dataTable.refresh();
|
||||
else {
|
||||
Mailer.dataTable.setSource(dataSource);
|
||||
Mailer.dataTable.render();
|
||||
}
|
||||
configureDraggables();
|
||||
Mailer.currentMailbox = mailbox;
|
||||
|
||||
@@ -767,7 +774,6 @@ function openMailbox(mailbox, reload) {
|
||||
*/
|
||||
function messageListCallback(row, data, isNew) {
|
||||
var currentMessage = Mailer.currentMessages[Mailer.currentMailbox];
|
||||
|
||||
row.id = data['rowID'];
|
||||
row.writeAttribute('labels', (data['labels']?data['labels']:""));
|
||||
row.className = data['rowClasses'];
|
||||
@@ -1511,7 +1517,8 @@ function loadMessageCallback(http) {
|
||||
var msguid = http.callbackData.msguid;
|
||||
// Warning: If the user can't set the read/unread flag, it won't
|
||||
// be reflected in the view unless we force the refresh.
|
||||
//Mailer.dataTable.invalidate(msguid, true);
|
||||
if (http.callbackData.seenStateHasChanged)
|
||||
Mailer.dataTable.invalidate(msguid, true);
|
||||
cachedMessage['idx'] = Mailer.currentMailbox + '/' + msguid;
|
||||
cachedMessage['time'] = (new Date()).getTime();
|
||||
cachedMessage['text'] = http.responseText;
|
||||
|
||||
@@ -159,6 +159,7 @@ var SOGoDataTableInterface = {
|
||||
count = end - start;
|
||||
|
||||
this.currentRenderID = index + "-" + count;
|
||||
|
||||
// Query the data source only if at least one row is not loaded
|
||||
if (refresh === true ||
|
||||
this.renderedIndex < 0 ||
|
||||
@@ -168,12 +169,16 @@ var SOGoDataTableInterface = {
|
||||
this.dataSource.getData(this.currentRenderID,
|
||||
index,
|
||||
count,
|
||||
this._render.bind(this),
|
||||
(refresh === true)?this._refresh.bind(this):this._render.bind(this),
|
||||
this.renderDelay);
|
||||
}
|
||||
},
|
||||
|
||||
_render: function(renderID, start, max, data) {
|
||||
_refresh: function(renderID, start, max, data) {
|
||||
this._render(renderID, start, max, data, true);
|
||||
},
|
||||
|
||||
_render: function(renderID, start, max, data, refresh) {
|
||||
if (this.currentRenderID != renderID) {
|
||||
// log ("DataTable._render() ignore render for " + renderID + " (current is " + this.currentRenderID + ")");
|
||||
return;
|
||||
@@ -201,17 +206,16 @@ var SOGoDataTableInterface = {
|
||||
this.renderedCount = 0;
|
||||
}
|
||||
|
||||
if (start > (this.renderedIndex + this.renderedCount) ||
|
||||
if (refresh === true ||
|
||||
start > (this.renderedIndex + this.renderedCount) ||
|
||||
start + data.length < this.renderedIndex) {
|
||||
// No reusable row in the viewport;
|
||||
// refresh the complete view port
|
||||
|
||||
for (i = 0, j = start;
|
||||
i < this.renderedCount && i < data.length;
|
||||
i++, j++) {
|
||||
// Render all existing rows with new data
|
||||
var row = rows[i+1]; // must skip the first row (this.rowTop)
|
||||
row.removeClassName('_selected');
|
||||
this.rowRenderCallback(row, data[i], false);
|
||||
}
|
||||
|
||||
@@ -314,11 +318,12 @@ var SOGoDataTableInterface = {
|
||||
}
|
||||
var index = this.dataSource.remove(uid);
|
||||
// log ("DataTable.remove(" + uid + ") at index " + index);
|
||||
if (this.renderedIndex > index)
|
||||
this.renderedIndex--;
|
||||
else if ((this.renderedIndex + this.renderedCount) > index)
|
||||
this.renderedCount--;
|
||||
|
||||
if (index >= 0) {
|
||||
if (this.renderedIndex > index)
|
||||
this.renderedIndex--;
|
||||
else if ((this.renderedIndex + this.renderedCount) > index)
|
||||
this.renderedCount--;
|
||||
}
|
||||
return index;
|
||||
},
|
||||
|
||||
|
||||
@@ -39,8 +39,10 @@ var SOGoDragHandlesInterface = {
|
||||
}
|
||||
}
|
||||
else if (this.dhType == 'vertical') {
|
||||
this.dhLimit = window.height() - 20 - this.upperBlock.cumulativeOffset()[1] + this.upperBlock.offsetTop;
|
||||
if (parseInt(this.getStyle("top")) > this.dhLimit) {
|
||||
var windowHeight = window.height();
|
||||
this.dhLimit = windowHeight - 20 - this.upperBlock.cumulativeOffset().top + this.upperBlock.offsetTop;
|
||||
if (parseInt(this.getStyle("top")) > this.dhLimit &&
|
||||
windowHeight > this.topMargin) {
|
||||
this.setStyle({ top: this.dhLimit + 'px' });
|
||||
this.lowerBlock.setStyle({ top: this.dhLimit + 'px' });
|
||||
this.upperBlock.setStyle({ height: (this.dhLimit - this.upperBlock.offsetTop) + 'px' });
|
||||
|
||||
@@ -45,12 +45,14 @@ SOGoMailDataSource = Class.create({
|
||||
init: function(uids, headers) {
|
||||
this.uids = uids;
|
||||
|
||||
var keys = headers[0];
|
||||
for (var i = 1; i < headers.length; i++) {
|
||||
var header = [];
|
||||
for (var j = 0; j < keys.length; j++)
|
||||
header[keys[j]] = headers[i][j];
|
||||
this.cache.set(header["uid"], header);
|
||||
if (headers) {
|
||||
var keys = headers[0];
|
||||
for (var i = 1; i < headers.length; i++) {
|
||||
var header = [];
|
||||
for (var j = 0; j < keys.length; j++)
|
||||
header[keys[j]] = headers[i][j];
|
||||
this.cache.set(header["uid"], header);
|
||||
}
|
||||
}
|
||||
|
||||
this.loaded = true;
|
||||
@@ -78,7 +80,10 @@ SOGoMailDataSource = Class.create({
|
||||
if (http.status == 200) {
|
||||
if (http.responseText.length > 0) {
|
||||
var data = http.responseText.evalJSON(true);
|
||||
this.init(data.uids, data.headers);
|
||||
if (data.uids)
|
||||
this.init(data.uids, data.headers);
|
||||
else
|
||||
this.init(data);
|
||||
this.loaded = true;
|
||||
if (this.delayedGetData) {
|
||||
this.delayedGetData();
|
||||
|
||||
@@ -180,7 +180,7 @@ function performSearch(input) {
|
||||
if (input.value.trim().length > 0) {
|
||||
var urlstr = (UserFolderURL
|
||||
+ "Contacts/allContactSearch?excludeGroups=1&search="
|
||||
+ escape(input.value));
|
||||
+ encodeURIComponent(input.value));
|
||||
triggerAjaxRequest(urlstr, performSearchCallback, input);
|
||||
}
|
||||
input.searchTimeout = null;
|
||||
|
||||
@@ -213,7 +213,7 @@ function onComboButtonClick(event) {
|
||||
"left": menuLeft + "px",
|
||||
"width": width + "px" });
|
||||
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
function onCategoryInputChange(event) {
|
||||
|
||||
Reference in New Issue
Block a user