From 109ca5a129b12ad358aa6c90c3aee362abcd0923 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 29 Jun 2009 19:08:29 +0000 Subject: [PATCH 1/3] See ChangeLog Monotone-Parent: ebd8557fae4ef7c0656a9eae753c68207fc9c60b Monotone-Revision: a57ac11c710e04e59d47cf12be270492f600a306 Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2009-06-29T19:08:29 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 13 +++ SoObjects/SOGo/SOGoParentFolder.h | 2 +- SoObjects/SOGo/SOGoParentFolder.m | 124 +++++++++++++++------------- UI/WebServerResources/ContactsUI.js | 14 ++-- 4 files changed, 88 insertions(+), 65 deletions(-) diff --git a/ChangeLog b/ChangeLog index 19b651638..3f721d684 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2009-06-29 Francis Lachapelle + + * SoObjects/SOGo/SOGoParentFolder.m ([SOGoParentFolder + -initSubFolders]): system folders (LDAP sources) are now loaded + unconditionally. + ([SOGoFolderParent -initSubscribedSubFolders]): new method to load + only subscribed folders. + ([SOGoParent -lookupName:inContext:acquire:]): we now properly + lookup in subscribed folders. + ([SOGoParentFolder -subFolders]): since the subscribed folders are + now stored in its own dictionary, we must return keys from both + dictionaries. + 2009-06-26 Francis Lachapelle * UI/Contacts/UIxContactsListViewContainer.[hm]: this class was diff --git a/SoObjects/SOGo/SOGoParentFolder.h b/SoObjects/SOGo/SOGoParentFolder.h index 66a3d9506..270252054 100644 --- a/SoObjects/SOGo/SOGoParentFolder.h +++ b/SoObjects/SOGo/SOGoParentFolder.h @@ -31,7 +31,7 @@ @interface SOGoParentFolder : SOGoFolder { - NSMutableDictionary *subFolders; + NSMutableDictionary *subFolders, *subscribedSubFolders; NSString *OCSPath; Class subFolderClass; BOOL hasSubscribedSources; diff --git a/SoObjects/SOGo/SOGoParentFolder.m b/SoObjects/SOGo/SOGoParentFolder.m index 1e8f7df58..a0e715a52 100644 --- a/SoObjects/SOGo/SOGoParentFolder.m +++ b/SoObjects/SOGo/SOGoParentFolder.m @@ -243,11 +243,6 @@ static SoSecurityManager *sm = nil; return nil; } -- (void) _removeSubscribedSource: (NSString *) key -{ -#warning TO BE IMPLEMENTED SOON FIXME -} - - (void) _appendSubscribedSource: (NSString *) sourceKey { SOGoGCSFolder *subscribedFolder; @@ -257,12 +252,10 @@ static SoSecurityManager *sm = nil; inContainer: self]; if (subscribedFolder && ![sm validatePermission: SOGoPerm_AccessObject - onObject: subscribedFolder - inContext: context]) - [subFolders setObject: subscribedFolder - forKey: [subscribedFolder nameInContainer]]; - else - [self _removeSubscribedSource: sourceKey]; + onObject: subscribedFolder + inContext: context]) + [subscribedSubFolders setObject: subscribedFolder + forKey: [subscribedFolder nameInContainer]]; } - (NSException *) appendSubscribedSources @@ -336,27 +329,16 @@ static SoSecurityManager *sm = nil; return error; } -- (NSException *) initSubFoldersMatching: (NSString *) folderName +- (NSException *) initSubFolders; { - NSString *login; NSException *error; if (!subFolders) { subFolders = [NSMutableDictionary new]; error = [self appendPersonalSources]; - if (!error - && !(folderName && [subFolders objectForKey: folderName])) - { - error = [self appendSystemSources]; - if (!error - && !(folderName && [subFolders objectForKey: folderName])) - { - login = [[context activeUser] login]; - if ([login isEqualToString: owner]) - error = [self appendSubscribedSources]; - } - } + if (!error) + error = [self appendSystemSources]; if (error) { [subFolders release]; @@ -369,15 +351,33 @@ static SoSecurityManager *sm = nil; return error; } -// - (void) _appendSubscribedSourcesIfNeeded -// { -// NSString *login; +- (NSException *) initSubscribedSubFolders +{ + NSArray *subscribedReferences; + NSUserDefaults *settings; + NSEnumerator *allKeys; + NSString *currentKey, *login; + NSException *error; -// login = [[context activeUser] login]; -// if ([login isEqualToString: owner]) -// [self appendSubscribedSources]; -// hasSubscribedSources = YES; -// } + error = nil; /* we ignore non-DB errors at this time... */ + login = [[context activeUser] login]; + + if (!subscribedSubFolders && [login isEqualToString: owner]) + { + subscribedSubFolders = [NSMutableDictionary new]; + settings = [[context activeUser] userSettings]; + subscribedReferences = [[settings objectForKey: nameInContainer] + objectForKey: @"SubscribedFolders"]; + if ([subscribedReferences isKindOfClass: [NSArray class]]) + { + allKeys = [subscribedReferences objectEnumerator]; + while ((currentKey = [allKeys nextObject])) + [self _appendSubscribedSource: currentKey]; + } + } + + return error; +} - (NSArray *) fetchContentObjectNames { @@ -395,11 +395,8 @@ static SoSecurityManager *sm = nil; obj = [super lookupName: name inContext: lookupContext acquire: NO]; if (!obj) { - if (!subFolders) - error = [self initSubFoldersMatching: name]; - else - error = nil; - + // Lookup in personal folders + error = [self initSubFolders]; if (error) { [self errorWithFormat: @"a database error occured: %@", [error reason]]; @@ -407,37 +404,48 @@ static SoSecurityManager *sm = nil; } else obj = [subFolders objectForKey: name]; -// if (!obj && !hasSubscribedSources) -// { -// [self _appendSubscribedSourcesIfNeeded]; -// obj = [subFolders objectForKey: name]; -// } + + if (!obj) + { + // Lookup in subscribed folders + error = [self initSubscribedSubFolders]; + if (error) + { + [self errorWithFormat: @"a database error occured: %@", [error reason]]; + obj = [NSException exceptionWithHTTPStatus: 503]; + } + else + obj = [subscribedSubFolders objectForKey: name]; + } } - + return obj; } - (NSArray *) subFolders { + NSMutableArray *ma; NSException *error; - if (!subFolders) + error = [self initSubFolders]; + if (error) { - error = [self initSubFoldersMatching: nil]; - if (error) - { - /* We exceptionnally raise the exception here because doPROPFIND: - will not care for errors in its response from - toManyRelationShipKeys, which may in turn trigger the - disappearance of user folders in the SOGo extensions. */ - [error raise]; - } + /* We exceptionnally raise the exception here because doPROPFIND: + will not care for errors in its response from + toManyRelationShipKeys, which may in turn trigger the + disappearance of user folders in the SOGo extensions. */ + [error raise]; } -// if (!!hasSubscribedSources) -// [self _appendSubscribedSourcesIfNeeded]; + + error = [self initSubscribedSubFolders]; + if (error) + [error raise]; - return [[subFolders allValues] - sortedArrayUsingSelector: @selector (compare:)]; + ma = [NSMutableArray arrayWithArray: [subFolders allValues]]; + if ([subscribedSubFolders count]) + [ma addObjectsFromArray: [subscribedSubFolders allValues]]; + + return [ma sortedArrayUsingSelector: @selector (compare:)]; } - (NSArray *) toManyRelationshipKeys diff --git a/UI/WebServerResources/ContactsUI.js b/UI/WebServerResources/ContactsUI.js index 896453b97..d99b2ef85 100644 --- a/UI/WebServerResources/ContactsUI.js +++ b/UI/WebServerResources/ContactsUI.js @@ -251,7 +251,7 @@ function actionContactCallback(http) { var error = html.select("p").first().firstChild.nodeValue.trim(); log("actionContactCallback failed: error " + http.status + " (" + error + ")"); if (parseInt(http.status) == 403) - window.alert(labels["You don't have the required privileges to perform the operation."]); + window.alert(clabels["You don't have the required privileges to perform the operation."]); else if (error) window.alert(labels[error]); refreshCurrentFolder(); @@ -775,6 +775,8 @@ function onAddressBookMenuPrepareVisibility() { menuEntry.removeClassName("disabled"); }); } + + return true; } function updateAddressBooksMenus() { @@ -897,8 +899,7 @@ function onAddressBooksMenuPrepareVisibility() { sharingOption.addClassName("disabled"); } - // disable the "remove" option when address book is public, otherwise - // enable it + // Disable the "remove" option when address book is public if (folderOwner == "nobody") removeOption.addClassName("disabled"); else @@ -912,7 +913,7 @@ function onAddressBooksMenuPrepareVisibility() { function onContactMenuPrepareVisibility() { var contactRows = document.menuTarget; - var selectedFolder = $("contactFolders").getSelectedNodes()[0]; + var selectedFolder = $("contactFolders").getSelectedNodes().first(); var options = { write: false, aim: false }; @@ -923,9 +924,10 @@ function onContactMenuPrepareVisibility() { var moveOption = elements[7]; $A(contactRows).each(function(contactRow) { - var emailCell = contactRow.down('td', 1); + var cells = contactRow.getElementsByTagName('td'); + var emailCell = cells[1]; options.write |= (emailCell.firstChild != null); - var aimCell = contactRow.down('td', 2); + var aimCell = cells[2]; options.aim |= (aimCell.firstChild != null); }); From deda9f6511077dc401044c4545338d4996b874a4 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Tue, 30 Jun 2009 01:39:27 +0000 Subject: [PATCH 2/3] Monotone-Parent: f8f29401b79be9d6545414948b83cb353a55ae8d Monotone-Revision: 6b27e776287f9677560ff81cbb45e7471959c9e0 Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2009-06-30T01:39:27 Monotone-Branch: ca.inverse.sogo --- UI/WebServerResources/SchedulerUI.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/WebServerResources/SchedulerUI.js b/UI/WebServerResources/SchedulerUI.js index e64b205b6..11034c3c2 100644 --- a/UI/WebServerResources/SchedulerUI.js +++ b/UI/WebServerResources/SchedulerUI.js @@ -390,7 +390,7 @@ function onViewEventCallback(http) { div.down("P", 1).hide(); if (data["description"].length) { - div.down("P", 2).update(data["description"]); + div.down("P", 2).update(data["description"].replace(/\r\n/g, "
")); div.down("P", 2).show(); } else div.down("P", 2).hide(); From 6209543ce046a76a170e7934d4283bf06862a703 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Tue, 30 Jun 2009 01:41:27 +0000 Subject: [PATCH 3/3] Fix component editor for document URL Monotone-Parent: 6b27e776287f9677560ff81cbb45e7471959c9e0 Monotone-Revision: eca223304213a13e4a7b9e29e6e5cc41c3b1cdb3 Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2009-06-30T01:41:27 Monotone-Branch: ca.inverse.sogo --- .../UIxAppointmentEditor.css | 15 ++-------- UI/WebServerResources/UIxComponentEditor.css | 29 +++++++++++++++++++ UI/WebServerResources/UIxComponentEditor.js | 22 ++++++++++++++ UI/WebServerResources/UIxTaskEditor.css | 5 +--- 4 files changed, 55 insertions(+), 16 deletions(-) diff --git a/UI/WebServerResources/UIxAppointmentEditor.css b/UI/WebServerResources/UIxAppointmentEditor.css index 0c30a9d69..e5551acf7 100644 --- a/UI/WebServerResources/UIxAppointmentEditor.css +++ b/UI/WebServerResources/UIxAppointmentEditor.css @@ -54,19 +54,10 @@ SELECT { margin-left: 1px; } LABEL#commentArea -{ height: 15em; } +{ height: 17em; } LABEL#commentArea textarea -{ padding-bottom: 0em; - top: 0px; - left: 8em; - width: 380px; - height: 15em; - vertical-align: bottom; - position: absolute; - padding: 0px; - margin: 0px; - margin-left: 1px; } +{ height: 15.5em; } SPAN.checkBoxList#participantsCB { height: 7em; } @@ -80,7 +71,7 @@ DIV#participants UL.contactList SPAN.checkBoxList SPAN.content LABEL { display: inline; } -SPAN.content +n0SPAN.content { position: absolute; line-height: 2em; top: -.25em; diff --git a/UI/WebServerResources/UIxComponentEditor.css b/UI/WebServerResources/UIxComponentEditor.css index 18402899c..d7706711d 100644 --- a/UI/WebServerResources/UIxComponentEditor.css +++ b/UI/WebServerResources/UIxComponentEditor.css @@ -9,3 +9,32 @@ SPAN.datePicker INPUT.textField SPAN.timeDateControl A.button { border: 0; } + +SPAN.content +{ position: absolute; + line-height: 2em; + top: -.25em; + left: 8em; + right: 1em; } + +SPAN.content > INPUT.textField, +LABEL#commentArea textarea +{ width: 380px; } + +LABEL, SPAN.checkBoxList +{ display: block; + position: relative; + line-height: 1.5em; + height: 1.5em; + margin-left: 0px; + margin-bottom: .5em; + width: 100%; } + +LABEL#commentArea textarea +{ padding-bottom: 0em; + top: 0px; + left: 8em; + position: absolute; + padding: 0px; + margin: 0px; + margin-left: 1px; } diff --git a/UI/WebServerResources/UIxComponentEditor.js b/UI/WebServerResources/UIxComponentEditor.js index 768ec3456..a92c785c3 100644 --- a/UI/WebServerResources/UIxComponentEditor.js +++ b/UI/WebServerResources/UIxComponentEditor.js @@ -43,6 +43,7 @@ function onPopupUrlWindow(event) { } urlInput.value = newUrl; } + onWindowResize(event); return false; } @@ -134,10 +135,31 @@ function onComponentEditorLoad(event) { $("repeatList").observe("change", onPopupRecurrenceWindow); $("reminderHref").observe("click", onPopupReminderWindow); $("reminderList").observe("change", onPopupReminderWindow); + + Event.observe(window, "resize", onWindowResize); + onPopupRecurrenceWindow(null); onPopupReminderWindow(null); } +function onWindowResize(event) { + var document = $("documentLabel"); + var comment = $("commentArea"); + var area = comment.select("textarea").first(); + var offset = 6; + var height; + + height = window.height() - comment.cumulativeOffset().top - offset; + + if (document.visible()) + height -= $("changeUrlButton").getHeight(); + + area.setStyle({ height: (height - offset*2) + "px" }); + comment.setStyle({ height: (height - offset) + "px" }); + + return true; +} + function onPopupRecurrenceWindow(event) { if (event) preventDefault(event); diff --git a/UI/WebServerResources/UIxTaskEditor.css b/UI/WebServerResources/UIxTaskEditor.css index afa7cb9a6..8ae836752 100644 --- a/UI/WebServerResources/UIxTaskEditor.css +++ b/UI/WebServerResources/UIxTaskEditor.css @@ -25,10 +25,7 @@ LABEL#commentArea { height: 15em; } LABEL#commentArea textarea -{ padding: 0; - margin: 0; - width: 380px; - height: 15em; } +{ height: 15em; } SPAN.checkBoxList#participantsCB { height: 7em; }