Monotone-Parent: df2b66af0afb7884e01b50efd6f7e99acf0743fa

Monotone-Revision: 1804bb2fc333899fed4fa062ac489b8006f6b8a4

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2007-11-19T21:07:54
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau
2007-11-19 21:07:54 +00:00
parent aec172d1fe
commit c1e1b16f0a
9 changed files with 257 additions and 144 deletions

View File

@@ -1,5 +1,18 @@
2007-11-19 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/Scheduler/UIxComponentEditor.m ([UIxComponentEditor
-setComponent:newComponent]): retain the component object.
([UIxComponentEditor -organizerIdentity]): new accessor method to
handle list of possible organizers.
* UI/Scheduler/UIxAppointmentEditor.m ([UIxAppointmentEditor
-event]): retain the returned event object.
* SoObjects/Appointments/SOGoAppointmentObject.m
([SOGoAppointmentObject -saveComponent:newEvent]): reset the
organizer only if there are no attendees AND the owner of the
component is not the organizer him-/herself.
* UI/Scheduler/UIxComponentEditor.m ([UIxComponentEditor
-toolbar]): rewrote in a way that ensures that each case is
handled properly.

View File

@@ -230,9 +230,11 @@
{
iCalEvent *oldEvent;
NSArray *attendees;
SOGoUser *currentUser;
[[newEvent parent] setMethod: @""];
if ([newEvent userIsOrganizer: [context activeUser]])
currentUser = [context activeUser];
if ([newEvent userIsOrganizer: currentUser])
{
oldEvent = [self component: NO secure: NO];
if (oldEvent)
@@ -249,7 +251,9 @@
toAttendees: attendees];
}
if (![[newEvent attendees] count])
if (![[newEvent attendees] count]
&& [[self ownerInContext: context]
isEqualToString: [currentUser login]])
[[newEvent uniqueChildWithTag: @"organizer"] setValue: 0
to: @""];
}

View File

@@ -69,6 +69,12 @@
/* template values */
- (iCalEvent *) event
{
if (!event)
{
event = (iCalEvent *) [[self clientObject] component: NO secure: NO];
[event retain];
}
return event;
}

View File

@@ -41,6 +41,8 @@
NSString *saveURL;
NSMutableArray *calendarList;
NSMutableArray *organizerList;
NSDictionary *organizerIdentity;
/* individual values */
NSCalendarDate *cycleUntilDate;
@@ -69,6 +71,9 @@
- (void) setSaveURL: (NSString *) newSaveURL;
- (NSString *) saveURL;
- (void) setItem: (id) _item;
- (id) item;
- (NSArray *) categoryList;
- (void) setCategories: (NSArray *) _categories;
- (NSArray *) categories;
@@ -89,16 +94,14 @@
- (NSString *) status;
- (NSString *) itemStatusText;
- (void) setItem: (id) _item;
- (id) item;
- (NSString *) itemPriorityText;
- (void) setTitle: (NSString *) _value;
- (NSString *) title;
- (void) setLocation: (NSString *) _value;
- (NSString *) location;
- (NSString *) location;
- (void) setComment: (NSString *) _value;
- (NSString *) comment;

View File

@@ -49,6 +49,7 @@
#import <SoObjects/Appointments/SOGoTaskObject.h>
#import <SoObjects/SOGo/iCalEntityObject+Utilities.h>
#import <SoObjects/SOGo/LDAPUserManager.h>
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
#import <SoObjects/SOGo/NSString+Utilities.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/SOGoPermissions.h>
@@ -68,6 +69,7 @@
[self setIsCycleEndNever];
componentOwner = @"";
organizer = nil;
organizerIdentity = nil;
attendeesNames = nil;
attendeesUIDs = nil;
attendeesEmails = nil;
@@ -84,6 +86,7 @@
[title release];
[location release];
[organizer release];
[organizerIdentity release];
[comment release];
[priority release];
[categories release];
@@ -95,6 +98,8 @@
[attendeesEmails release];
[calendarList release];
[component release];
[super dealloc];
}
@@ -160,7 +165,7 @@
if (!component)
{
component = newComponent;
ASSIGN (component, newComponent);
co = [self clientObject];
componentOwner = [co ownerInContext: nil];
@@ -248,16 +253,75 @@
return url;
}
- (BOOL) hasOrganizer
{
return (![organizer isVoid]);
}
- (NSString *) organizerName
{
return [organizer mailAddress];
}
- (BOOL) canBeOrganizer
{
NSString *owner;
SOGoCalendarComponent *co;
SOGoUser *currentUser;
BOOL hasOrganizer;
co = [self clientObject];
owner = [co ownerInContext: context];
currentUser = [context activeUser];
hasOrganizer = ([[organizer value: 0] length] > 0);
return ([co isNew]
|| ([owner isEqualToString: [currentUser login]]
&& (!hasOrganizer || [component userIsOrganizer: currentUser])));
}
- (BOOL) hasOrganizer
{
return ([[organizer value: 0] length] && ![self canBeOrganizer]);
}
- (void) setOrganizerIdentity: (NSDictionary *) newOrganizerIdentity
{
ASSIGN (organizerIdentity, newOrganizerIdentity);
}
- (NSDictionary *) organizerIdentity
{
NSArray *allIdentities;
NSEnumerator *identities;
NSDictionary *currentIdentity;
NSString *orgEmail;
orgEmail = [organizer rfc822Email];
if (!organizerIdentity)
{
if ([orgEmail length])
{
allIdentities = [[context activeUser] allIdentities];
identities = [allIdentities objectEnumerator];
while (!organizerIdentity
&& ((currentIdentity = [identities nextObject])))
if ([[currentIdentity objectForKey: @"email"]
caseInsensitiveCompare: orgEmail]
== NSOrderedSame)
ASSIGN (organizerIdentity, currentIdentity);
}
}
return organizerIdentity;
}
- (NSArray *) organizerList
{
return [[context activeUser] allIdentities];
}
- (NSString *) itemOrganizerText
{
return [item keysWithFormat: @"%{fullName} <%{email}>"];
}
- (void) setAttendeesNames: (NSString *) newAttendeesNames
{
ASSIGN (attendeesNames, newAttendeesNames);
@@ -852,19 +916,19 @@
- (void) _handleOrganizer
{
NSString *organizerEmail;
SOGoUser *activeUser;
NSDictionary *primaryIdentity;
NSString *owner, *login;
organizerEmail = [[component organizer] email];
if ([organizerEmail length] == 0)
{
if ([[component attendees] count] > 0)
owner = [[self clientObject] ownerInContext: context];
login = [[context activeUser] login];
if (![owner isEqualToString: login]
|| [[component attendees] count] > 0)
{
ASSIGN (organizer, [iCalPerson elementWithTag: @"organizer"]);
activeUser = [context activeUser];
primaryIdentity = [activeUser primaryIdentity];
[organizer setCn: [activeUser cn]];
[organizer setEmail: [primaryIdentity objectForKey: @"email"]];
[organizer setCn: [organizerIdentity objectForKey: @"fullName"]];
[organizer setEmail: [organizerIdentity objectForKey: @"email"]];
[component setOrganizer: organizer];
}
}
@@ -908,6 +972,7 @@
#warning the following methods probably share some code...
- (NSString *) _toolbarForOwner: (SOGoUser *) ownerUser
andClientObject: (SOGoCalendarComponent *) clientObject
{
NSString *toolbarFilename;
iCalPersonPartStat participationStatus;
@@ -928,7 +993,7 @@
}
else
{
if ([component isKindOfClass: [iCalEvent class]])
if ([clientObject isKindOfClass: [SOGoAppointmentObject class]])
toolbarFilename = @"SOGoAppointmentObject.toolbar";
else
toolbarFilename = @"SOGoTaskObject.toolbar";
@@ -938,15 +1003,13 @@
}
- (NSString *) _toolbarForDelegate: (SOGoUser *) ownerUser
andClientObject: (SOGoCalendarComponent *) clientObject
{
SOGoCalendarComponent *clientObject;
SoSecurityManager *sm;
NSString *toolbarFilename, *adminToolbar;
iCalPersonPartStat participationStatus;
clientObject = [self clientObject];
if ([component isKindOfClass: [iCalEvent class]])
if ([clientObject isKindOfClass: [SOGoAppointmentObject class]])
adminToolbar = @"SOGoAppointmentObject.toolbar";
else
adminToolbar = @"SOGoTaskObject.toolbar";
@@ -1001,9 +1064,11 @@
roles: nil];
if ([ownerUser isEqual: [context activeUser]])
toolbarFilename = [self _toolbarForOwner: ownerUser];
toolbarFilename = [self _toolbarForOwner: ownerUser
andClientObject: clientObject];
else
toolbarFilename = [self _toolbarForDelegate: ownerUser];
toolbarFilename = [self _toolbarForDelegate: ownerUser
andClientObject: clientObject];
return toolbarFilename;

View File

@@ -71,10 +71,12 @@
/* template values */
- (iCalToDo *) todo
{
if (!todo) {
todo = (iCalToDo *) [[self clientObject] component: NO secure: NO];
[todo retain];
}
if (!todo)
{
todo = (iCalToDo *) [[self clientObject] component: NO secure: NO];
[todo retain];
}
return todo;
}

View File

@@ -57,8 +57,15 @@
</span></span>
<var:if condition="hasOrganizer"
><label id="organizerLabel"><var:string label:value="Organizer:"
/><span class="content"><var:string value="organizerName"/></span></label>
/><span class="content"><var:string
value="organizerName"/></span></label>
</var:if>
<var:if condition="canBeOrganizer"
><label id="organizerListLabel"><var:string label:value="Organizer:"
/><span class="content"><var:popup list="organizerList"
item="item" string="itemOrganizerText"
var:selection="organizerIdentity"/>
</span></label></var:if>
<label id="attendeesLabel"><var:string label:value="Attendees:"
/><span class="content"
><a href="#" id="attendeesHref"><!-- space --></a></span></label>

View File

@@ -1,2 +1,5 @@
#attendeesLabel
{ display: none; }
#organizerListLabel
{ display: none; }

View File

@@ -1,160 +1,170 @@
function onPopupAttendeesWindow(event) {
if (event)
preventDefault(event);
window.open(ApplicationBaseURL + "/editAttendees", null,
"width=803,height=573");
if (event)
preventDefault(event);
window.open(ApplicationBaseURL + "/editAttendees", null,
"width=803,height=573");
return false;
return false;
}
function onSelectPrivacy(event) {
if (event.button == 0 || (isSafari() && event.button == 1)) {
var node = getTarget(event);
if (node.tagName != 'BUTTON')
node = $(node).up("button");
popupToolbarMenu(node, "privacy-menu");
Event.stop(event);
// preventDefault(event);
}
if (event.button == 0 || (isSafari() && event.button == 1)) {
var node = getTarget(event);
if (node.tagName != 'BUTTON')
node = $(node).up("button");
popupToolbarMenu(node, "privacy-menu");
Event.stop(event);
// preventDefault(event);
}
}
function onPopupUrlWindow(event) {
if (event)
preventDefault(event);
if (event)
preventDefault(event);
var urlInput = document.getElementById("url");
var newUrl = window.prompt(labels["Target:"], urlInput.value);
if (newUrl != null) {
var documentHref = $("documentHref");
var documentLabel = $("documentLabel");
if (documentHref.childNodes.length > 0) {
documentHref.childNodes[0].nodeValue = newUrl;
if (newUrl.length > 0)
documentLabel.setStyle({ display: "block" });
else
documentLabel.setStyle({ display: "none" });
}
else {
documentHref.appendChild(document.createTextNode(newUrl));
if (newUrl.length > 0)
documentLabel.setStyle({ display: "block" });
}
urlInput.value = newUrl;
}
var urlInput = document.getElementById("url");
var newUrl = window.prompt(labels["Target:"], urlInput.value);
if (newUrl != null) {
var documentHref = $("documentHref");
var documentLabel = $("documentLabel");
if (documentHref.childNodes.length > 0) {
documentHref.childNodes[0].nodeValue = newUrl;
if (newUrl.length > 0)
documentLabel.setStyle({ display: "block" });
else
documentLabel.setStyle({ display: "none" });
}
else {
documentHref.appendChild(document.createTextNode(newUrl));
if (newUrl.length > 0)
documentLabel.setStyle({ display: "block" });
}
urlInput.value = newUrl;
}
return false;
return false;
}
function onPopupDocumentWindow(event) {
var documentUrl = $("url");
var documentUrl = $("url");
preventDefault(event);
window.open(documentUrl.value, "SOGo_Document");
preventDefault(event);
window.open(documentUrl.value, "SOGo_Document");
return false;
return false;
}
function onMenuSetClassification(event) {
event.cancelBubble = true;
event.cancelBubble = true;
var classification = this.getAttribute("classification");
if (this.parentNode.chosenNode)
this.parentNode.chosenNode.removeClassName("_chosen");
this.addClassName("_chosen");
this.parentNode.chosenNode = this;
var classification = this.getAttribute("classification");
if (this.parentNode.chosenNode)
this.parentNode.chosenNode.removeClassName("_chosen");
this.addClassName("_chosen");
this.parentNode.chosenNode = this;
// log("classification: " + classification);
var privacyInput = document.getElementById("privacy");
privacyInput.value = classification;
// log("classification: " + classification);
var privacyInput = document.getElementById("privacy");
privacyInput.value = classification;
}
function onChangeCalendar(event) {
var calendars = $("calendarFoldersList").value.split(",");
var form = document.forms["editform"];
var urlElems = form.getAttribute("action").split("/");
var choice = calendars[this.value];
urlElems[urlElems.length-3] = choice;
form.setAttribute("action", urlElems.join("/"));
var calendars = $("calendarFoldersList").value.split(",");
var form = document.forms["editform"];
var urlElems = form.getAttribute("action").split("/");
var choice = calendars[this.value];
urlElems[urlElems.length-3] = choice;
form.setAttribute("action", urlElems.join("/"));
}
function refreshAttendees() {
var attendeesLabel = $("attendeesLabel");
var attendeesNames = $("attendeesNames");
var attendeesHref = $("attendeesHref");
var attendeesLabel = $("attendeesLabel");
var attendeesNames = $("attendeesNames");
var attendeesHref = $("attendeesHref");
var organizerListLabel = $("organizerListLabel");
for (var i = 0; i < attendeesHref.childNodes.length; i++)
attendeesHref.removeChild(attendeesHref.childNodes[i]);
log ("label: "+ organizerListLabel);
for (var i = 0; i < attendeesHref.childNodes.length; i++)
attendeesHref.removeChild(attendeesHref.childNodes[i]);
if (attendeesNames.value.length > 0) {
attendeesHref.appendChild(document.createTextNode(attendeesNames.value));
attendeesLabel.setStyle({ display: "block" });
}
else
attendeesLabel.setStyle({ display: "none" });
if (attendeesNames.value.length > 0) {
attendeesHref.appendChild(document.createTextNode(attendeesNames.value));
attendeesLabel.setStyle({ display: "block" });
if (organizerListLabel)
organizerListLabel.setStyle({ display: "block" });
}
else {
attendeesLabel.setStyle({ display: "none" });
if (organizerListLabel)
organizerListLabel.setStyle({ display: "none" });
}
}
function initializeAttendeesHref() {
var attendeesHref = $("attendeesHref");
var attendeesLabel = $("attendeesLabel");
var attendeesNames = $("attendeesNames");
var attendeesHref = $("attendeesHref");
var attendeesLabel = $("attendeesLabel");
var attendeesNames = $("attendeesNames");
var organizerListLabel = $("organizerListLabel");
Event.observe(attendeesHref, "click", onPopupAttendeesWindow, false);
if (attendeesNames.value.length > 0) {
attendeesHref.setStyle({ textDecoration: "underline", color: "#00f" });
attendeesHref.appendChild(document.createTextNode(attendeesNames.value));
attendeesLabel.setStyle({ display: "block" });
}
Event.observe(attendeesHref, "click", onPopupAttendeesWindow, false);
if (attendeesNames.value.length > 0) {
if (organizerListLabel)
organizerListLabel.setStyle({ display: "block" });
attendeesHref.setStyle({ textDecoration: "underline", color: "#00f" });
attendeesHref.appendChild(document.createTextNode(attendeesNames.value));
attendeesLabel.setStyle({ display: "block" });
}
}
function initializeDocumentHref() {
var documentHref = $("documentHref");
var documentLabel = $("documentLabel");
var documentUrl = $("url");
var documentHref = $("documentHref");
var documentLabel = $("documentLabel");
var documentUrl = $("url");
Event.observe(documentHref, "click", onPopupDocumentWindow, false);
documentHref.setStyle({ textDecoration: "underline", color: "#00f" });
if (documentUrl.value.length > 0) {
documentHref.appendChild(document.createTextNode(documentUrl.value));
documentLabel.setStyle({ display: "block" });
}
Event.observe(documentHref, "click", onPopupDocumentWindow, false);
documentHref.setStyle({ textDecoration: "underline", color: "#00f" });
if (documentUrl.value.length > 0) {
documentHref.appendChild(document.createTextNode(documentUrl.value));
documentLabel.setStyle({ display: "block" });
}
var changeUrlButton = $("changeUrlButton");
Event.observe(changeUrlButton, "click", onPopupUrlWindow, false);
var changeUrlButton = $("changeUrlButton");
Event.observe(changeUrlButton, "click", onPopupUrlWindow, false);
}
function initializePrivacyMenu() {
var privacy = $("privacy").value.toUpperCase();
if (privacy.length > 0) {
var privacyMenu = $("privacy-menu").childNodesWithTag("ul")[0];
var menuEntries = $(privacyMenu).childNodesWithTag("li");
var chosenNode;
if (privacy == "CONFIDENTIAL")
chosenNode = menuEntries[1];
else if (privacy == "PRIVATE")
chosenNode = menuEntries[2];
else
chosenNode = menuEntries[0];
privacyMenu.chosenNode = chosenNode;
$(chosenNode).addClassName("_chosen");
}
var privacy = $("privacy").value.toUpperCase();
if (privacy.length > 0) {
var privacyMenu = $("privacy-menu").childNodesWithTag("ul")[0];
var menuEntries = $(privacyMenu).childNodesWithTag("li");
var chosenNode;
if (privacy == "CONFIDENTIAL")
chosenNode = menuEntries[1];
else if (privacy == "PRIVATE")
chosenNode = menuEntries[2];
else
chosenNode = menuEntries[0];
privacyMenu.chosenNode = chosenNode;
$(chosenNode).addClassName("_chosen");
}
}
function onComponentEditorLoad(event) {
if (!$("statusPercent"))
initializeAttendeesHref();
initializeDocumentHref();
initializePrivacyMenu();
var list = $("calendarList");
Event.observe(list, "mousedown",
onChangeCalendar.bindAsEventListener(list),
false);
list.fire("mousedown");
if (!$("statusPercent"))
initializeAttendeesHref();
initializeDocumentHref();
initializePrivacyMenu();
var list = $("calendarList");
Event.observe(list, "mousedown",
onChangeCalendar.bindAsEventListener(list),
false);
list.fire("mousedown");
var menuItems = $("itemPrivacyList").childNodesWithTag("li");
for (var i = 0; i < menuItems.length; i++)
Event.observe(menuItems[i], "mousedown",
onMenuSetClassification.bindAsEventListener(menuItems[i]),
false);
var menuItems = $("itemPrivacyList").childNodesWithTag("li");
for (var i = 0; i < menuItems.length; i++)
Event.observe(menuItems[i], "mousedown",
onMenuSetClassification.bindAsEventListener(menuItems[i]),
false);
}
FastInit.addOnLoad(onComponentEditorLoad);