]> err.no Git - scalable-opengroupware.org/blob - UI/Scheduler/UIxComponentEditor.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1236 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / UI / Scheduler / UIxComponentEditor.m
1 /* UIxComponentEditor.m - this file is part of SOGo
2  *
3  * Copyright (C) 2006 Inverse groupe conseil
4  *
5  * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
6  *
7  * This file is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This file is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #import <Foundation/NSArray.h>
24 #import <Foundation/NSBundle.h>
25 #import <Foundation/NSException.h>
26 #import <Foundation/NSCalendarDate.h>
27 #import <Foundation/NSKeyValueCoding.h>
28 #import <Foundation/NSString.h>
29 #import <Foundation/NSUserDefaults.h>
30 #import <Foundation/NSURL.h>
31
32 #import <NGCards/iCalPerson.h>
33 #import <NGCards/iCalRepeatableEntityObject.h>
34 #import <NGCards/iCalRecurrenceRule.h>
35 #import <NGCards/NSString+NGCards.h>
36 #import <NGCards/NSCalendarDate+NGCards.h>
37 #import <NGObjWeb/SoSecurityManager.h>
38 #import <NGObjWeb/NSException+HTTP.h>
39 #import <NGObjWeb/WORequest.h>
40 #import <NGExtensions/NSCalendarDate+misc.h>
41 #import <NGExtensions/NSObject+Logs.h>
42 #import <NGExtensions/NSString+misc.h>
43
44 #import <SoObjects/Appointments/SOGoAppointmentFolder.h>
45 #import <SoObjects/Appointments/SOGoAppointmentFolders.h>
46 #import <SoObjects/Appointments/SOGoAppointmentObject.h>
47 #import <SoObjects/Appointments/SOGoTaskObject.h>
48 #import <SoObjects/SOGo/NSString+Utilities.h>
49 #import <SoObjects/SOGo/SOGoUser.h>
50 #import <SoObjects/SOGo/SOGoPermissions.h>
51
52 #import "UIxComponent+Scheduler.h"
53
54 #import "UIxComponentEditor.h"
55
56 @implementation UIxComponentEditor
57
58 - (id) init
59 {
60   if ((self = [super init]))
61     {
62       component = nil;
63       [self setPrivacy: @"PUBLIC"];
64       [self setIsCycleEndNever];
65       componentOwner = @"";
66       organizer = nil;
67       attendeesNames = nil;
68       attendeesEmails = nil;
69       calendarList = nil;
70     }
71
72   return self;
73 }
74
75 - (void) dealloc
76 {
77   [item release];
78   [cycleUntilDate release];
79   [title release];
80   [location release];
81   [organizer release];
82   [comment release];
83   [priority release];
84   [categories release];
85   [cycle release];
86   [cycleEnd release];
87   [url release];
88   [attendeesNames release];
89   [attendeesEmails release];
90   [calendarList release];
91
92   [super dealloc];
93 }
94
95 - (void) _loadAttendees
96 {
97   NSEnumerator *attendees;
98   iCalPerson *currentAttendee;
99   NSMutableString *names, *emails;
100
101   names = [NSMutableString new];
102   emails = [NSMutableString new];
103
104   attendees = [[component attendees] objectEnumerator];
105   currentAttendee = [attendees nextObject];
106   while (currentAttendee)
107     {
108       [names appendFormat: @"%@,", [currentAttendee cn]];
109       [emails appendFormat: @"%@,", [currentAttendee rfc822Email]];
110       currentAttendee = [attendees nextObject];
111     }
112
113   if ([names length] > 0)
114     {
115       ASSIGN (attendeesNames, [names substringToIndex: [names length] - 1]);
116       ASSIGN (attendeesEmails,
117               [emails substringToIndex: [emails length] - 1]);
118     }
119
120   [names release];
121   [emails release];
122 }
123
124 - (void) _loadCategories
125 {
126   NSString *compCategories, *simpleCategory;
127
128   compCategories = [component categories];
129   if ([compCategories length] > 0)
130     {
131       simpleCategory = [[compCategories componentsSeparatedByString: @","]
132                          objectAtIndex: 0];
133       ASSIGN (category, [simpleCategory uppercaseString]);
134     }
135 }
136
137 /* warning: we use this method which will be triggered by the template system
138    when the page is instantiated, but we should find another and cleaner way of
139    doing this... for example, when the clientObject is set */
140 - (void) setComponent: (iCalRepeatableEntityObject *) newComponent
141 {
142 //   iCalRecurrenceRule *rrule;
143   SOGoObject *co;
144
145   if (!component)
146     {
147       component = newComponent;
148
149       co = [self clientObject];
150       componentOwner = [co ownerInContext: nil];
151
152       ASSIGN (title, [component summary]);
153       ASSIGN (location, [component location]);
154       ASSIGN (comment, [component comment]);
155       ASSIGN (url, [[component url] absoluteString]);
156       ASSIGN (privacy, [component accessClass]);
157       ASSIGN (priority, [component priority]);
158       ASSIGN (status, [component status]);
159       ASSIGN (categories, [[component categories] commaSeparatedValues]);
160       ASSIGN (organizer, [component organizer]);
161       [self _loadCategories];
162       [self _loadAttendees];
163     }
164 //   /* cycles */
165 //   if ([component isRecurrent])
166 //     {
167 //       rrule = [[component recurrenceRules] objectAtIndex: 0];
168 //       [self adjustCycleControlsForRRule: rrule];
169 //     }
170 }
171
172 - (void) setSaveURL: (NSString *) newSaveURL
173 {
174   saveURL = newSaveURL;
175 }
176
177 - (NSString *) saveURL
178 {
179   return saveURL;
180 }
181
182 /* accessors */
183
184 - (void) setItem: (id) _item
185 {
186   ASSIGN (item, _item);
187 }
188
189 - (id) item
190 {
191   return item;
192 }
193
194 - (NSString *) itemPriorityText
195 {
196   return [self labelForKey: [NSString stringWithFormat: @"prio_%@", item]];
197 }
198
199 - (NSString *) itemPrivacyText
200 {
201   NSString *tag;
202
203   tag = [[self clientObject] componentTag];
204
205   return [self labelForKey: [NSString stringWithFormat: @"%@_%@", item, tag]];
206 }
207
208 - (NSString *) itemStatusText
209 {
210   return [self labelForKey: [NSString stringWithFormat: @"status_%@", item]];
211 }
212
213 - (void) setTitle: (NSString *) _value
214 {
215   ASSIGN (title, _value);
216 }
217
218 - (NSString *) title
219 {
220   return title;
221 }
222
223 - (void) setUrl: (NSString *) _url
224 {
225   ASSIGN (url, _url);
226 }
227
228 - (NSString *) url
229 {
230   return url;
231 }
232
233 - (void) setAttendeesNames: (NSString *) newAttendeesNames
234 {
235   ASSIGN (attendeesNames, newAttendeesNames);
236 }
237
238 - (NSString *) attendeesNames
239 {
240   return attendeesNames;
241 }
242
243 - (void) setAttendeesEmails: (NSString *) newAttendeesEmails
244 {
245   ASSIGN (attendeesEmails, newAttendeesEmails);
246 }
247
248 - (NSString *) attendeesEmails
249 {
250   return attendeesEmails;
251 }
252
253 - (void) setLocation: (NSString *) _value
254 {
255   ASSIGN (location, _value);
256 }
257
258 - (NSString *) location
259 {
260   return location;
261 }
262
263 - (void) setComment: (NSString *) _value
264 {
265   ASSIGN (comment, _value);
266 }
267
268 - (NSString *) comment
269 {
270   return comment;
271 }
272
273 - (NSArray *) categoryList
274 {
275   static NSArray *categoryItems = nil;
276
277   if (!categoryItems)
278     {
279       categoryItems = [NSArray arrayWithObjects: @"ANNIVERSARY",
280                                @"BIRTHDAY",
281                                @"BUSINESS",
282                                @"CALLS", 
283                                @"CLIENTS",
284                                @"COMPETITION",
285                                @"CUSTOMER",
286                                @"FAVORITES",
287                                @"FOLLOW UP",
288                                @"GIFTS",
289                                @"HOLIDAYS",
290                                @"IDEAS",
291                                @"ISSUES",
292                                @"MISCELLANEOUS",
293                                @"PERSONAL",
294                                @"PROJECTS",
295                                @"PUBLIC HOLIDAY",
296                                @"STATUS",
297                                @"SUPPLIERS",
298                                @"TRAVEL",
299                                @"VACATION",
300                               nil];
301       [categoryItems retain];
302     }
303
304   return categoryItems;
305 }
306
307 - (void) setCategories: (NSArray *) _categories
308 {
309   ASSIGN (categories, _categories);
310 }
311
312 - (NSArray *) categories
313 {
314   return categories;
315 }
316
317 - (void) setCategory: (NSArray *) newCategory
318 {
319   ASSIGN (category, newCategory);
320 }
321
322 - (NSString *) category
323 {
324   return category;
325 }
326
327 - (NSString *) itemCategoryText
328 {
329   return [self labelForKey:
330                  [NSString stringWithFormat: @"category_%@", item]];
331 }
332
333 - (NSArray *) calendarList
334 {
335   SOGoAppointmentFolder *calendar, *currentCalendar;
336   SOGoAppointmentFolders *calendarParent;
337   NSEnumerator *allCalendars;
338
339   if (!calendarList)
340     {
341       calendarList = [NSMutableArray new];
342       calendar = [[self clientObject] container];
343       calendarParent = [calendar container];
344       allCalendars = [[calendarParent subFolders] objectEnumerator];
345       currentCalendar = [allCalendars nextObject];
346       while (currentCalendar)
347         {
348           if ([currentCalendar isActive])
349             [calendarList addObject: currentCalendar];
350           currentCalendar = [allCalendars nextObject];
351         }
352     }
353
354   return calendarList;
355 }
356
357 - (NSString *) calendarsFoldersList
358 {
359   NSArray *calendars;
360
361   calendars = [[self calendarList] valueForKey: @"nameInContainer"];
362
363   return [calendars componentsJoinedByString: @","];
364 }
365
366 - (SOGoAppointmentFolder *) componentCalendar
367 {
368   SOGoAppointmentFolder *calendar;
369
370   calendar = [[self clientObject] container];
371   
372   return calendar;
373 }
374
375 /* priorities */
376
377 - (NSArray *) priorities
378 {
379   /* 0 == undefined
380      9 == low
381      5 == medium
382      1 == high
383   */
384   static NSArray *priorities = nil;
385
386   if (!priorities)
387     {
388       priorities = [NSArray arrayWithObjects: @"9", @"5", @"1", nil];
389       [priorities retain];
390     }
391
392   return priorities;
393 }
394
395 - (void) setPriority: (NSString *) _priority
396 {
397   ASSIGN (priority, _priority);
398 }
399
400 - (NSString *) priority
401 {
402   return priority;
403 }
404
405 - (NSArray *) privacyClasses
406 {
407   static NSArray *priorities = nil;
408
409   if (!priorities)
410     {
411       priorities = [NSArray arrayWithObjects: @"PUBLIC",
412                             @"CONFIDENTIAL", @"PRIVATE", nil];
413       [priorities retain];
414     }
415
416   return priorities;
417 }
418
419 - (void) setPrivacy: (NSString *) _privacy
420 {
421   ASSIGN (privacy, _privacy);
422 }
423
424 - (NSString *) privacy
425 {
426   return privacy;
427 }
428
429 - (NSArray *) statusTypes
430 {
431   static NSArray *priorities = nil;
432
433   if (!priorities)
434     {
435       priorities = [NSArray arrayWithObjects: @"", @"TENTATIVE", @"CONFIRMED", @"CANCELLED", nil];
436       [priorities retain];
437     }
438
439   return priorities;
440 }
441
442 - (void) setStatus: (NSString *) _status
443 {
444   ASSIGN (status, _status);
445 }
446
447 - (NSString *) status
448 {
449   return status;
450 }
451
452 - (NSArray *) cycles
453 {
454   NSBundle *bundle;
455   NSString *path;
456   static NSArray *cycles = nil;
457   
458   if (!cycles)
459     {
460       bundle = [NSBundle bundleForClass:[self class]];
461       path   = [bundle pathForResource: @"cycles" ofType: @"plist"];
462       NSAssert(path != nil, @"Cannot find cycles.plist!");
463       cycles = [[NSArray arrayWithContentsOfFile:path] retain];
464       NSAssert(cycles != nil, @"Cannot instantiate cycles from cycles.plist!");
465     }
466
467   return cycles;
468 }
469
470 - (void) setCycle: (NSDictionary *) _cycle
471 {
472   ASSIGN (cycle, _cycle);
473 }
474
475 - (NSDictionary *) cycle
476 {
477   return cycle;
478 }
479
480 - (BOOL) hasCycle
481 {
482   return ([cycle objectForKey: @"rule"] != nil);
483 }
484
485 - (NSString *) cycleLabel
486 {
487   NSString *key;
488   
489   key = [(NSDictionary *)item objectForKey: @"label"];
490
491   return [self labelForKey:key];
492 }
493
494 - (void) setCycleUntilDate: (NSCalendarDate *) _cycleUntilDate
495 {
496 //   NSCalendarDate *until;
497
498 //   /* copy hour/minute/second from startDate */
499 //   until = [_cycleUntilDate hour: [startDate hourOfDay]
500 //                            minute: [startDate minuteOfHour]
501 //                            second: [startDate secondOfMinute]];
502 //   [until setTimeZone: [startDate timeZone]];
503 //   ASSIGN (cycleUntilDate, until);
504 }
505
506 - (NSCalendarDate *) cycleUntilDate
507 {
508   return cycleUntilDate;
509 }
510
511 - (iCalRecurrenceRule *) rrule
512 {
513   NSString *ruleRep;
514   iCalRecurrenceRule *rule;
515
516   if (![self hasCycle])
517     return nil;
518   ruleRep = [cycle objectForKey: @"rule"];
519   rule = [iCalRecurrenceRule recurrenceRuleWithICalRepresentation:ruleRep];
520
521   if (cycleUntilDate && [self isCycleEndUntil])
522     [rule setUntilDate:cycleUntilDate];
523
524   return rule;
525 }
526
527 - (void) adjustCycleControlsForRRule: (iCalRecurrenceRule *) _rrule
528 {
529 //   NSDictionary *c;
530 //   NSCalendarDate *until;
531   
532 //   c = [self cycleMatchingRRule:_rrule];
533 //   [self setCycle:c];
534
535 //   until = [[[_rrule untilDate] copy] autorelease];
536 //   if (!until)
537 //     until = startDate;
538 //   else
539 //     [self setIsCycleEndUntil];
540
541 //   [until setTimeZone:[[self clientObject] userTimeZone]];
542 //   [self setCycleUntilDate:until];
543 }
544
545 /*
546  This method is necessary, because we have a fixed sets of cycles in the UI.
547  The model is able to represent arbitrary rules, however.
548  There SHOULD be a different UI, similar to iCal.app, to allow modelling
549  of more complex rules.
550  
551  This method obviously cannot map all existing rules back to the fixed list
552  in cycles.plist. This should be fixed in a future version when interop
553  becomes more important.
554  */
555 - (NSDictionary *) cycleMatchingRRule: (iCalRecurrenceRule *) _rrule
556 {
557   NSString *cycleRep;
558   NSArray *cycles;
559   unsigned i, count;
560
561   if (!_rrule)
562     return [[self cycles] objectAtIndex:0];
563
564   cycleRep = [_rrule versitString];
565   cycles   = [self cycles];
566   count    = [cycles count];
567   for (i = 1; i < count; i++) {
568     NSDictionary *c;
569     NSString *cr;
570
571     c  = [cycles objectAtIndex:i];
572     cr = [c objectForKey: @"rule"];
573     if ([cr isEqualToString:cycleRep])
574       return c;
575   }
576   [self warnWithFormat: @"No default cycle for rrule found! -> %@", _rrule];
577   return nil;
578 }
579
580 /* cycle "ends" - supposed to be 'never', 'COUNT' or 'UNTIL' */
581 - (NSArray *) cycleEnds
582 {
583   static NSArray *ends = nil;
584   
585   if (!ends)
586     {
587       ends = [NSArray arrayWithObjects: @"cycle_end_never",
588                       @"cycle_end_until", nil];
589       [ends retain];
590     }
591
592   return ends;
593 }
594
595 - (void) setCycleEnd: (NSString *) _cycleEnd
596 {
597   ASSIGN (cycleEnd, _cycleEnd);
598 }
599
600 - (NSString *) cycleEnd
601 {
602   return cycleEnd;
603 }
604
605 - (BOOL) isCycleEndUntil
606 {
607   return (cycleEnd && [cycleEnd isEqualToString: @"cycle_end_until"]);
608 }
609
610 - (void) setIsCycleEndUntil
611 {
612   [self setCycleEnd: @"cycle_end_until"];
613 }
614
615 - (void) setIsCycleEndNever
616 {
617   [self setCycleEnd: @"cycle_end_never"];
618 }
619
620 /* helpers */
621 - (NSString *) completeURIForMethod: (NSString *) _method
622 {
623   NSString *uri;
624   NSRange r;
625     
626   uri = [[[self context] request] uri];
627     
628   /* first: identify query parameters */
629   r = [uri rangeOfString: @"?" options:NSBackwardsSearch];
630   if (r.length > 0)
631     uri = [uri substringToIndex:r.location];
632     
633   /* next: append trailing slash */
634   if (![uri hasSuffix: @"/"])
635     uri = [uri stringByAppendingString: @"/"];
636   
637   /* next: append method */
638   uri = [uri stringByAppendingString:_method];
639     
640   /* next: append query parameters */
641   return [self completeHrefForMethod:uri];
642 }
643
644 - (BOOL) isWriteableClientObject
645 {
646   return [[self clientObject] 
647                 respondsToSelector: @selector(saveContentString:)];
648 }
649
650 - (BOOL) containsConflict: (id) _component
651 {
652   [self subclassResponsibility: _cmd];
653
654   return NO;
655 }
656
657 /* access */
658
659 #if 0
660 - (iCalPerson *) getOrganizer
661 {
662   iCalPerson *p;
663   NSString *emailProp;
664   
665   emailProp = [@"MAILTO:" stringByAppendingString:[self emailForUser]];
666   p = [[[iCalPerson alloc] init] autorelease];
667   [p setEmail:emailProp];
668   [p setCn:[self cnForUser]];
669   return p;
670 }
671 #endif
672
673 - (BOOL) isMyComponent
674 {
675   return ([[context activeUser] hasEmail: [organizer rfc822Email]]);
676 }
677
678 - (BOOL) canEditComponent
679 {
680   return [self isMyComponent];
681 }
682
683 /* response generation */
684
685 - (NSString *) initialCycleVisibility
686 {
687   return ([self hasCycle]
688           ? @"visibility: visible;"
689           : @"visibility: hidden;");
690 }
691
692 - (NSString *) initialCycleEndUntilVisibility {
693   return ([self isCycleEndUntil]
694           ? @"visibility: visible;"
695           : @"visibility: hidden;");
696 }
697
698 // - (NSString *) iCalParticipantsAndResourcesStringFromQueryParameters
699 // {
700 //   NSString *s;
701   
702 //   s = [self iCalParticipantsStringFromQueryParameters];
703 //   return [s stringByAppendingString:
704 //               [self iCalResourcesStringFromQueryParameters]];
705 // }
706
707 // - (NSString *) iCalParticipantsStringFromQueryParameters
708 // {
709 //   static NSString *iCalParticipantString = @"ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CN=\"%@\":MAILTO:%@\r\n";
710   
711 //   return [self iCalStringFromQueryParameter: @"ps"
712 //                format: iCalParticipantString];
713 // }
714
715 // - (NSString *) iCalResourcesStringFromQueryParameters
716 // {
717 //   static NSString *iCalResourceString = @"ATTENDEE;ROLE=NON-PARTICIPANT;CN=\"%@\":MAILTO:%@\r\n";
718
719 //   return [self iCalStringFromQueryParameter: @"rs"
720 //                format: iCalResourceString];
721 // }
722
723 // - (NSString *) iCalStringFromQueryParameter: (NSString *) _qp
724 //                                      format: (NSString *) _format
725 // {
726 //   AgenorUserManager *um;
727 //   NSMutableString *iCalRep;
728 //   NSString *s;
729
730 //   um = [AgenorUserManager sharedUserManager];
731 //   iCalRep = (NSMutableString *)[NSMutableString string];
732 //   s = [self queryParameterForKey:_qp];
733 //   if(s && [s length] > 0) {
734 //     NSArray *es;
735 //     unsigned i, count;
736     
737 //     es = [s componentsSeparatedByString: @","];
738 //     count = [es count];
739 //     for(i = 0; i < count; i++) {
740 //       NSString *email, *cn;
741       
742 //       email = [es objectAtIndex:i];
743 //       cn = [um getCNForUID:[um getUIDForEmail:email]];
744 //       [iCalRep appendFormat:_format, cn, email];
745 //     }
746 //   }
747 //   return iCalRep;
748 // }
749
750 - (NSException *) validateObjectForStatusChange
751 {
752   id co;
753
754   co = [self clientObject];
755   if (![co respondsToSelector: @selector(changeParticipationStatus:)])
756     return [NSException exceptionWithHTTPStatus: 400 /* Bad Request */
757                         reason:
758                           @"method cannot be invoked on the specified object"];
759
760   return nil;
761 }
762
763 /* contact editor compatibility */
764
765 - (NSString *) urlButtonClasses
766 {
767   NSString *classes;
768
769   if ([url length])
770     classes = @"button";
771   else
772     classes = @"button _disabled";
773
774   return classes;
775 }
776
777 - (void) _handleAttendeesEdition
778 {
779   NSArray *names, *emails;
780   NSMutableArray *newAttendees;
781   unsigned int count, max;
782   NSString *currentEmail;
783   iCalPerson *currentAttendee;
784
785   newAttendees = [NSMutableArray new];
786   if ([attendeesNames length] > 0)
787     {
788       names = [attendeesNames componentsSeparatedByString: @","];
789       emails = [attendeesEmails componentsSeparatedByString: @","];
790       max = [emails count];
791       for (count = 0; count < max; count++)
792         {
793           currentEmail = [emails objectAtIndex: count];
794           currentAttendee = [component findParticipantWithEmail: currentEmail];
795           if (!currentAttendee)
796             {
797               currentAttendee = [iCalPerson elementWithTag: @"attendee"];
798               [currentAttendee setCn: [names objectAtIndex: count]];
799               [currentAttendee setEmail: currentEmail];
800               [currentAttendee setRole: @"REQ-PARTICIPANT"];
801               [currentAttendee
802                 setParticipationStatus: iCalPersonPartStatNeedsAction];
803             }
804           [newAttendees addObject: currentAttendee];
805         }
806     }
807
808   [component setAttendees: newAttendees];
809   [newAttendees release];
810 }
811
812 - (void) _handleOrganizer
813 {
814   NSString *organizerEmail;
815   SOGoUser *activeUser;
816   NSDictionary *primaryIdentity;
817
818   organizerEmail = [[component organizer] email];
819   if ([organizerEmail length] == 0)
820     {
821       if ([[component attendees] count] > 0)
822         {
823           ASSIGN (organizer, [iCalPerson elementWithTag: @"organizer"]);
824           activeUser = [context activeUser];
825           primaryIdentity = [activeUser primaryIdentity];
826           [organizer setCn: [activeUser cn]];
827           [organizer setEmail: [primaryIdentity objectForKey: @"email"]];
828           [component setOrganizer: organizer];
829         }
830     }
831   else
832     {
833       if ([[component attendees] count] == 0)
834         {
835           ASSIGN (organizer, [iCalPerson elementWithTag: @"organizer"]);
836           [component setOrganizer: organizer];
837         }
838     }
839 }
840
841 - (void) takeValuesFromRequest: (WORequest *) _rq
842                      inContext: (WOContext *) _ctx
843 {
844   NSCalendarDate *now;
845   SOGoCalendarComponent *clientObject;
846
847   [super takeValuesFromRequest: _rq inContext: _ctx];
848
849   now = [NSCalendarDate calendarDate];
850   [component setSummary: title];
851   [component setLocation: location];
852   [component setComment: comment];
853   [component setUrl: url];
854   [component setAccessClass: privacy];
855   [component setCategories: [category capitalizedString]];
856   [self _handleAttendeesEdition];
857   [self _handleOrganizer];
858   clientObject = [self clientObject];
859   if ([clientObject isNew])
860     {
861       [component setUid: [clientObject nameInContainer]];
862       [component setCreated: now];
863       [component setTimeStampAsDate: now];
864     }
865   [component setPriority: priority];
866   [component setLastModified: now];
867 }
868
869 - (NSString *) toolbar
870 {
871   SOGoCalendarComponent *clientObject;
872   NSString *toolbarFilename;
873   iCalPerson *participant;
874   iCalPersonPartStat participationStatus;
875   SoSecurityManager *sm;
876   NSString *owner;
877
878   sm = [SoSecurityManager sharedSecurityManager];
879   clientObject = [self clientObject];
880
881   owner = [clientObject ownerInContext: context];
882   participant = [clientObject findParticipantWithUID: owner];
883
884   if (participant
885       && ![sm validatePermission: SOGoCalendarPerm_RespondToComponent
886               onObject: clientObject
887               inContext: context])
888     {
889       participationStatus = [participant participationStatus];
890       /* Lightning does not manage participation status within tasks */
891       if (participationStatus == iCalPersonPartStatAccepted)
892         toolbarFilename = @"SOGoAppointmentObjectDecline.toolbar";
893       else if (participationStatus == iCalPersonPartStatDeclined)
894         toolbarFilename = @"SOGoAppointmentObjectAccept.toolbar";
895       else
896         toolbarFilename = @"SOGoAppointmentObjectAcceptOrDecline.toolbar";
897     }
898   else if (![sm validatePermission: SOGoCalendarPerm_ModifyComponent
899                 onObject: clientObject
900                 inContext: context])
901     {
902       if ([[clientObject componentTag] isEqualToString: @"vevent"])
903         toolbarFilename = @"SOGoAppointmentObject.toolbar";
904       else
905         toolbarFilename = @"SOGoTaskObject.toolbar";
906     }
907   else
908     toolbarFilename = @"SOGoComponentClose.toolbar";
909
910   return toolbarFilename;
911 }
912
913 @end