Fixed issues, ajaxified import process

Monotone-Parent: 80ad9ff70fe3d4130d99bbd2590349b71c85b9f3
Monotone-Revision: 33b6c38a250d6ae49e26dd7de548708c132d5c34

Monotone-Author: crobert@inverse.ca
Monotone-Date: 2009-09-03T17:53:38
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
C Robert 2009-09-03 17:53:38 +00:00
parent 110bfdcb4e
commit 45420d434c
34 changed files with 292 additions and 27 deletions

View File

@ -1,6 +1,8 @@
2009-09-03 Cyril Robert <crobert@inverse.ca>
* UI/Contacts/UIxContactsListView.m: Added ldif / vcard import
* UI/Contacts/UIxContactsListView.m: Changed return types to know how many
cards were imported.
2009-09-02 Cyril Robert <crobert@inverse.ca>

View File

@ -144,7 +144,7 @@
- (NSException *) setProxySubscribers: (NSArray *) newSubscribers
withWriteAccess: (BOOL) hasWriteAccess;
- (void) importComponent: (iCalEntityObject *) event;
- (BOOL) importComponent: (iCalEntityObject *) event;
@end

View File

@ -3173,7 +3173,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
return error;
}
- (void) importComponent: (iCalEntityObject *) event
- (BOOL) importComponent: (iCalEntityObject *) event
{
SOGoAppointmentObject *object;
NSString *uid;
@ -3186,7 +3186,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
content =
[NSString stringWithFormat: @"BEGIN:VCALENDAR\n%@END:VCALENDAR\n",
[event versitString]];
[object saveContentString: content];
return ([object saveContentString: content] == nil);
}
@end /* SOGoAppointmentFolder */

View File

@ -183,3 +183,7 @@
"Import cards" = "Import cards";
"Select file..." = "Select file...";
"Upload" = "Upload";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing contacts." = "An error occured while importing contacts.";
"Imported contacts:" = "Imported contacts:";

View File

@ -183,3 +183,7 @@
"Import cards" = "Import cards";
"Select file..." = "Select file...";
"Upload" = "Upload";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing contacts." = "An error occured while importing contacts.";
"Imported contacts:" = "Imported contacts:";

View File

@ -183,3 +183,7 @@
"Import cards" = "Import cards";
"Select file..." = "Select file...";
"Upload" = "Upload";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing contacts." = "An error occured while importing contacts.";
"Imported contacts:" = "Imported contacts:";

View File

@ -183,3 +183,7 @@
"Import cards" = "Import cards";
"Select file..." = "Select file...";
"Upload" = "Upload";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing contacts." = "An error occured while importing contacts.";
"Imported contacts:" = "Imported contacts:";

View File

@ -183,3 +183,7 @@
"Import cards" = "Importer des contacts";
"Select file..." = "Sélectionner un fichier...";
"Upload" = "Ajouter";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing contacts." = "Une erreur s'est produite lors de l'importation.";
"Imported contacts:" = "Contacts importés:";

View File

@ -183,3 +183,7 @@
"Import cards" = "Import cards";
"Select file..." = "Select file...";
"Upload" = "Upload";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing contacts." = "An error occured while importing contacts.";
"Imported contacts:" = "Imported contacts:";

View File

@ -183,3 +183,7 @@
"Import cards" = "Import cards";
"Select file..." = "Select file...";
"Upload" = "Upload";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing contacts." = "An error occured while importing contacts.";
"Imported contacts:" = "Imported contacts:";

View File

@ -183,3 +183,7 @@
"Import cards" = "Import cards";
"Select file..." = "Select file...";
"Upload" = "Upload";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing contacts." = "An error occured while importing contacts.";
"Imported contacts:" = "Imported contacts:";

View File

@ -168,3 +168,7 @@
"Import cards" = "Import cards";
"Select file..." = "Select file...";
"Upload" = "Upload";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing contacts." = "An error occured while importing contacts.";
"Imported contacts:" = "Imported contacts:";

View File

@ -183,3 +183,7 @@
"Import cards" = "Import cards";
"Select file..." = "Select file...";
"Upload" = "Upload";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing contacts." = "An error occured while importing contacts.";
"Imported contacts:" = "Imported contacts:";

View File

@ -35,9 +35,9 @@
NSArray *contactInfos;
}
- (void) importLdifData: (NSString *) ldifData;
- (void) importVcardData: (NSString *) vcardData;
- (void) importVcard: (NGVCard *) card;
- (int) importLdifData: (NSString *) ldifData;
- (int) importVcardData: (NSString *) vcardData;
- (BOOL) importVcard: (NGVCard *) card;
@end

View File

@ -230,26 +230,47 @@
- (id <WOActionResults>) importAction
{
WORequest *request;
WOResponse *response;
NSData *data;
NSMutableDictionary *rc;
NSString *fileContent;
int imported = 0;
request = [context request];
rc = [NSMutableDictionary dictionary];
data = (NSData *)[request formValueForKey: @"contactsFile"];
fileContent = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
fileContent = [[NSString alloc] initWithData: data
encoding: NSUTF8StringEncoding];
[fileContent autorelease];
if (fileContent && [fileContent length])
{
if ([fileContent hasPrefix: @"dn:"])
[self importLdifData: fileContent];
imported = [self importLdifData: fileContent];
else if ([fileContent hasPrefix: @"BEGIN:"])
imported = [self importVcardData: fileContent];
else
[self importVcardData: fileContent];
imported = 0;
}
return [self redirectToLocation: @"../view"];
[rc setObject: [NSNumber numberWithInt: imported]
forKey: @"imported"];
if (imported <= 0)
[rc setObject: [self labelForKey: @"An error occured while importing contacts."]
forKey: @"message"];
else
[rc setObject: [NSString stringWithFormat: @"%@ %d",
[self labelForKey: @"Imported contacts:"], imported]
forKey: @"message"];
response = [self responseWithStatus: 200];
[(WOResponse*)response appendContentString: [rc jsonRepresentation]];
return response;
}
- (void) importLdifData: (NSString *) ldifData
- (int) importLdifData: (NSString *) ldifData
{
SOGoContactGCSFolder *folder;
NSString *key, *value;
@ -258,6 +279,7 @@
NGVCard *vCard;
NSString *uid;
int i,j,count,linesCount;
int rc = 0;
folder = [self clientObject];
ldifContacts = [ldifData componentsSeparatedByString: @"\ndn"];
@ -297,25 +319,33 @@
if (ldifEntry)
{
vCard = [ldifEntry vCard];
[self importVcard: vCard];
if ([self importVcard: vCard])
rc++;
}
}
return rc;
}
- (void) importVcardData: (NSString *) vcardData
- (int) importVcardData: (NSString *) vcardData
{
NGVCard *card;
int rc;
rc = 0;
card = [NGVCard parseSingleFromSource: vcardData];
[self importVcard: card];
if ([self importVcard: card])
rc = 1;
return rc;
}
- (void) importVcard: (NGVCard *) card
- (BOOL) importVcard: (NGVCard *) card
{
NSString *uid, *name;
SOGoContactGCSFolder *folder;
NSException *ex;
BOOL rc = NO;
if (card)
{
@ -328,7 +358,11 @@
baseVersion: 0];
if (ex)
NSLog (@"write failed: %@", ex);
else
rc = YES;
}
return rc;
}

View File

@ -167,3 +167,7 @@
"Import cards" = "Import cards";
"Select file..." = "Select file...";
"Upload" = "Upload";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing contacts." = "An error occured while importing contacts.";
"Imported contacts:" = "Imported contacts:";

View File

@ -111,6 +111,10 @@
"Publish Calendar..." = "Publicar Calendário...";
"Reload Remote Calendars" = "Recarregar Calendários Remotos";
"Properties" = "Propriedades";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing calendar." = "An error occured while importing calendar.";
"Imported events:" = "Imported events:";
"Compose E-Mail to All Attendees" = "Compor E-Mail para Todos os Participantes";
"Compose E-Mail to Undecided Attendees" = "Compor E-Mail para os Participantes não confirmados";

View File

@ -111,6 +111,10 @@
"Publish Calendar..." = "Publikovat kalendář...";
"Reload Remote Calendars" = "Nahrát vzdálené kalendáře";
"Properties" = "Vlastnosti";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing calendar." = "An error occured while importing calendar.";
"Imported events:" = "Imported events:";
"Compose E-Mail to All Attendees" = "Vytvořit e-mail pro všechny účastníky";
"Compose E-Mail to Undecided Attendees" = "Vytvořit e-mail pro nerozhodnuté účastníky";

View File

@ -111,6 +111,10 @@
"Publish Calendar..." = "Agenda publiceren...";
"Reload Remote Calendars" = "Externe agenda vernieuwen";
"Properties" = "Instellingen";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing calendar." = "An error occured while importing calendar.";
"Imported events:" = "Imported events:";
"Compose E-Mail to All Attendees" = "E-mail aan alle deelnemers opstellen";
"Compose E-Mail to Undecided Attendees" = "E-mail aan deelnemers opstellen die nog niet hebben gereageerd";

View File

@ -111,6 +111,10 @@
"Publish Calendar..." = "Publish Calendar...";
"Reload Remote Calendars" = "Reload Remote Calendars";
"Properties" = "Properties";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing calendar." = "An error occured while importing calendar.";
"Imported events:" = "Imported events:";
"Compose E-Mail to All Attendees" = "Compose E-Mail to All Attendees";
"Compose E-Mail to Undecided Attendees" = "Compose E-Mail to Undecided Attendees";

View File

@ -111,6 +111,10 @@
"Publish Calendar..." = "Publier l'agenda...";
"Reload Remote Calendars" = "Recharger les agendas distants";
"Properties" = "Propriétés";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing calendar." = "Une erreur s'est produite lors de l'importation.";
"Imported events:" = "Événements importés:";
"Compose E-Mail to All Attendees" = "Rédiger un courriel pour tous les participants";
"Compose E-Mail to Undecided Attendees" = "Rédiger un courriel pour les participants indécis";

View File

@ -111,6 +111,10 @@
"Publish Calendar..." = "Kalender publizieren...";
"Reload Remote Calendars" = "Externe Kalender neu laden";
"Properties" = "Einstellungen";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing calendar." = "An error occured while importing calendar.";
"Imported events:" = "Imported events:";
"Compose E-Mail to All Attendees" = "E-Mail an alle Teilnehmer erstellen";
"Compose E-Mail to Undecided Attendees" = "E-Mail an unentschlossene Teilnehmer erstellen";

View File

@ -111,6 +111,10 @@
"Publish Calendar..." = "Naptár közzététele...";
"Reload Remote Calendars" = "Távoli naptárak frissítése";
"Properties" = "Tulajdonságok";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing calendar." = "An error occured while importing calendar.";
"Imported events:" = "Imported events:";
"Compose E-Mail to All Attendees" = "Üzenet küldése az összes résztvevőnek";
"Compose E-Mail to Undecided Attendees" = "Üzenet küldése az bizonytalan résztvevőnek";

View File

@ -111,6 +111,10 @@
"Publish Calendar..." = "Pubblica calendario...";
"Reload Remote Calendars" = "Aggiorna calendari remoti";
"Properties" = "Proprietà";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing calendar." = "An error occured while importing calendar.";
"Imported events:" = "Imported events:";
"Compose E-Mail to All Attendees" = "Invia Email a tutti gli invitati";
"Compose E-Mail to Undecided Attendees" = "Invia Email agli invitati indecisi";

View File

@ -111,6 +111,10 @@
"Publish Calendar..." = "Опубликовать календарь...";
"Reload Remote Calendars" = "Обновить удаленные календари";
"Properties" = "Свойства";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing calendar." = "An error occured while importing calendar.";
"Imported events:" = "Imported events:";
"Compose E-Mail to All Attendees" = "Составить сообщение ко всем приглашенным";
"Compose E-Mail to Undecided Attendees" = "Составить сообщение ко всем не решившим приглашенным";

View File

@ -111,6 +111,10 @@
"Publish Calendar..." = "Publicar calendario...";
"Reload Remote Calendars" = "Recargar calendarios remotos";
"Properties" = "Propiedades";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing calendar." = "An error occured while importing calendar.";
"Imported events:" = "Imported events:";
"Compose E-Mail to All Attendees" = "Crear correo para todos los asistentes";
"Compose E-Mail to Undecided Attendees" = "Crear correo para todos los asistentes indecisos (sin confirmación)";

View File

@ -20,6 +20,11 @@
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/Foundation.h>
#import <SoObjects/SOGo/NSArray+Utilities.h>
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
#import <SoObjects/SOGo/NSString+Utilities.h>
#import <NGObjWeb/SoSecurityManager.h>
#import <NGObjWeb/SoUser.h>
#import <NGObjWeb/WOResponse.h>
@ -697,20 +702,25 @@ static BOOL shouldDisplayWeekend = NO;
- (WOResponse *) importAction
{
SOGoAppointmentFolder *folder;
NSMutableDictionary *rc;
NSArray *components;
WORequest *request;
WOResponse *response;
NSString *fileContent;
NSData *data;
iCalCalendar *additions;
int i, count;
int i, count, imported;
imported = 0;
rc = [NSMutableDictionary dictionary];
request = [context request];
folder = [self clientObject];
data = (NSData *)[request formValueForKey: @"calendarFile"];
fileContent = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
[fileContent autorelease];
if (fileContent && [fileContent length])
if (fileContent && [fileContent length]
&& [fileContent hasPrefix: @"BEGIN:"])
{
additions = [iCalCalendar parseSingleFromSource: fileContent];
if (additions)
@ -718,22 +728,39 @@ static BOOL shouldDisplayWeekend = NO;
components = [additions events];
count = [components count];
for (i = 0; i < count; i++)
[folder importComponent: [components objectAtIndex: i]];
if ([folder importComponent: [components objectAtIndex: i]])
imported++;
components = [additions todos];
count = [components count];
for (i = 0; i < count; i++)
[folder importComponent: [components objectAtIndex: i]];
if ([folder importComponent: [components objectAtIndex: i]])
imported++;
components = [additions journals];
count = [components count];
for (i = 0; i < count; i++)
[folder importComponent: [components objectAtIndex: i]];
if ([folder importComponent: [components objectAtIndex: i]])
imported++;
components = [additions freeBusys];
count = [components count];
for (i = 0; i < count; i++)
[folder importComponent: [components objectAtIndex: i]];
if ([folder importComponent: [components objectAtIndex: i]])
imported++;
}
}
return [self redirectToLocation: @"../view"];
[rc setObject: [NSNumber numberWithInt: imported]
forKey: @"imported"];
if (imported <= 0)
[rc setObject: [self labelForKey: @"An error occured while importing calendar."]
forKey: @"message"];
else
[rc setObject: [NSString stringWithFormat: @"%@ %d",
[self labelForKey: @"Imported events:"], imported]
forKey: @"message"];
response = [self responseWithStatus: 200];
[(WOResponse*)response appendContentString: [rc jsonRepresentation]];
return response;
}
@end /* UIxCalView */

View File

@ -111,6 +111,10 @@
"Publish Calendar..." = "Cyhoeddi Calendr...";
"Reload Remote Calendars" = "Ail-lwytho Calendrau Anghysbell";
"Properties" = "Dewisiadau";
"Import" = "Import";
"OK" = "OK";
"An error occured while importing calendar." = "An error occured while importing calendar.";
"Imported events:" = "Imported events:";
"Compose E-Mail to All Attendees" = "Cyfansoddi Ebost i bawb sy'n mynychu";
"Compose E-Mail to Undecided Attendees" = "Cyfansoddi Ebost i bawb sydd heb benderfynu";

View File

@ -30,13 +30,23 @@
<h3><var:string label:value="Select file..."/></h3>
<form name="uploadForm" id="uploadForm" method="post"
enctype="multipart/form-data"
onsubmit="return validateUploadForm()">
onsubmit="return AIM.submit(this, {'onStart' : validateUploadForm,
'onComplete' : uploadCompleted})">
<p><input type="file" name="contactsFile" id="contactsFile" /></p>
<p><input class="button" type="submit" const:id="uploadSubmit" label:value="Upload"/>
<input class="button" type="button" const:id="uploadCancel" label:value="Cancel"/></p>
</form>
</div>
</div>
<div id="uploadResults" style="display: none" class="dialog left">
<div>
<h3><var:string label:value="Import"/></h3>
<p id="uploadResultsContent"></p>
<p><input class="button" type="button" const:id="uploadOK"
label:value="OK"/></p>
</div>
</div>
<div class="menu" id="contactFoldersMenu">
<ul>

View File

@ -103,7 +103,8 @@
<h3><var:string label:value="Select file..."/></h3>
<form name="uploadForm" id="uploadForm" method="post"
enctype="multipart/form-data"
onsubmit="return validateUploadForm()">
onsubmit="return AIM.submit(this, {'onStart' : validateUploadForm,
'onComplete' : uploadCompleted})">
<p><input type="file" name="calendarFile" id="calendarFile" /></p>
<p><input class="button" type="submit" const:id="uploadSubmit" label:value="Upload"/>
<input class="button" type="button" const:id="uploadCancel" label:value="Cancel"/></p>
@ -111,6 +112,15 @@
</div>
</div>
<div id="uploadResults" style="display: none" class="dialog left">
<div>
<h3><var:string label:value="Import"/></h3>
<p id="uploadResultsContent"></p>
<p><input class="button" type="button" const:id="uploadOK"
label:value="OK"/></p>
</div>
</div>
<div id="leftPanel">
<div class="tabsContainer" id="schedulerTabs">
<ul>

View File

@ -670,19 +670,40 @@ function onAddressBookImport(event) {
var top = cellPosition[1];
var div = $("uploadDialog");
var res = $("uploadResults");
div.style.top = top + "px";
res.style.top = top + "px";
div.style.left = left + "px";
res.style.left = left + "px";
div.style.display = "block";
}
function hideContactsImport () {
$("uploadDialog").style.display = "none";
}
function hideImportResults () {
$("uploadResults").style.display = "none";
}
function validateUploadForm () {
rc = false;
if ($("contactsFile").value.length)
rc = true;
return rc;
}
function uploadCompleted (response) {
response = response.replace (/<pre>/, "");
response = response.replace (/<\/pre>/, "");
data = response.evalJSON (true);
var div = $("uploadResults");
$("uploadOK").onclick = hideImportResults;
$("uploadResultsContent").update (data.message);
if (data.imported > 0)
refreshCurrentFolder ();
hideContactsImport ();
$("uploadResults").style.display = "block";
}
function onAddressBookRemove(event) {
var selector = $("contactFolders");

View File

@ -1904,19 +1904,40 @@ function onCalendarImport(event) {
var top = cellPosition[1];
var div = $("uploadDialog");
var res = $("uploadResults");
div.style.top = top + "px";
res.style.top = top + "px";
div.style.left = left + "px";
res.style.left = left + "px";
div.style.display = "block";
}
function hideCalendarImport () {
$("uploadDialog").style.display = "none";
}
function hideImportResults () {
$("uploadResults").style.display = "none";
}
function validateUploadForm () {
rc = false;
if ($("calendarFile").value.length)
rc = true;
return rc;
}
function uploadCompleted (response) {
response = response.replace (/<pre>/, "");
response = response.replace (/<\/pre>/, "");
data = response.evalJSON (true);
var div = $("uploadResults");
$("uploadOK").onclick = hideImportResults;
$("uploadResultsContent").update (data.message);
if (data.imported > 0)
refreshCurrentFolder ();
hideCalendarImport ();
$("uploadResults").style.display = "block";
}
function setEventsOnCalendar(checkBox, li) {
li.observe("mousedown", listRowMouseDownHandler);

View File

@ -783,11 +783,13 @@ DIV.resize-handle
color: #000000 !important;
}
DIV#uploadDialog
DIV#uploadDialog,DIV#uploadResults
{ border-width: 1px;
width: 260px;
height: 118px;
}
height: 127px; }
DIV#uploadDialog DIV,DIV#uploadResults DIV
{ width: 260px;
height: 115px; }
DIV.dialog
{ position: absolute;

View File

@ -1672,4 +1672,54 @@ function onHeaderClick(event) {
window.alert("generic headerClick");
}
/**
*
* AJAX IFRAME METHOD (AIM)
* http://www.webtoolkit.info/
*
**/
AIM = {
frame : function(c) {
var d = new Element ('div');
var n = d.identify ();
d.innerHTML = '<iframe style="display:none" src="about:blank" id="'
+ n + '" name="' + n + '" onload="AIM.loaded(\'' + n + '\')"></iframe>';
document.body.appendChild(d);
var i = $(n); // TODO: useful?
if (c && typeof(c.onComplete) == 'function')
i.onComplete = c.onComplete;
return n;
},
form : function(f, name) {
f.writeAttribute('target', name);
},
submit : function(f, c) {
AIM.form(f, AIM.frame(c));
if (c && typeof(c.onStart) == 'function')
return c.onStart();
else
return true;
},
loaded : function(id) {
var i = $(id);
if (i.contentDocument)
var d = i.contentDocument;
else if (i.contentWindow)
var d = i.contentWindow.document;
else
var d = window.frames[id].document;
if (d.location.href == "about:blank")
return;
if (typeof(i.onComplete) == 'function')
i.onComplete(d.body.innerHTML);
}
}
document.observe("dom:loaded", onLoadHandler);