]> err.no Git - scalable-opengroupware.org/blobdiff - UI/Scheduler/UIxTaskEditor.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1172 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / UI / Scheduler / UIxTaskEditor.m
index 8ff0ff6e14c946f7188628c3907f85397b5b367c..0258ae2d24ae6adc9256ce416215b66c6589fcd4 100644 (file)
-/*
-  Copyright (C) 2004-2005 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
+/* UIxTaskEditor.m - this file is part of SOGo
+ *
+ * Copyright (C) 2007 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <NGObjWeb/SoObject.h>
+#import <NGObjWeb/WORequest.h>
+#import <NGObjWeb/NSException+HTTP.h>
+#import <NGExtensions/NSCalendarDate+misc.h>
+
+#import <NGCards/iCalToDo.h>
+#import <NGCards/iCalPerson.h>
+
+#import <SoObjects/SOGo/SOGoUser.h>
+#import <SoObjects/SOGo/SOGoContentObject.h>
+#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
+#import <SoObjects/Appointments/SOGoTaskObject.h>
+
+#import "UIxComponentEditor.h"
+#import "UIxTaskEditor.h"
 
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
+@implementation UIxTaskEditor
 
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      taskStartDate = nil;
+      taskDueDate = nil;
+      statusDate = nil;
+      hasStartDate = NO;
+      hasDueDate = NO;
+      status = nil;
+      statusPercent = nil;
+      item = nil;
+      todo = nil;
+    }
 
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
+  return self;
+}
 
-#import <SOGo/NSCalendarDate+SOGo.h>
+- (void) dealloc
+{
+  [taskStartDate release];
+  [taskDueDate release];
+  [statusDate release];
+  [status release];
+  [statusPercent release];
+  [super dealloc];
+}
 
-#import "UIxTaskEditor.h"
+/* template values */
+- (iCalToDo *) todo
+{
+  return todo;
+}
 
-/* TODO: CLEAN UP */
+- (NSString *) saveURL
+{
+  return [NSString stringWithFormat: @"%@/saveAsTask",
+                   [[self clientObject] baseURL]];
+}
 
-#import "common.h"
-#import <NGCards/NGCards.h>
-#import <NGExtensions/NGCalendarDateRange.h>
-#import <SOGoUI/SOGoDateFormatter.h>
-#import <SOGo/AgenorUserManager.h>
-#import <Appointments/SOGoAppointmentFolder.h>
-#import <Appointments/SOGoTaskObject.h>
-#import "UIxComponent+Agenor.h"
+/* icalendar values */
+- (void) setTaskStartDate: (NSCalendarDate *) newTaskStartDate
+{
+  ASSIGN (taskStartDate, newTaskStartDate);
+}
 
-@implementation UIxTaskEditor
+- (NSCalendarDate *) taskStartDate
+{
+  return taskStartDate;
+}
 
-- (void) dealloc
+- (void) setHasStartDate: (BOOL) newHasStartDate
 {
-  [dueDate release];
-  [super dealloc];
+  hasStartDate = newHasStartDate;
 }
 
-- (void) setTaskStartDate: (NSCalendarDate *) _date
+- (BOOL) hasStartDate
 {
-  [self setStartDate: _date];
+  return hasStartDate;
 }
 
-- (NSCalendarDate *) taskStartDate
+- (BOOL) startDateDisabled
 {
-  return [self startDate];
+  return !hasStartDate;
 }
 
-- (void) setTaskDueDate: (NSCalendarDate *) _date
+- (void) setTaskDueDate: (NSCalendarDate *) newTaskDueDate
 {
-  ASSIGN(dueDate, _date);
+  ASSIGN (taskDueDate, newTaskDueDate);
 }
 
 - (NSCalendarDate *) taskDueDate
 {
-  return dueDate;
-}
-
-/* iCal */
-
-- (NSString *) iCalStringTemplate
-{
-  static NSString *iCalStringTemplate = \
-    @"BEGIN:VCALENDAR\r\n"
-    @"METHOD:REQUEST\r\n"
-    @"PRODID://Inverse groupe conseil/SOGo 0.9\r\n"
-    @"VERSION:2.0\r\n"
-    @"BEGIN:VTODO\r\n"
-    @"UID:%@\r\n"
-    @"CLASS:PUBLIC\r\n"
-    @"STATUS:NEEDS-ACTION\r\n" /* confirmed by default */
-    @"PERCENT-COMPLETE:0\r\n"
-    @"DTSTART:%@Z\r\n"
-    @"DUE:%@Z\r\n"
-    @"DTSTAMP:%@Z\r\n"
-    @"SEQUENCE:1\r\n"
-    @"PRIORITY:5\r\n"
-    @"%@"                   /* organizer */
-    @"%@"                   /* participants and resources */
-    @"END:VTODO\r\n"
-    @"END:VCALENDAR";
-
-  NSCalendarDate *stamp, *lStartDate, *lDueDate;
-  NSString *template, *s;
-  NSTimeZone *utc;
-  unsigned minutes;
-
-  s = [self queryParameterForKey:@"dur"];
-  if ([s length] > 0)
-    minutes = [s intValue];
-  else
-    minutes = 60;
-
-  utc = [NSTimeZone timeZoneWithName: @"GMT"];
-  lStartDate = [self newStartDate];
-  [lStartDate setTimeZone: utc];
-  lDueDate = [lStartDate dateByAddingYears: 0 months: 0 days: 0
-                         hours: 0 minutes: minutes seconds: 0];
-  stamp = [NSCalendarDate calendarDate];
-  [stamp setTimeZone: utc];
-  
-  s = [self iCalParticipantsAndResourcesStringFromQueryParameters];
-  template   = [NSString stringWithFormat:iCalStringTemplate,
-                         [[self clientObject] nameInContainer],
-                         [lStartDate iCalFormattedDateTimeString],
-                         [lDueDate iCalFormattedDateTimeString],
-                         [stamp iCalFormattedDateTimeString],
-                         [self iCalOrganizerString],
-                         s];
-  return template;
-}
-
-/* new */
-
-- (id) newAction
-{
-  /*
-    This method creates a unique ID and redirects to the "edit" method on the
-    new ID.
-    It is actually a folder method and should be defined on the folder.
-    
-    Note: 'clientObject' is the SOGoAppointmentFolder!
-          Update: remember that there are group folders as well.
-  */
-  NSString *uri, *objectId, *method, *ps;
-
-  objectId = [NSClassFromString(@"SOGoAppointmentFolder")
-                              globallyUniqueObjectId];
-  if ([objectId length] == 0) {
-    return [NSException exceptionWithHTTPStatus:500 /* Internal Error */
-                       reason:@"could not create a unique ID"];
-  }
-
-  method = [NSString stringWithFormat:@"Calendar/%@/editAsTask", objectId];
-  method = [[self userFolderPath] stringByAppendingPathComponent:method];
-
-  /* check if participants have already been provided */
-  ps     = [self queryParameterForKey:@"ps"];
-//   if (ps) {
-//     [self setQueryParameter:ps forKey:@"ps"];
-//   }
- if (!ps
-     && [[self clientObject] respondsToSelector:@selector(calendarUIDs)]) {
-    AgenorUserManager *um;
-    NSArray *uids;
-    NSMutableArray *emails;
-    unsigned i, count;
-
-    /* add all current calendarUIDs as default participants */
-
-    um     = [AgenorUserManager sharedUserManager];
-    uids   = [[self clientObject] calendarUIDs];
-    count  = [uids count];
-    emails = [NSMutableArray arrayWithCapacity:count];
-    
-    for (i = 0; i < count; i++) {
-      NSString *email;
-      
-      email = [um getEmailForUID:[uids objectAtIndex:i]];
-      if (email)
-        [emails addObject:email];
-    }
-    ps = [emails componentsJoinedByString:@","];
-    [self setQueryParameter:ps forKey:@"ps"];
-  }
-  uri = [self completeHrefForMethod:method];
-  return [self redirectToLocation:uri];
+  return taskDueDate;
+}
+
+- (void) setHasDueDate: (BOOL) newHasDueDate
+{
+  hasDueDate = newHasDueDate;
 }
 
-/* save */
+- (BOOL) hasDueDate
+{
+  return hasDueDate;
+}
 
-- (void) loadValuesFromTask: (iCalToDo *) _task
+- (BOOL) dueDateDisabled
 {
-  NSTimeZone *uTZ;
+  return !hasDueDate;
+}
 
-  [self loadValuesFromComponent: _task];
+- (NSArray *) repeatList
+{
+  static NSArray *repeatItems = nil;
 
-  uTZ = [[self clientObject] userTimeZone];
-  dueDate = [_task due];
-//   if (!dueDate)
-//     dueDate = [[self startDate] dateByAddingYears: 0 months: 0 days: 0
-//                                 hours: 1 minutes: 0 seconds: 0];
-  if (dueDate)
+  if (!repeatItems)
     {
-      [dueDate setTimeZone: uTZ];
-      [dueDate retain];
+      repeatItems = [NSArray arrayWithObjects: @"DAILY",
+                             @"WEEKLY",
+                             @"BI-WEEKLY",
+                             @"EVERY WEEKDAY",
+                             @"MONTHLY",
+                             @"YEARLY",
+                             @"-",
+                             @"CUSTOM",
+                             nil];
+      [repeatItems retain];
     }
+
+  return repeatItems;
 }
 
-- (void) saveValuesIntoTask: (iCalToDo *) _task
+- (NSString *) itemRepeatText
 {
-  /* merge in form values */
-  NSArray *attendees, *lResources;
-  iCalRecurrenceRule *rrule;
-  NSCalendarDate *dateTime;
+  NSString *text;
 
-  if (hasStartDate)
-    dateTime = [self taskStartDate];
-  else
-    dateTime = nil;
-  [_task setStartDate: dateTime];
-  if (hasDueDate)
-    dateTime = [self taskDueDate];
+  if ([item isEqualToString: @"-"])
+    text = item;
   else
-    dateTime = nil;
-  [_task setDue: dateTime];
-
-  [_task setSummary: [self title]];
-  [_task setUrl: [self url]];
-  [_task setLocation: [self location]];
-  [_task setComment: [self comment]];
-  [_task setPriority:[self priority]];
-  [_task setAccessClass: [self privacy]];
-  [_task setStatus: [self status]];
-
-//   [_task setCategories: [[self categories] componentsJoinedByString: @","]];
-  
-#if 0
-  /*
-    Note: bad, bad, bad!
-    Organizer is no form value, thus we MUST NOT change it
-  */
-  [_task setOrganizer:organizer];
-#endif
-  attendees  = [self participants];
-  lResources = [self resources];
-  if ([lResources count] > 0) {
-    attendees = ([attendees count] > 0)
-      ? [attendees arrayByAddingObjectsFromArray:lResources]
-      : lResources;
-  }
-  [attendees makeObjectsPerformSelector: @selector (setTag:)
-             withObject: @"attendee"];
-  [_task setAttendees:attendees];
-
-  /* cycles */
-  [_task removeAllRecurrenceRules];
-  rrule = [self rrule];
-  if (rrule)
-    [_task addToRecurrenceRules: rrule];
-}
-
-- (iCalToDo *) taskFromString: (NSString *) _iCalString
-{
-  iCalCalendar *calendar;
-  iCalToDo *task;
-
-  calendar = [iCalCalendar parseSingleFromSource: _iCalString];
-  task = (iCalToDo *) [calendar firstChildWithTag: @"vtodo"];
-
-  return task;
-}
-
-/* conflict management */
-
-- (BOOL) containsConflict: (id) _task
-{
-  NSArray *attendees, *uids;
-  SOGoAppointmentFolder *groupCalendar;
-  NSArray *infos;
-  NSArray *ranges;
-  id folder;
-
-  [self logWithFormat:@"search from %@ to %@", 
-         [_task startDate], [_task due]];
-
-  folder    = [[self clientObject] container];
-  attendees = [_task attendees];
-  uids      = [folder uidsFromICalPersons:attendees];
-  if ([uids count] == 0) {
-    [self logWithFormat:@"Note: no UIDs selected."];
-    return NO;
-  }
-
-  groupCalendar = [folder lookupGroupCalendarFolderForUIDs:uids
-                          inContext:[self context]];
-  [self debugWithFormat:@"group calendar: %@", groupCalendar];
-  
-  if (![groupCalendar respondsToSelector:@selector(fetchFreeBusyInfosFrom:to:)]) {
-    [self errorWithFormat:@"invalid folder to run freebusy query on!"];
-    return NO;
-  }
-
-  infos = [groupCalendar fetchFreeBusyInfosFrom:[_task startDate]
-                         to:[_task due]];
-  [self debugWithFormat:@"  process: %d tasks", [infos count]];
-
-  ranges = [infos arrayByCreatingDateRangesFromObjectsWithStartDateKey:@"startDate"
-                  andEndDateKey:@"dueDate"];
-  ranges = [ranges arrayByCompactingContainedDateRanges];
-  [self debugWithFormat:@"  blocked ranges: %@", ranges];
-
-  return [ranges count] != 0 ? YES : NO;
+    text = [self labelForKey: [NSString stringWithFormat: @"repeat_%@", item]];
+
+  return text;
 }
 
-- (id <WOActionResults>) defaultAction
+- (NSArray *) statusList
 {
-  NSString *ical;
+  static NSArray *statusItems = nil;
 
-  /* load iCalendar file */
-  
-  // TODO: can't we use [clientObject contentAsString]?
-//   ical = [[self clientObject] valueForKey:@"iCalString"];
-  ical = [[self clientObject] contentAsString];
-  if ([ical length] == 0)
+  if (!statusItems)
     {
-      newTask = YES;
-      ical = [self iCalStringTemplate];
+      statusItems = [NSArray arrayWithObjects: @"NEEDS-ACTION",
+                             @"IN-PROCESS",
+                             @"COMPLETED",
+                             @"CANCELLED",
+                             nil];
+      [statusItems retain];
     }
-  else
-    newTask = NO;
 
-  [self setICalString:ical];
-  [self loadValuesFromTask: [self taskFromString: ical]];
-  
-//   if (![self canEditComponent]) {
-//     /* TODO: we need proper ACLs */
-//     return [self redirectToLocation: [self completeURIForMethod: @"../view"]];
-//   }
+  return statusItems;
+}
 
-  return self;
+- (NSString *) itemStatusText
+{
+  return [self labelForKey: [NSString stringWithFormat: @"status_%@", item]];
 }
 
-- (id <WOActionResults>) saveAction
+- (void) setItem: (NSString *) newItem
 {
-  iCalToDo *task;
-  iCalPerson *p;
-  id <WOActionResults> result;
-  NSString *content;
-  NSException *ex;
-
-  if (![self isWriteableClientObject]) {
-    /* return 400 == Bad Request */
-    return [NSException exceptionWithHTTPStatus:400
-                        reason: @"method cannot be invoked on "
-                                @"the specified object"];
-  }
-
-  task = [self taskFromString: [self iCalString]];
-  if (task == nil) {
-    NSString *s;
-    
-    s = [self labelForKey: @"Invalid iCal data!"];
-    [self setErrorText: s];
-
-    return self;
-  }
-
-  [self saveValuesIntoTask:task];
-  p = [task findParticipantWithEmail:[self emailForUser]];
-  if (p) {
-    [p setParticipationStatus:iCalPersonPartStatAccepted];
-  }
-
-  if ([self checkForConflicts]) {
-    if ([self containsConflict:task]) {
-      NSString *s;
-      
-      s = [self labelForKey:@"Conflicts found!"];
-      [self setErrorText:s];
-
-      return self;
-    }
-  }
-  content = [[task parent] versitString];
-//   [task release]; task = nil;
-  
-  if (content == nil) {
-    NSString *s;
-    
-    s = [self labelForKey: @"Could not create iCal data!"];
-    [self setErrorText: s];
-    return self;
-  }
-  
-  ex = [[self clientObject] saveContentString:content];
-  if (ex != nil) {
-    [self setErrorText:[ex reason]];
-    return self;
-  }
-
-  if ([[[[self context] request] formValueForKey: @"nojs"] intValue])
-    result = [self redirectToLocation: [self applicationPath]];
-  else
-    result = [self jsCloseWithRefreshMethod: @"refreshTasks()"];
+  item = newItem;
+}
 
-  return result;
+- (NSString *) item
+{
+  return item;
 }
 
-- (id) changeStatusAction
+- (NSString *) repeat
 {
-  iCalToDo *task;
-  SOGoTaskObject *taskObject;
-  NSString *content;
-  id ex;
-  int newStatus;
+  return @"";
+}
 
-  newStatus = [[self queryParameterForKey: @"status"] intValue];
+- (void) setRepeat: (NSString *) newRepeat
+{
+}
 
-  taskObject = [self clientObject];
-  task = (iCalToDo *) [taskObject component];
-  switch (newStatus)
-    {
-    case 1:
-      [task setCompleted: [NSCalendarDate calendarDate]];
-      break;
-    case 2:
-      [task setStatus: @"IN-PROCESS"];
-      break;
-    case 3:
-      [task setStatus: @"CANCELLED"];
-      break;
-    default:
-      [task setStatus: @"NEEDS-ACTION"];
-    }
+- (NSString *) status
+{
+  return status;
+}
 
-  content = [[task parent] versitString];
-  ex = [[self clientObject] saveContentString: content];
-  if (ex != nil) {
-    [self setErrorText:[ex reason]];
-    return self;
-  }
-  
-  return [self redirectToLocation: [self completeURIForMethod: @".."]];
+- (void) setStatus: (NSString *) newStatus
+{
+  status = newStatus;
 }
 
-- (id)acceptAction {
-  return [self acceptOrDeclineAction:YES];
+- (void) setStatusDate: (NSCalendarDate *) newStatusDate
+{
+  ASSIGN (statusDate, newStatusDate);
 }
 
-- (id)declineAction {
-  return [self acceptOrDeclineAction:NO];
+- (NSCalendarDate *) statusDate
+{
+  return statusDate;
 }
 
-- (NSString *) saveUrl
+- (BOOL) statusDateDisabled
 {
-  return [NSString stringWithFormat: @"%@/saveAsTask",
-                   [[self clientObject] baseURL]];
+  return ![status isEqualToString: @"COMPLETED"];
 }
 
-// TODO: add tentatively
+- (BOOL) statusPercentDisabled
+{
+  return ([status length] == 0
+         || [status isEqualToString: @"CANCELLED"]);
+}
+
+- (void) setStatusPercent: (NSString *) newStatusPercent
+{
+  ASSIGN (statusPercent, newStatusPercent);
+}
+
+- (NSString *) statusPercent
+{
+  return statusPercent;
+}
+
+/* actions */
+- (NSCalendarDate *) newStartDate
+{
+  NSCalendarDate *newStartDate, *now;
+  int hour;
+  NSTimeZone *timeZone;
+
+  timeZone = [[context activeUser] timeZone];
+
+  newStartDate = [self selectedDate];
+  if ([[self queryParameterForKey: @"hm"] length] == 0)
+    {
+      now = [NSCalendarDate calendarDate];
+      [now setTimeZone: timeZone];
+      if ([now isDateOnSameDay: newStartDate])
+        {
+          hour = [now hourOfDay];
+          if (hour < 8)
+            newStartDate = [now hour: 8 minute: 0];
+          else if (hour > 18)
+            newStartDate = [[now tomorrow] hour: 8 minute: 0];
+          else
+            newStartDate = now;
+        }
+      else
+        newStartDate = [newStartDate hour: 8 minute: 0];
+    }
+
+  return newStartDate;
+}
+
+- (id <WOActionResults>) defaultAction
+{
+  NSCalendarDate *startDate, *dueDate;
+  NSString *duration;
+  unsigned int minutes;
+
+  todo = (iCalToDo *) [[self clientObject] component: NO];
+  if (todo)
+    {
+      startDate = [todo startDate];
+      dueDate = [todo due];
+      hasStartDate = (startDate != nil);
+      hasDueDate = (dueDate != nil);
+      ASSIGN (status, [todo status]);
+      if ([status isEqualToString: @"COMPLETED"])
+       ASSIGN (statusDate, [todo completed]);
+      else
+       ASSIGN (statusDate, [self newStartDate]);
+      ASSIGN (statusPercent, [todo percentComplete]);
+    }
+  else
+    {
+      startDate = [self newStartDate];
+      duration = [self queryParameterForKey:@"dur"];
+      if ([duration length] > 0)
+       minutes = [duration intValue];
+      else
+       minutes = 60;
+      dueDate = [startDate dateByAddingYears: 0 months: 0 days: 0
+                          hours: 0 minutes: minutes seconds: 0];
+      hasStartDate = NO;
+      hasDueDate = NO;
+      ASSIGN (statusDate, [self newStartDate]);
+      ASSIGN (status, @"");
+      ASSIGN (statusPercent, @"");
+    }
+
+  ASSIGN (taskStartDate, startDate);
+  ASSIGN (taskDueDate, dueDate);
+
+  /* here comes the code for initializing repeat, reminder and isAllDay... */
 
-- (id)acceptOrDeclineAction:(BOOL)_accept {
-  // TODO: this should live in the SoObjects
-  NSException *ex;
-
-  if ((ex = [self validateObjectForStatusChange]) != nil)
-    return ex;
-  
-  ex = [[self clientObject] changeParticipationStatus:
-                              _accept ? @"ACCEPTED" : @"DECLINED"
-                            inContext:[self context]];
-  if (ex != nil) return ex;
-  
   return self;
-//   return [self redirectToLocation: [self completeURIForMethod:@"../view"]];
 }
 
-- (void) setHasStartDate: (BOOL) aBool
+- (id <WOActionResults>) newAction
 {
-  hasStartDate = aBool;
+  NSString *objectId, *method, *uri;
+  id <WOActionResults> result;
+  Class clientKlazz;
+
+  clientKlazz = [[self clientObject] class];
+  objectId = [clientKlazz globallyUniqueObjectId];
+  if ([objectId length] > 0)
+    {
+      method = [NSString stringWithFormat:@"%@/Calendar/%@/editAsTask",
+                         [self userFolderPath], objectId];
+      uri = [self completeHrefForMethod: method];
+      result = [self redirectToLocation: uri];
+    }
+  else
+    result = [NSException exceptionWithHTTPStatus: 500 /* Internal Error */
+                          reason: @"could not create a unique ID"];
+
+  return result;
 }
 
-- (BOOL) hasStartDate
+- (id <WOActionResults>) saveAction
 {
-  return (!newTask && [self taskStartDate] != nil);
+  SOGoTaskObject *clientObject;
+  NSString *iCalString;
+
+  clientObject = [self clientObject];
+  iCalString = [[clientObject calendar: NO] versitString];
+  [clientObject saveContentString: iCalString];
+
+  return [self jsCloseWithRefreshMethod: @"refreshTasks()"];
 }
 
-- (BOOL) startDateDisabled
+- (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
+                           inContext: (WOContext*) context
 {
-  return (![self hasStartDate]);
+  NSString *actionName;
+
+  actionName = [[request requestHandlerPath] lastPathComponent];
+
+  return ([[self clientObject] isKindOfClass: [SOGoTaskObject class]]
+         && [actionName hasPrefix: @"save"]);
 }
 
-- (void) setHasDueDate: (BOOL) aBool
+- (void) takeValuesFromRequest: (WORequest *) _rq
+                     inContext: (WOContext *) _ctx
 {
-  hasDueDate = aBool;
+  SOGoTaskObject *clientObject;
+
+  clientObject = [self clientObject];
+  todo = (iCalToDo *) [clientObject component: YES];
+
+  [super takeValuesFromRequest: _rq inContext: _ctx];
+
+  if (hasStartDate)
+    [todo setStartDate: taskStartDate];
+  else
+    [todo setStartDate: nil];
+
+  if (hasDueDate)
+    [todo setDue: taskDueDate];
+  else
+    [todo setDue: nil];
+
+  if ([status isEqualToString: @"COMPLETED"])
+    [todo setCompleted: statusDate];
+  else
+    [todo setCompleted: nil];
+  if ([status length] > 0)
+    {
+      [todo setStatus: status];
+      [todo setPercentComplete: statusPercent];
+    }
+  else
+    {
+      [todo setStatus: @""];
+      [todo setPercentComplete: @""];
+    }
 }
 
-- (BOOL) hasDueDate
+// TODO: add tentatively
+
+- (id) acceptOrDeclineAction: (BOOL) _accept
 {
-  return (!newTask && [self taskDueDate] != nil);
+  [[self clientObject] changeParticipationStatus:
+                         _accept ? @"ACCEPTED" : @"DECLINED"];
+
+  return self;
 }
 
-- (BOOL) dueDateDisabled
+- (id) acceptAction
 {
-  return (![self hasDueDate]);
+  return [self acceptOrDeclineAction: YES];
 }
 
-- (void) setDueDateDisabled: (BOOL) aBool
+- (id) declineAction
 {
+  return [self acceptOrDeclineAction: NO];
 }
 
-- (void) setStartDateDisabled: (BOOL) aBool
+- (id) changeStatusAction
 {
+  SOGoTaskObject *clientObject;
+  NSString *newStatus, *iCalString;
+
+  clientObject = [self clientObject];
+  todo = (iCalToDo *) [clientObject component: NO];
+  if (todo)
+    {
+      newStatus = [self queryParameterForKey: @"status"];
+      if ([newStatus intValue])
+       [todo setCompleted: [NSCalendarDate date]];
+      else
+       {
+         [todo setCompleted: nil];
+         [todo setPercentComplete: @"0"];
+         [todo setStatus: @"IN-PROCESS"];
+       }
+
+      iCalString = [[clientObject calendar: NO] versitString];
+      [clientObject saveContentString: iCalString];
+    }
+
+  return self;
 }
 
-@end /* UIxTaskEditor */
+@end