mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-05-26 13:55:23 +00:00
merge of '785de8feba6c3e190c55defa1a5e18e85c9b82ba'
and '9fc56cd3ca7051c4b29662926289d2cb181bc57a' Monotone-Parent: 785de8feba6c3e190c55defa1a5e18e85c9b82ba Monotone-Parent: 9fc56cd3ca7051c4b29662926289d2cb181bc57a Monotone-Revision: 33545be02b741723c3eb86718dc21f534032fc81 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-04-18T20:09:02 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
@@ -1,3 +1,53 @@
|
||||
2012-04-18 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* UI/WebServerResources/generic.js (showAuthenticationDialog): new
|
||||
dialog providing an interface for requesting a username and a
|
||||
password to acallback passed as parameter.
|
||||
(accessToSubscribedFolder): fixed method to return the proper url
|
||||
for folders owned by the active user.
|
||||
|
||||
* UI/WebServerResources/SchedulerUI.js (reloadWebCalendars): now
|
||||
invokes "reloadAction" on every web calendar foldar, in a chain of
|
||||
simultaneous requests.
|
||||
(reloadWebCalendar): new function invoking "reloadAction" on a
|
||||
single cal folder.
|
||||
(reloadWebCalendarCallback): callback for the above invocation
|
||||
that takes care of refreshing the views at the end of a refresh
|
||||
chain, if present, and when useful.
|
||||
|
||||
* UI/Scheduler/UIxCalFolderActions.m (reloadAction): new web
|
||||
method that applies only to SOGoWebAppointmentFolder instances and
|
||||
which returns a JSON representation of the result returned by
|
||||
-[SOGoWebAppointmentFolder loadWebCalendar]. This method replaces
|
||||
-[UIxCalMainActions -reloadWebCalendars].
|
||||
(setCredentialsAction): new web method acting as a proxy for
|
||||
-[SOGoWebAppointmentFolder setUsername:andPassword:].
|
||||
|
||||
* UI/WebServerResources/generic.js (clickEventWrapper): new
|
||||
function that returns a wrapper function for click callbacks which
|
||||
invokes "preventDefault" on the "event" parameter before it is
|
||||
passed to the real callback.
|
||||
|
||||
* UI/Scheduler/UIxCalMainActions.m
|
||||
(-reloadWebCalendarsAndRedirectAction): removed obsolete method.
|
||||
(-reloadWebCalendars): removed obsolete method.
|
||||
|
||||
* SoObjects/Appointments/SOGoAppointmentFolders.m
|
||||
(-newWebCalendarWithName:atURL:): perform sanity checks on the url
|
||||
parameter.
|
||||
|
||||
* SoObjects/Appointments/SOGoWebAppointmentFolder.m
|
||||
(-setUsername:andPassword:): new method that associate an
|
||||
encrypted login pair for authenticating to remove calendars.
|
||||
(-loadWebCalendar): rewrote method to make use of curl, thereby
|
||||
permitting HTTP authentication. A NSDictionary containing
|
||||
different informations about the connection is not returned,
|
||||
including the HTTP status and an error tag, when required.
|
||||
|
||||
* SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||
(-importCalendar:): journals and freebusys are not
|
||||
supported.
|
||||
|
||||
2012-04-16 Jean Raby <jraby@inverse.ca>
|
||||
|
||||
* SOPE/NGCards/iCalMonthlyRecurrenceCalculator.m
|
||||
|
||||
@@ -2746,8 +2746,8 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
components = [[calendar events] mutableCopy];
|
||||
[components autorelease];
|
||||
[components addObjectsFromArray: [calendar todos]];
|
||||
[components addObjectsFromArray: [calendar journals]];
|
||||
[components addObjectsFromArray: [calendar freeBusys]];
|
||||
// [components addObjectsFromArray: [calendar journals]];
|
||||
// [components addObjectsFromArray: [calendar freeBusys]];
|
||||
count = [components count];
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSEnumerator.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGObjWeb/WORequest+So.h>
|
||||
@@ -133,25 +134,35 @@ static SoSecurityManager *sm = nil;
|
||||
|
||||
- (SOGoWebAppointmentFolder *)
|
||||
newWebCalendarWithName: (NSString *) folderDisplayName
|
||||
atURL: (NSString *) url
|
||||
atURL: (NSString *) urlString
|
||||
{
|
||||
NSException *error;
|
||||
SOGoAppointmentFolder *aptFolder;
|
||||
SOGoWebAppointmentFolder *webCalendar;
|
||||
NSString *name;
|
||||
NSURL *url;
|
||||
|
||||
if ([self newFolderWithName: folderDisplayName
|
||||
nameInContainer: &name])
|
||||
webCalendar = nil;
|
||||
else
|
||||
webCalendar = nil;
|
||||
|
||||
if ([folderDisplayName length] > 0 && [urlString length] > 0)
|
||||
{
|
||||
aptFolder = [subFolders objectForKey: name];
|
||||
[aptFolder setFolderPropertyValue: url
|
||||
inCategory: @"WebCalendars"];
|
||||
|
||||
webCalendar = [SOGoWebAppointmentFolder objectWithName: name
|
||||
inContainer: self];
|
||||
[webCalendar setOCSPath: [aptFolder ocsPath]];
|
||||
[subFolders setObject: webCalendar forKey: name];
|
||||
url = [NSURL URLWithString: urlString];
|
||||
if ([[url scheme] hasPrefix: @"http"])
|
||||
{
|
||||
error = [self newFolderWithName: folderDisplayName
|
||||
nameInContainer: &name];
|
||||
if (!error)
|
||||
{
|
||||
aptFolder = [subFolders objectForKey: name];
|
||||
[aptFolder setFolderPropertyValue: urlString
|
||||
inCategory: @"WebCalendars"];
|
||||
|
||||
webCalendar = [SOGoWebAppointmentFolder objectWithName: name
|
||||
inContainer: self];
|
||||
[webCalendar setOCSPath: [aptFolder ocsPath]];
|
||||
[subFolders setObject: webCalendar forKey: name];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return webCalendar;
|
||||
@@ -542,6 +553,7 @@ static SoSecurityManager *sm = nil;
|
||||
calSettings = [us objectForKey: @"Calendar"];
|
||||
refs = [[calSettings objectForKey: @"WebCalendars"] allKeys];
|
||||
max = [refs count];
|
||||
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
ref = [refs objectAtIndex: count];
|
||||
|
||||
@@ -27,7 +27,10 @@
|
||||
|
||||
@interface SOGoWebAppointmentFolder : SOGoAppointmentFolder
|
||||
|
||||
- (int) loadWebCalendar;
|
||||
- (void) setUsername: (NSString *) username
|
||||
andPassword: (NSString *) password;
|
||||
|
||||
- (NSDictionary *) loadWebCalendar;
|
||||
- (void) deleteAllContent;
|
||||
|
||||
- (void) setReloadOnLogin: (BOOL) newReloadOnLogin;
|
||||
|
||||
@@ -21,12 +21,26 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <curl/curl.h>
|
||||
|
||||
#import <Foundation/NSData.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
|
||||
#import <NGObjWeb/WOHTTPConnection.h>
|
||||
#import <NGObjWeb/WORequest.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <NGHttp/NGHttpResponse.h>
|
||||
|
||||
#import <NGCards/iCalCalendar.h>
|
||||
#import <GDLContentStore/GCSFolder.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <SoObjects/SOGo/SOGoUser.h>
|
||||
#import <SoObjects/SOGo/SOGoUserSettings.h>
|
||||
#import <SOGo/SOGoAuthenticator.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/SOGoUserSettings.h>
|
||||
#import <SOGo/NSDictionary+Utilities.h>
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
|
||||
#import "SOGoWebAppointmentFolder.h"
|
||||
|
||||
@@ -39,45 +53,154 @@
|
||||
[[self ocsFolder] deleteAllContent];
|
||||
}
|
||||
|
||||
- (int) loadWebCalendar
|
||||
- (NSDictionary *) _loadAuthData
|
||||
{
|
||||
NSString *location, *contents;
|
||||
WOHTTPURLHandle *handle;
|
||||
iCalCalendar *calendar;
|
||||
NSData *data;
|
||||
NSDictionary *authData;
|
||||
NSString *authValue, *userPassword;
|
||||
NSArray *parts, *keys;
|
||||
|
||||
userPassword = [[self authenticatorInContext: context]
|
||||
passwordInContext: context];
|
||||
if ([userPassword length] == 0)
|
||||
{
|
||||
authData = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
authValue
|
||||
= [[self folderPropertyValueInCategory: @"WebCalendarsAuthentication"]
|
||||
decryptWithKey: userPassword];
|
||||
parts = [authValue componentsSeparatedByString: @":"];
|
||||
if ([parts count] == 2)
|
||||
{
|
||||
keys = [NSArray arrayWithObjects: @"username", @"password", nil];
|
||||
authData = [NSDictionary dictionaryWithObjects: parts
|
||||
forKeys: keys];
|
||||
}
|
||||
else
|
||||
authData = nil;
|
||||
}
|
||||
|
||||
return authData;
|
||||
}
|
||||
|
||||
- (void) setUsername: (NSString *) username
|
||||
andPassword: (NSString *) password
|
||||
{
|
||||
NSString *authValue, *userPassword;
|
||||
|
||||
userPassword = [[self authenticatorInContext: context]
|
||||
passwordInContext: context];
|
||||
if ([userPassword length] > 0)
|
||||
{
|
||||
if (!username)
|
||||
username = @"";
|
||||
if (!password)
|
||||
password = @"";
|
||||
authValue = [NSString stringWithFormat: @"%@:%@", username, password];
|
||||
[self setFolderPropertyValue: [authValue encryptWithKey: userPassword]
|
||||
inCategory: @"WebCalendarsAuthentication"];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDictionary *) loadWebCalendar
|
||||
{
|
||||
NSString *location, *httpauth;
|
||||
NSDictionary *authInfos;
|
||||
NSMutableData *bodyData;
|
||||
NSURL *url;
|
||||
CURL *curl;
|
||||
CURLcode rc;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
NSMutableDictionary *result;
|
||||
NSString *content, *newDisplayName;
|
||||
iCalCalendar *calendar;
|
||||
NSUInteger imported, status;
|
||||
|
||||
int imported = 0;
|
||||
result = [NSMutableDictionary dictionary];
|
||||
|
||||
// Prepare HTTPS post using libcurl
|
||||
location = [self folderPropertyValueInCategory: @"WebCalendars"];
|
||||
[result setObject: location forKey: @"url"];
|
||||
|
||||
url = [NSURL URLWithString: location];
|
||||
if (url)
|
||||
{
|
||||
handle = AUTORELEASE([[WOHTTPURLHandle alloc] initWithURL: url cached: NO]);
|
||||
data = [handle resourceData];
|
||||
|
||||
if (!data && [[location lowercaseString] hasPrefix: @"https"])
|
||||
{
|
||||
NSLog(@"WARNING: Your GNUstep/SOPE installation might not have SSL support.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
contents = [[NSString alloc] initWithData: data
|
||||
encoding: NSUTF8StringEncoding];
|
||||
[contents autorelease];
|
||||
calendar = [iCalCalendar parseSingleFromSource: contents];
|
||||
if (calendar)
|
||||
curl_global_init (CURL_GLOBAL_SSL);
|
||||
curl = curl_easy_init ();
|
||||
if (curl)
|
||||
{
|
||||
[self deleteAllContent];
|
||||
imported = [self importCalendar: calendar];
|
||||
}
|
||||
else
|
||||
{
|
||||
imported = -1;
|
||||
curl_easy_setopt (curl, CURLOPT_URL, [location UTF8String]);
|
||||
curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
|
||||
authInfos = [self _loadAuthData];
|
||||
if (authInfos)
|
||||
{
|
||||
httpauth = [authInfos keysWithFormat: @"%{username}:%{password}"];
|
||||
curl_easy_setopt (curl, CURLOPT_USERPWD, [httpauth UTF8String]);
|
||||
curl_easy_setopt (curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
|
||||
}
|
||||
|
||||
bodyData = [NSMutableData data];
|
||||
size_t curlBodyFunction (void *ptr, size_t size, size_t nmemb, void *inSelf)
|
||||
{
|
||||
size_t total;
|
||||
|
||||
total = size * nmemb;
|
||||
[bodyData appendBytes: ptr length: total];
|
||||
|
||||
return total;
|
||||
}
|
||||
curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, curlBodyFunction);
|
||||
|
||||
error[0] = 0;
|
||||
curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, &error);
|
||||
|
||||
// Perform SOAP request
|
||||
rc = curl_easy_perform (curl);
|
||||
if (rc == 0)
|
||||
{
|
||||
curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &status);
|
||||
[result setObject: [NSNumber numberWithUnsignedInt: status]
|
||||
forKey: @"status"];
|
||||
|
||||
if (status == 200)
|
||||
{
|
||||
content = [[NSString alloc] initWithData: bodyData
|
||||
encoding: NSUTF8StringEncoding];
|
||||
if (!content)
|
||||
content = [[NSString alloc] initWithData: bodyData
|
||||
encoding: NSISOLatin1StringEncoding];
|
||||
[content autorelease];
|
||||
calendar = [iCalCalendar parseSingleFromSource: content];
|
||||
if (calendar)
|
||||
{
|
||||
newDisplayName = [[calendar
|
||||
firstChildWithTag: @"x-wr-calname"]
|
||||
flattenedValuesForKey: @""];
|
||||
if ([newDisplayName length] > 0)
|
||||
[self setDisplayName: newDisplayName];
|
||||
[self deleteAllContent];
|
||||
imported = [self importCalendar: calendar];
|
||||
[result setObject: [NSNumber numberWithInt: imported]
|
||||
forKey: @"imported"];
|
||||
}
|
||||
else
|
||||
[result setObject: @"invalid-calendar-content" forKey: @"error"];
|
||||
}
|
||||
else
|
||||
[result setObject: @"http-error" forKey: @"error"];
|
||||
}
|
||||
else
|
||||
[result setObject: @"bad-url" forKey: @"error"];
|
||||
curl_easy_cleanup (curl);
|
||||
}
|
||||
}
|
||||
|
||||
return imported;
|
||||
else
|
||||
[result setObject: @"invalid-url" forKey: @"error"];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void) setReloadOnLogin: (BOOL) newReloadOnLogin
|
||||
@@ -98,7 +221,10 @@
|
||||
|
||||
error = [super delete];
|
||||
if (!error)
|
||||
[self setFolderPropertyValue: nil inCategory: @"WebCalendars"];
|
||||
{
|
||||
[self setFolderPropertyValue: nil inCategory: @"WebCalendars"];
|
||||
[self setFolderPropertyValue: nil inCategory: @"WebCalendarsAuthentication"];
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Recarregar Calendários Remotos";
|
||||
"Properties" = "Propriedades";
|
||||
"Done" = "Feito";
|
||||
"An error occured while importing calendar." = "Um erro ocorreu na importação do calendário.";
|
||||
"An error occurred while importing calendar." = "Um erro ocorreu na importação do calendário.";
|
||||
"No event was imported." = "Nenhum evento importado.";
|
||||
"A total of %{0} events were imported in the calendar." = "Um total de %{0} eventos foram importados no calendário.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Actualitzar calendaris remots";
|
||||
"Properties" = "Propietats";
|
||||
"Done" = "Fet";
|
||||
"An error occured while importing calendar." = "Hi ha hagut un error en importar el calendari.";
|
||||
"An error occurred while importing calendar." = "Hi ha hagut un error en importar el calendari.";
|
||||
"No event was imported." = "No s'ha importat cap esdeveniment.";
|
||||
"A total of %{0} events were imported in the calendar." = "Han estat importats %{0} esdeveniments al calendari.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Aktualizovat vzdálené kalendáře";
|
||||
"Properties" = "Vlastnosti";
|
||||
"Done" = "Hotovo";
|
||||
"An error occured while importing calendar." = "Při importu událostí došlo k chybě.";
|
||||
"An error occurred while importing calendar." = "Při importu událostí došlo k chybě.";
|
||||
"No event was imported." = "Nebyla importována žádná událost.";
|
||||
"A total of %{0} events were imported in the calendar." = "Do kalendáře bylo importováno %{0} událostí.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Opdatér kalendere";
|
||||
"Properties" = "Egenskaber";
|
||||
"Done" = "Udført";
|
||||
"An error occured while importing calendar." = "Der opstod en fejl under importering af kalender.";
|
||||
"An error occurred while importing calendar." = "Der opstod en fejl under importering af kalender.";
|
||||
"No event was imported." = "Ingen begivenhed blev importeret.";
|
||||
"A total of %{0} events were imported in the calendar." = "I alt %{0} begivenheder blev importeret i kalenderen.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Externe agenda herladen";
|
||||
"Properties" = "Instellingen";
|
||||
"Done" = "Klaar";
|
||||
"An error occured while importing calendar." = "Er is een fout opgetreden bij het importeren van de kalender.";
|
||||
"An error occurred while importing calendar." = "Er is een fout opgetreden bij het importeren van de kalender.";
|
||||
"No event was imported." = "Geen enkele gebeurtenis werd geïmporteerd.";
|
||||
"A total of %{0} events were imported in the calendar." = "Een totaal van %{0} gebeurtenissen werd geïmporteerd in de kalender.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Reload Remote Calendars";
|
||||
"Properties" = "Properties";
|
||||
"Done" = "Done";
|
||||
"An error occured while importing calendar." = "An error occured while importing calendar.";
|
||||
"An error occurred while importing calendar." = "An error occurred while importing calendar.";
|
||||
"No event was imported." = "No event was imported.";
|
||||
"A total of %{0} events were imported in the calendar." = "A total of %{0} events were imported in the calendar.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Recharger les agendas distants";
|
||||
"Properties" = "Propriétés";
|
||||
"Done" = "Terminer";
|
||||
"An error occured while importing calendar." = "Une erreur s'est produite lors de l'importation.";
|
||||
"An error occurred while importing calendar." = "Une erreur s'est produite lors de l'importation.";
|
||||
"No event was imported." = "Aucun événement n'a été importé.";
|
||||
"A total of %{0} events were imported in the calendar." = "Un total de %{0} événements ont été importés dans le calendrier.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Externe Kalender neu laden";
|
||||
"Properties" = "Einstellungen";
|
||||
"Done" = "Fertig";
|
||||
"An error occured while importing calendar." = "Fehler während des Importierens von Terminen.";
|
||||
"An error occurred while importing calendar." = "Fehler während des Importierens von Terminen.";
|
||||
"No event was imported." = "Es wurden keine Termine importiert.";
|
||||
"A total of %{0} events were imported in the calendar." = "%{0} Termine wurden in den Kalender importiert.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Távoli naptárak frissítése";
|
||||
"Properties" = "Tulajdonságok";
|
||||
"Done" = "Kész";
|
||||
"An error occured while importing calendar." = "Hiba történt a naptár importálásakor.";
|
||||
"An error occurred while importing calendar." = "Hiba történt a naptár importálásakor.";
|
||||
"No event was imported." = "Nem volt importált esemény.";
|
||||
"A total of %{0} events were imported in the calendar." = "Összesen %{0} esemény lett importálva a naptárba.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Reload Remote Calendars";
|
||||
"Properties" = "Eiginleikar";
|
||||
"Done" = "Ljúka";
|
||||
"An error occured while importing calendar." = "Villa kom upp þegar dagatalið var flutt inn.";
|
||||
"An error occurred while importing calendar." = "Villa kom upp þegar dagatalið var flutt inn.";
|
||||
"No event was imported." = "Enginn viðburður var fluttur inn.";
|
||||
"A total of %{0} events were imported in the calendar." = "Alls voru %{0} viðburðir fluttir inn í dagatalið.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Aggiorna calendari remoti";
|
||||
"Properties" = "Proprietà";
|
||||
"Done" = "Fatto";
|
||||
"An error occured while importing calendar." = "Si è verificato un errore durante l'importazione del calendario.";
|
||||
"An error occurred while importing calendar." = "Si è verificato un errore durante l'importazione del calendario.";
|
||||
"No event was imported." = "Nessun evento è stato importato.";
|
||||
"A total of %{0} events were imported in the calendar." = "Un totale di %{0} sono stati importati nel calendario.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Last på nytt fjernkalendre";
|
||||
"Properties" = "Egenskaper";
|
||||
"Done" = "Klar";
|
||||
"An error occured while importing calendar." = "En feil har oppstått under kalenderimporten.";
|
||||
"An error occurred while importing calendar." = "En feil har oppstått under kalenderimporten.";
|
||||
"No event was imported." = "Ingen hendelser ble importert.";
|
||||
"A total of %{0} events were imported in the calendar." = "Totalt %{0} hendelser ble importert til kalenderen.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Last på nytt fjernkalendre";
|
||||
"Properties" = "Egenskaper";
|
||||
"Done" = "Klar";
|
||||
"An error occured while importing calendar." = "En feil har oppstått under kalenderimporten.";
|
||||
"An error occurred while importing calendar." = "En feil har oppstått under kalenderimporten.";
|
||||
"No event was imported." = "Ingen hendelser ble importert.";
|
||||
"A total of %{0} events were imported in the calendar." = "Totalt %{0} hendelser ble importert til kalenderen.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Przeładuj zdalne kalendarze";
|
||||
"Properties" = "Właściwości";
|
||||
"Done" = "Zrobione";
|
||||
"An error occured while importing calendar." = "Błąd w trakcie importu kalendarza.";
|
||||
"An error occurred while importing calendar." = "Błąd w trakcie importu kalendarza.";
|
||||
"No event was imported." = "Nie zaimportowano żadnego wydarzenia.";
|
||||
"A total of %{0} events were imported in the calendar." = "Do kalendarza zaimportowano razem %{0} wydarzeń(nia).";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Обновить удаленные календари";
|
||||
"Properties" = "Свойства";
|
||||
"Done" = "Готово";
|
||||
"An error occured while importing calendar." = "Ошибка при импорте календаря.";
|
||||
"An error occurred while importing calendar." = "Ошибка при импорте календаря.";
|
||||
"No event was imported." = "События не были импортированы.";
|
||||
"A total of %{0} events were imported in the calendar." = " Всего %{0} событий было импортировано в календарь.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Recargar calendarios remotos";
|
||||
"Properties" = "Propiedades";
|
||||
"Done" = "Hecho";
|
||||
"An error occured while importing calendar." = "Ha ocurrido un error mientras importaba el calendario.";
|
||||
"An error occurred while importing calendar." = "Ha ocurrido un error mientras importaba el calendario.";
|
||||
"No event was imported." = "El evento no fue importado.";
|
||||
"A total of %{0} events were imported in the calendar." = "Un total de %{0} eventos fueron importados al calendario.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Recargar calendarios remotos";
|
||||
"Properties" = "Propiedades";
|
||||
"Done" = "Hecho";
|
||||
"An error occured while importing calendar." = "Ha ocurido un error mientras importaba el calendario.";
|
||||
"An error occurred while importing calendar." = "Ha ocurido un error mientras importaba el calendario.";
|
||||
"No event was imported." = "El evento no fue importado.";
|
||||
"A total of %{0} events were imported in the calendar." = "Un total de %{0} eventos fueron importados al calendario.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Ladda om fjärrkalendrar";
|
||||
"Properties" = "Egenskaper";
|
||||
"Done" = "Klar";
|
||||
"An error occured while importing calendar." = "Ett fel har inträffat under kalenderimporten.";
|
||||
"An error occurred while importing calendar." = "Ett fel har inträffat under kalenderimporten.";
|
||||
"No event was imported." = "Inga händeler importerades.";
|
||||
"A total of %{0} events were imported in the calendar." = "Totalt %{0} händelser importerades till kalendern.";
|
||||
|
||||
|
||||
@@ -20,12 +20,13 @@
|
||||
*/
|
||||
|
||||
#import <Foundation/NSValue.h>
|
||||
|
||||
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
|
||||
|
||||
#import <NGObjWeb/NSException+HTTP.h>
|
||||
#import <NGObjWeb/WORequest.h>
|
||||
|
||||
#import <SOGo/NSDictionary+Utilities.h>
|
||||
|
||||
#import <Appointments/SOGoAppointmentFolder.h>
|
||||
#import <Appointments/SOGoWebAppointmentFolder.h>
|
||||
#import <Appointments/SOGoAppointmentFolderICS.h>
|
||||
|
||||
#import "UIxCalFolderActions.h"
|
||||
@@ -95,4 +96,43 @@
|
||||
return response;
|
||||
}
|
||||
|
||||
/* These methods are only available on instance of SOGoWebAppointmentFolder. */
|
||||
- (WOResponse *) reloadAction
|
||||
{
|
||||
WOResponse *response;
|
||||
NSDictionary *results;
|
||||
|
||||
response = [self responseWithStatus: 200];
|
||||
[response setHeader: @"application/json" forKey: @"content-type"];
|
||||
results = [[self clientObject] loadWebCalendar];
|
||||
[response appendContentString: [results jsonRepresentation]];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
- (WOResponse *) setCredentialsAction
|
||||
{
|
||||
WORequest *request;
|
||||
WOResponse *response;
|
||||
NSString *username, *password;
|
||||
|
||||
request = [context request];
|
||||
|
||||
username = [[request formValueForKey: @"username"] stringByTrimmingSpaces];
|
||||
password = [[request formValueForKey: @"password"] stringByTrimmingSpaces];
|
||||
if ([username length] > 0 && [password length] > 0)
|
||||
{
|
||||
[[self clientObject] setUsername: username
|
||||
andPassword: password];
|
||||
response = [self responseWith204];
|
||||
}
|
||||
else
|
||||
response
|
||||
= (WOResponse *) [NSException exceptionWithHTTPStatus: 400
|
||||
reason: @"missing 'username' and/or"
|
||||
@" 'password' parameters"];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@end /* UIxCalFolderActions */
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <NGObjWeb/NSException+HTTP.h>
|
||||
#import <NGObjWeb/WOContext.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGObjWeb/WORequest.h>
|
||||
@@ -29,6 +30,7 @@
|
||||
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/SOGoUserSettings.h>
|
||||
#import <SOGo/NSArray+Utilities.h>
|
||||
#import <SOGo/NSDictionary+Utilities.h>
|
||||
#import <Appointments/SOGoWebAppointmentFolder.h>
|
||||
#import <Appointments/SOGoAppointmentFolders.h>
|
||||
@@ -60,68 +62,41 @@
|
||||
WORequest *r;
|
||||
WOResponse *response;
|
||||
SOGoWebAppointmentFolder *folder;
|
||||
NSURL *url;
|
||||
NSString *urlString, *displayName;
|
||||
NSMutableDictionary *rc;
|
||||
SOGoAppointmentFolders *folders;
|
||||
int imported = 0;
|
||||
|
||||
r = [context request];
|
||||
rc = [NSMutableDictionary dictionary];
|
||||
|
||||
// Just a check
|
||||
urlString = [r formValueForKey: @"url"];
|
||||
url = [NSURL URLWithString: urlString];
|
||||
if (url)
|
||||
urlString = [[r formValueForKey: @"url"] stringByTrimmingSpaces];
|
||||
if ([urlString length] > 0)
|
||||
{
|
||||
folders = [self clientObject];
|
||||
displayName = [self displayNameForUrl: [r formValueForKey: @"url"]];
|
||||
displayName = [self displayNameForUrl: urlString];
|
||||
folder = [folders newWebCalendarWithName: displayName
|
||||
atURL: urlString];
|
||||
if (folder)
|
||||
{
|
||||
imported = [folder loadWebCalendar];
|
||||
if (imported >= 0)
|
||||
{
|
||||
[rc setObject: displayName forKey: @"displayname"];
|
||||
[rc setObject: [folder nameInContainer] forKey: @"name"];
|
||||
}
|
||||
else
|
||||
{
|
||||
[folder delete];
|
||||
}
|
||||
[rc setObject: [NSNumber numberWithInt: imported]
|
||||
forKey: @"imported"];
|
||||
response = [self responseWithStatus: 200];
|
||||
[response setHeader: @"application/json" forKey: @"content-type"];
|
||||
|
||||
rc = [NSMutableDictionary dictionary];
|
||||
[rc setObject: [folder displayName] forKey: @"name"];
|
||||
[rc setObject: [folder folderReference] forKey: @"folderID"];
|
||||
[response appendContentString: [rc jsonRepresentation]];
|
||||
}
|
||||
else
|
||||
response = (WOResponse *)
|
||||
[NSException exceptionWithHTTPStatus: 400
|
||||
reason: @"folder was not created"];
|
||||
}
|
||||
else
|
||||
response = (WOResponse *)
|
||||
[NSException exceptionWithHTTPStatus: 400
|
||||
reason: @"missing 'url' parameter"];
|
||||
|
||||
response = [self responseWithStatus: 200];
|
||||
[response appendContentString: [rc jsonRepresentation]];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
- (WOResponse *) reloadWebCalendarsAction
|
||||
{
|
||||
[[self clientObject] reloadWebCalendars: YES];
|
||||
|
||||
return [self responseWith204];
|
||||
}
|
||||
|
||||
//
|
||||
// The method below is different than the -reloadWebCalendarsAction as it
|
||||
// won't force the reload of all calendars and automatically redirect the
|
||||
// user to the /SOGo/so page upon completion.
|
||||
//
|
||||
// This is particularly useful for WebAuth users and they won't have a
|
||||
// precise "entry point" in SOGo - so calendars reload upon login
|
||||
// isn't possible for them.
|
||||
//
|
||||
- (WOResponse *) reloadWebCalendarsAndRedirectAction
|
||||
{
|
||||
[[self clientObject] reloadWebCalendars: NO];
|
||||
|
||||
return [self redirectToLocation: @"/SOGo/so"];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Перевантажити віддалені календарі";
|
||||
"Properties" = "Властивості";
|
||||
"Done" = "Зроблено";
|
||||
"An error occured while importing calendar." = "Виникла помилка під час імпорту календаря.";
|
||||
"An error occurred while importing calendar." = "Виникла помилка під час імпорту календаря.";
|
||||
"No event was imported." = "Жодну подію не було імпортовано.";
|
||||
"A total of %{0} events were imported in the calendar." = "Разом %{0} подій було імпортовано в цьому календарі.";
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"Reload Remote Calendars" = "Ail-lwytho Calendrau Anghysbell";
|
||||
"Properties" = "Dewisiadau";
|
||||
"Done" = "Done";
|
||||
"An error occured while importing calendar." = "An error occured while importing calendar.";
|
||||
"An error occurred while importing calendar." = "An error occurred while importing calendar.";
|
||||
"No event was imported." = "No event was imported.";
|
||||
"A total of %{0} events were imported in the calendar." = "A total of %{0} events were imported in the calendar.";
|
||||
|
||||
|
||||
+15
-10
@@ -45,16 +45,6 @@
|
||||
actionClass = "UIxCalMainActions";
|
||||
actionName = "addWebCalendar";
|
||||
};
|
||||
reloadWebCalendars = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxCalMainActions";
|
||||
actionName = "reloadWebCalendars";
|
||||
};
|
||||
reloadWebCalendarsAndRedirect = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxCalMainActions";
|
||||
actionName = "reloadWebCalendarsAndRedirect";
|
||||
};
|
||||
saveDragHandleState = {
|
||||
protectedBy = "View";
|
||||
pageName = "UIxCalMainView";
|
||||
@@ -181,6 +171,21 @@
|
||||
};
|
||||
};
|
||||
|
||||
SOGoWebAppointmentFolder = {
|
||||
methods = {
|
||||
reload = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxCalFolderActions";
|
||||
actionName = "reload";
|
||||
};
|
||||
"set-credentials" = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxCalFolderActions";
|
||||
actionName = "setCredentials";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
SOGoAppointmentFolderICS = {
|
||||
methods = {
|
||||
export = {
|
||||
|
||||
@@ -1203,25 +1203,180 @@ function onMonthOverview() {
|
||||
return _ensureView("monthview");
|
||||
}
|
||||
|
||||
function onCalendarReload() {
|
||||
function refreshEventsAndTasks() {
|
||||
refreshEvents();
|
||||
refreshTasks();
|
||||
reloadWebCalendars();
|
||||
}
|
||||
|
||||
function onCalendarReload() {
|
||||
if (!reloadWebCalendars()) {
|
||||
refreshEventsAndTasks();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function reloadWebCalendars() {
|
||||
var url = ApplicationBaseURL + "reloadWebCalendars";
|
||||
if (document.reloadWebCalAjaxRequest) {
|
||||
document.reloadWebCalAjaxRequest.aborted = true;
|
||||
document.reloadWebCalAjaxRequest.abort();
|
||||
log("* reloadWebCalendars");
|
||||
var hasWebCalendars = false;
|
||||
|
||||
var remaining = [];
|
||||
var refreshOperations = { "remaining": remaining };
|
||||
if (UserSettings['Calendar']
|
||||
&& UserSettings['Calendar']['WebCalendars']) {
|
||||
var webCalendars = UserSettings['Calendar']['WebCalendars'];
|
||||
|
||||
var folders = $("calendarList");
|
||||
var calendarNodes = folders.childNodesWithTag("li");
|
||||
for (var i = 0; i < calendarNodes.length; i++) {
|
||||
var current = calendarNodes[i];
|
||||
var calendarID = current.getAttribute("id");
|
||||
var owner = current.getAttribute("owner");
|
||||
var realID = owner + ":Calendar/" + calendarID.substr(1);
|
||||
if (webCalendars[realID]) { /* is web calendar ? */
|
||||
remaining.push(realID);
|
||||
reloadWebCalendar(realID, refreshOperations);
|
||||
}
|
||||
}
|
||||
}
|
||||
document.reloadWebCalAjaxRequest
|
||||
= triggerAjaxRequest(url, reloadWebCalendarsCallback);
|
||||
|
||||
return (remaining.length > 0);
|
||||
}
|
||||
|
||||
function reloadWebCalendarsCallback (http) {
|
||||
changeCalendarDisplay(null, currentView);
|
||||
var calendarReloadErrors = { "invalid-calendar-content":
|
||||
_("the returned content was not valid calendar"
|
||||
+ " data"),
|
||||
"http-error": _("an unknown http error occurred"
|
||||
+ " during the load operation"),
|
||||
"bad-url": _("the url in use is invalid or the"
|
||||
+ " host is currently unreachable"),
|
||||
"invalid-url": _("the url being used is invalid"
|
||||
+ " or not handled") };
|
||||
|
||||
function reloadWebCalendar(folderID, refreshOperations) {
|
||||
var url = URLForFolderID(folderID) + "/reload";
|
||||
var cbData = { "folderID": folderID };
|
||||
if (refreshOperations) {
|
||||
cbData["refreshOperations"] = refreshOperations;
|
||||
}
|
||||
triggerAjaxRequest(url, reloadWebCalendarCallback, cbData);
|
||||
}
|
||||
|
||||
function reloadWebCalendarCallback(http) {
|
||||
var cbData = http.callbackData;
|
||||
if (http.status == 200) {
|
||||
var result = http.responseText.evalJSON(true);
|
||||
var requireAuth = false;
|
||||
var success = false;
|
||||
if (result.status) {
|
||||
if (result.status == 401) {
|
||||
requireAuth = true;
|
||||
}
|
||||
else {
|
||||
if (result.status == 200) {
|
||||
success = true;
|
||||
}
|
||||
else {
|
||||
var errorMessage = _("An error occurred while importing calendar.");
|
||||
if (result["error"]) {
|
||||
var message = calendarReloadErrors[result["error"]];
|
||||
errorMessage = (_("An error occurred while loading remote"
|
||||
+ " calendar: %{0}.").formatted(message));
|
||||
}
|
||||
showAlertDialog (errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
var errorMessage = _("An error occurred while importing calendar.");
|
||||
if (result["error"]) {
|
||||
var message = calendarReloadErrors[result["error"]];
|
||||
errorMessage = (_("An error occurred while loading remote"
|
||||
+ " calendar: %{0}.").formatted(message));
|
||||
}
|
||||
showAlertDialog (errorMessage);
|
||||
}
|
||||
|
||||
if (requireAuth) {
|
||||
reauthenticateWebCalendar(cbData["folderID"], cbData);
|
||||
}
|
||||
else {
|
||||
var refreshOperations = cbData["refreshOperations"];
|
||||
if (refreshOperations) {
|
||||
var remaining = refreshOperations["remaining"];
|
||||
var calIdx = remaining.indexOf(cbData["folderID"]);
|
||||
remaining.splice(calIdx, 1);
|
||||
if (remaining.length == 0) {
|
||||
refreshEventsAndTasks();
|
||||
changeCalendarDisplay(null, currentView);
|
||||
}
|
||||
else {
|
||||
var newFolderID = remaining[0];
|
||||
reloadWebCalendar(newFolderID, refreshOperations);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (success) {
|
||||
refreshEventsAndTasks();
|
||||
changeCalendarDisplay(null, currentView);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
showAlertDialog(_("An error occurred while importing calendar."));
|
||||
var refreshOperations = cbData["refreshOperations"];
|
||||
if (refreshOperations) {
|
||||
var remaining = refreshOperations["remaining"];
|
||||
var calIdx = remaining.indexOf(cbData["folderID"]);
|
||||
remaining.splice(calIdx, 1);
|
||||
if (remaining.length > 0) {
|
||||
var newFolderID = remaining[0];
|
||||
reloadWebCalendar(newFolderID, refreshOperations);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function reauthenticateWebCalendar(folderID, refreshCBData) {
|
||||
var remoteURL = null;
|
||||
if (UserSettings['Calendar'] && UserSettings['Calendar']['WebCalendars']) {
|
||||
var webCalendars = UserSettings['Calendar']['WebCalendars'];
|
||||
remoteURL = webCalendars[folderID];
|
||||
}
|
||||
var parts = remoteURL.split("/");
|
||||
var hostname = parts[2];
|
||||
function authenticate(username, password) {
|
||||
disposeDialog();
|
||||
var url = URLForFolderID(folderID) + "/set-credentials";
|
||||
var parameters = ("username=" + encodeURIComponent(username)
|
||||
+ "&password=" + encodeURIComponent(password));
|
||||
triggerAjaxRequest(url, authenticateWebCalendarCallback, refreshCBData, parameters,
|
||||
{ "Content-type": "application/x-www-form-urlencoded" });
|
||||
}
|
||||
showAuthenticationDialog(_("Please identify yourself to \"%{0}\"...")
|
||||
.formatted(hostname),
|
||||
authenticate);
|
||||
}
|
||||
|
||||
function authenticateWebCalendarCallback(http) {
|
||||
var cbData = http.callbackData;
|
||||
var folderID = cbData["folderID"];
|
||||
var refreshOperations = cbData["refreshOperations"];
|
||||
if (isHttpStatus204(http.status)) {
|
||||
reloadWebCalendar(folderID, refreshOperations);
|
||||
}
|
||||
else {
|
||||
if (refreshOperations) {
|
||||
var remaining = refreshOperations["remaining"];
|
||||
var calIdx = remaining.indexOf(folderID);
|
||||
remaining.splice(calIdx, 1);
|
||||
if (remaining.length > 0) {
|
||||
var newFolderID = remaining[0];
|
||||
reloadWebCalendar(newFolderID, refreshOperations);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function scrollDayView(scrollEvent) {
|
||||
@@ -2420,7 +2575,7 @@ function onMenuSharing(event) {
|
||||
var folders = $("calendarList");
|
||||
var selected = folders.getSelectedNodes()[0];
|
||||
/* FIXME: activation of the context menu should preferably select the entry
|
||||
above which the event has occured */
|
||||
above which the event has occurred */
|
||||
if (selected) {
|
||||
var folderID = selected.getAttribute("id");
|
||||
var urlstr = URLForFolderID(folderID) + "/acls";
|
||||
@@ -2473,14 +2628,14 @@ function initCalendarSelector() {
|
||||
var items = list.childNodesWithTag("li");
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var input = items[i].childNodesWithTag("input")[0];
|
||||
$(input).observe("click", updateCalendarStatus);
|
||||
$(input).observe("click", clickEventWrapper(updateCalendarStatus));
|
||||
}
|
||||
|
||||
var links = $("calendarSelectorButtons").childNodesWithTag("a");
|
||||
$(links[0]).observe("click", onCalendarNew);
|
||||
$(links[1]).observe("click", onCalendarWebAdd);
|
||||
$(links[2]).observe("click", onCalendarAdd);
|
||||
$(links[3]).observe("click", onCalendarRemove);
|
||||
$(links[0]).observe("click", clickEventWrapper(onCalendarNew));
|
||||
$(links[1]).observe("click", clickEventWrapper(onCalendarWebAdd));
|
||||
$(links[2]).observe("click", clickEventWrapper(onCalendarAdd));
|
||||
$(links[3]).observe("click", clickEventWrapper(onCalendarRemove));
|
||||
}
|
||||
|
||||
function onCalendarSelectionChange(event) {
|
||||
@@ -2567,29 +2722,51 @@ function onCalendarWebAdd(event) {
|
||||
}
|
||||
|
||||
function onCalendarWebAddConfirm() {
|
||||
disposeDialog();
|
||||
var calendarUrl = this.value;
|
||||
if (calendarUrl) {
|
||||
if (document.addWebCalendarRequest) {
|
||||
document.addWebCalendarRequest.aborted = true;
|
||||
document.addWebCalendarRequest.abort ();
|
||||
}
|
||||
var url = ApplicationBaseURL + "/addWebCalendar?url=" + escape (calendarUrl);
|
||||
document.addWebCalendarRequest =
|
||||
triggerAjaxRequest (url, addWebCalendarCallback);
|
||||
var url = ApplicationBaseURL + "/addWebCalendar"
|
||||
var parameters = "url=" + calendarUrl;
|
||||
triggerAjaxRequest(url, addWebCalendarCallback, calendarUrl, parameters,
|
||||
{ "Content-type": "application/x-www-form-urlencoded" });
|
||||
}
|
||||
disposeDialog();
|
||||
}
|
||||
function addWebCalendarCallback (http) {
|
||||
var data = http.responseText.evalJSON(true);
|
||||
if (data.imported >= 0) {
|
||||
appendCalendar(data.displayname, "/" + data.name);
|
||||
refreshEvents();
|
||||
refreshTasks();
|
||||
changeCalendarDisplay();
|
||||
|
||||
function addWebCalendarCallback(http) {
|
||||
if (http.status == 200) {
|
||||
var data = http.responseText.evalJSON(true);
|
||||
if (!data || data["error"] || !data["name"] || !data["folderID"]) {
|
||||
showAlertDialog (_("An error occurred while importing calendar."));
|
||||
}
|
||||
else {
|
||||
if (UserSettings['Calendar']) {
|
||||
var webCalendars = UserSettings['Calendar']['WebCalendars'];
|
||||
if (!webCalendars) {
|
||||
webCalendars = {};
|
||||
UserSettings['Calendar']['WebCalendars'] = webCalendars;
|
||||
}
|
||||
webCalendars[data["folderID"]] = http.callbackData;
|
||||
}
|
||||
|
||||
appendCalendar(data["name"], data["folderID"]);
|
||||
reloadWebCalendar(data["folderID"]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
showAlertDialog (_("An error occured while importing calendar."));
|
||||
showAlertDialog (_("An error occurred while importing calendar."));
|
||||
}
|
||||
|
||||
// if (data.imported) {
|
||||
// appendCalendar(data.displayname, "/" + data.name);
|
||||
// refreshEvents();
|
||||
// refreshTasks();
|
||||
// changeCalendarDisplay();
|
||||
// }
|
||||
// else if (data.status && data.status == 401) {
|
||||
// reauthenticateWebCalendar(data.name, data.url);
|
||||
// }
|
||||
// else {
|
||||
// }
|
||||
}
|
||||
|
||||
function onCalendarExport(event) {
|
||||
@@ -2637,7 +2814,7 @@ function uploadCompleted(response) {
|
||||
|
||||
var div = $("uploadResults");
|
||||
if (data.imported < 0)
|
||||
$("uploadResultsContent").update(_("An error occured while importing calendar."));
|
||||
$("uploadResultsContent").update(_("An error occurred while importing calendar."));
|
||||
else if (data.imported == 0)
|
||||
$("uploadResultsContent").update(_("No event was imported."));
|
||||
else {
|
||||
@@ -2699,7 +2876,7 @@ function appendCalendar(folderName, folderPath) {
|
||||
li.getElementsByTagName("input")[0].checked = true;
|
||||
|
||||
// Register event on checkbox
|
||||
$(checkBox).on("click", updateCalendarStatus);
|
||||
$(checkBox).on("click", clickEventWrapper(updateCalendarStatus));
|
||||
|
||||
var url = URLForFolderID(folderPath) + "/canAccessContent";
|
||||
triggerAjaxRequest(url, calendarEntryCallback, folderPath);
|
||||
|
||||
@@ -47,6 +47,15 @@ var removeFolderRequestCount = 0;
|
||||
// Email validation regexp
|
||||
var emailRE = /^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i;
|
||||
|
||||
function clickEventWrapper(functionRef) {
|
||||
function button_clickEventWrapper(event) {
|
||||
preventDefault(event);
|
||||
return functionRef(event);
|
||||
}
|
||||
|
||||
return button_clickEventWrapper;
|
||||
}
|
||||
|
||||
|
||||
function createElement(tagName, id, classes,
|
||||
attributes, htmlAttributes,
|
||||
@@ -1257,11 +1266,18 @@ function accessToSubscribedFolder(serverFolder) {
|
||||
|
||||
var parts = serverFolder.split(":");
|
||||
if (parts.length > 1) {
|
||||
var username = parts[0];
|
||||
var paths = parts[1].split("/");
|
||||
folder = "/" + parts[0].asCSSIdentifier() + "_" + paths[2];
|
||||
if (username == UserLogin) {
|
||||
folder = paths[1];
|
||||
}
|
||||
else {
|
||||
folder = "/" + username.asCSSIdentifier() + "_" + paths[1];
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
folder = serverFolder;
|
||||
}
|
||||
|
||||
return folder;
|
||||
}
|
||||
@@ -1927,8 +1943,9 @@ function createButton(id, caption, action) {
|
||||
var span = createElement("span", null, null, null, null, newButton);
|
||||
span.appendChild(document.createTextNode(caption));
|
||||
}
|
||||
if (action)
|
||||
newButton.on("click", action);
|
||||
if (action) {
|
||||
newButton.on("click", clickEventWrapper(action));
|
||||
}
|
||||
|
||||
return newButton;
|
||||
}
|
||||
@@ -2086,6 +2103,53 @@ function _showSelectDialog(title, label, options, button, callbackFcn, callbackA
|
||||
dialog.appear({ duration: 0.2 });
|
||||
}
|
||||
|
||||
function showAuthenticationDialog(label, callback) {
|
||||
log("* showAuthenticationDialog");
|
||||
log(backtrace());
|
||||
|
||||
var div = $("bgDialogDiv");
|
||||
if (div && div.visible() && div.getOpacity() > 0) {
|
||||
log("push");
|
||||
dialogsStack.push(_showAuthenticationDialog.bind(this, label, callback));
|
||||
}
|
||||
else {
|
||||
log("show");
|
||||
_showAuthenticationDialog(label, callback);
|
||||
}
|
||||
}
|
||||
|
||||
function _showAuthenticationDialog(label, callback) {
|
||||
var dialog = dialogs[label];
|
||||
if (dialog) {
|
||||
$("bgDialogDiv").show();
|
||||
var inputs = dialog.getElementsByTagName("input");
|
||||
for (var i = 0; i < inputs.length; i++) {
|
||||
inputs[i].value = "";
|
||||
}
|
||||
}
|
||||
else {
|
||||
var fields = createElement("p", null, ["prompt"]);
|
||||
fields.appendChild(document.createTextNode(_("Username:")));
|
||||
var un_input = createElement("input", null, "textField",
|
||||
{ type: "text", "value": "" });
|
||||
fields.appendChild(un_input);
|
||||
fields.appendChild(document.createTextNode(_("Password:")));
|
||||
var pw_input = createElement("input", null, "textField",
|
||||
{ type: "password", "value": "" });
|
||||
fields.appendChild(pw_input);
|
||||
function callbackWrapper() {
|
||||
callback(un_input.value, pw_input.value);
|
||||
}
|
||||
fields.appendChild(createButton(null, _("OK"), callbackWrapper));
|
||||
fields.appendChild(createButton(null, _("Cancel"), disposeDialog));
|
||||
dialog = createDialog(null, label, null, fields, "none");
|
||||
document.body.appendChild(dialog);
|
||||
dialogs[label] = dialog;
|
||||
}
|
||||
dialog.appear({ duration: 0.2,
|
||||
afterFinish: function () { dialog.down("input").focus(); } });
|
||||
}
|
||||
|
||||
function disposeDialog() {
|
||||
$$("DIV.dialog").each(function(div) {
|
||||
if (div.visible() && div.getOpacity() == 1)
|
||||
|
||||
Reference in New Issue
Block a user