AD071F6606CE66DF00A9EEF4 /* README */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 8; lastKnownFileType = text; path = README; sourceTree = "<group>"; tabWidth = 8; };
AD0A0ACC07A8093400D3B8EF /* UIxMailWindowCloser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIxMailWindowCloser.m; sourceTree = "<group>"; };
AD152B6F06AC159A002375D2 /* ChangeLog */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 8; lastKnownFileType = text; path = ChangeLog; sourceTree = "<group>"; tabWidth = 8; usesTabs = 1; };
- AD273D4D077315640064794B /* UIxCalParticipationStatusView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIxCalParticipationStatusView.m; sourceTree = "<group>"; };
+ AD273D4D077315640064794B /* UIxCalParticipationStatusView.m */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = UIxCalParticipationStatusView.m; sourceTree = "<group>"; tabWidth = 2; };
AD2C74A3071A9FF70087E027 /* README */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
AD2C74A5071A9FF70087E027 /* UIxEnvelopeAddressFormatter.m */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = UIxEnvelopeAddressFormatter.m; sourceTree = "<group>"; };
AD2C74A6071A9FF70087E027 /* UIxMailAccountsView.m */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = UIxMailAccountsView.m; sourceTree = "<group>"; };
2005-07-14 Marcus Mueller <znek@mulle-kybernetik.com>
+ * v0.9.42
+
+ * calendar.css: further refined new css
+
+ * v0.9.41
+
* calendar.css, uix.css: added homepagefont and added 'title' class
- to use in the scheduler overview (v0.9.41)
+ to use in the scheduler overview
2005-07-13 Marcus Mueller <znek@mulle-kybernetik.com>
# Version file
-SUBMINOR_VERSION:=41
+SUBMINOR_VERSION:=42
# v0.9.28 requires NGExtensions v4.5.136
font-size: 10pt;
}
-.title {
+.titlefont {
font-size: 12pt;
font-weight: bold;
+}
+
+.titleheader {
background-color: #d8d8d0;
}
+.buttonheader {
+ text-align: right;
+}
+
th.schedoverview_title {
font-size: 10pt;
font-weight: bold;
+2005-07-14 Marcus Mueller <znek@mulle-kybernetik.com>
+
+ * v0.9.133
+
+ * UIxAppointmentView.m: supports accept/decline from participants
+ tab now
+
+ * UIxAppointmentEditor.m: fixed redirect url after accept/decline
+
+ * UIxCalParticipationStatusView.m: added accessor for partStat, so
+ partStat isn't accidentaly lost
+
+ * UIxCalScheduleOverview.m: is able to suppress rendering of
+ rejected and accepted foreign appointments now based on formValue
+
+ * English.lproj/Localizable.strings: new labels for
+ UIxCalScheduleOverview
+
2005-07-14 Helge Hess <helge.hess@opengroupware.org>
* UIxAppointmentView.m: fixed a small memory leak when creating the
2005-07-14 Marcus Mueller <znek@mulle-kybernetik.com>
+ * v0.9.131
+
* product.plist: removed 'schedule' method from SOGoAppointmentFolder
- (v0.9.131)
+
+ * v0.9.130
* UIxCalView.m: removed resourcePath stuff as this isn't used
- anywhere anymore (and it shouldn't) (v0.9.130)
+ anywhere anymore (and it shouldn't)
2005-07-13 Marcus Mueller <znek@mulle-kybernetik.com>
"accept" = "Accept";
"decline" = "Decline";
"more participants" = "more participants";
+"Hide already accepted and rejected appointments" = "Hide already accepted and rejected appointments";
+"Show already accepted and rejected appointments" = "Show already accepted and rejected appointments";
/* Appointments */
reason:[ex reason]];
}
- return [self redirectToLocation:[self _completeURIForMethod:@".."]];
+ return [self redirectToLocation:[self _completeURIForMethod:@"../view"]];
}
@end /* UIxAppointmentEditor */
@interface UIxAppointmentView : UIxComponent
{
- NSString *tabSelection;
id appointment;
id attendee;
SOGoDateFormatter *dateFormatter;
#include "UIxAppointmentView.h"
#include <NGiCal/NGiCal.h>
#include <SOGo/SOGoAppointment.h>
+#include <SOGo/WOContext+Agenor.h>
#include <Appointments/SOGoAppointmentObject.h>
#include <SOGoUI/SOGoDateFormatter.h>
#include "UIxComponent+Agenor.h"
#include "common.h"
+@interface UIxAppointmentView (PrivateAPI)
+- (BOOL)isAttendeeActiveUser;
+@end
+
@implementation UIxAppointmentView
- (void)dealloc {
return self->attendee;
}
+- (BOOL)isAttendeeActiveUser {
+ NSString *email, *attEmail;
+
+ email = [[[self context] activeUser] email];
+ attEmail = [[self attendee] rfc822Email];
+ return [email isEqualToString:attEmail];
+}
+- (BOOL)showAcceptButton {
+ return [[self attendee] participationStatus] != iCalPersonPartStatAccepted;
+}
+- (BOOL)showRejectButton {
+ return [[self attendee] participationStatus] != iCalPersonPartStatDeclined;
+}
+- (NSString *)attendeeStatusColspan {
+ return [self isAttendeeActiveUser] ? @"1" : @"2";
+}
+
- (void)setItem:(id)_item {
ASSIGN(self->item, _item);
}
*/
// $Id$
-
#include <NGObjWeb/NGObjWeb.h>
-
@interface UIxCalParticipationStatusView : WOComponent
{
- int partStat;
+ int partStat;
}
- (NSString *)participationStatus;
@implementation UIxCalParticipationStatusView
- (void)setPartStat:(id)_partStat {
- self->partStat = [_partStat intValue];
+ self->partStat = [_partStat intValue];
+}
+- (int)partStat {
+ return self->partStat;
}
- (NSString *)participationStatus {
- switch (self->partStat) {
- case iCalPersonPartStatNeedsAction:
- return @"NEEDS-ACTION";
- case iCalPersonPartStatAccepted:
- return @"ACCEPTED";
- case iCalPersonPartStatDeclined:
- return @"DECLINED";
- case iCalPersonPartStatTentative:
- return @"TENTATIVE";
- case iCalPersonPartStatDelegated:
- return @"DELEGATED";
- }
- return @"OTHER";
+ switch (self->partStat) {
+ case iCalPersonPartStatNeedsAction:
+ return @"NEEDS-ACTION";
+ case iCalPersonPartStatAccepted:
+ return @"ACCEPTED";
+ case iCalPersonPartStatDeclined:
+ return @"DECLINED";
+ case iCalPersonPartStatTentative:
+ return @"TENTATIVE";
+ case iCalPersonPartStatDelegated:
+ return @"DELEGATED";
+ }
+ return @"OTHER";
}
- (NSString *)participationStatusLabel {
- return [NSString stringWithFormat:@"partStat_%@",
- [self participationStatus]];
+ return [NSString stringWithFormat:@"partStat_%@",
+ [self participationStatus]];
}
@end
- (unsigned)truncatedParticipantsCount;
- (BOOL)didTruncateParticipants;
+- (NSString *)getUserPartStateFromApt:(id)_apt;
+
+- (BOOL)shouldIgnoreRejectedAppointments;
+- (BOOL)shouldIgnoreAcceptedAppointments;
+- (BOOL)shouldShowRejectedAndAcceptedAppointments;
+
@end
#include <NGObjWeb/SoComponent.h>
}
- (BOOL)hasUserAppointments {
+ // NOTE: this has been disabled for Agenor 0.8 on client's request
+#if 1
+ return NO;
+#else
return [[self userAppointments] count] > 0;
+#endif
}
- (BOOL)hasForeignAppointments {
return [[self foreignAppointments] count] > 0;
return self->userParticipationStatus;
}
+- (BOOL)shouldIgnoreRejectedAppointments {
+ return ![self shouldShowRejectedAndAcceptedAppointments];
+}
+
+- (BOOL)shouldIgnoreAcceptedAppointments {
+ return ![self shouldShowRejectedAndAcceptedAppointments];
+}
+
+- (BOOL)shouldShowRejectedAndAcceptedAppointments {
+ NSString *value;
+
+ value = [[[self context] request] formValueForKey:@"dr"];
+ if (!value) return NO;
+ return [value boolValue];
+}
+
+- (NSString *)toggleShowHideAptsQueryParameter {
+ BOOL shouldShow;
+
+ shouldShow = [self shouldShowRejectedAndAcceptedAppointments];
+ return shouldShow ? @"0" : @"1";
+}
+
+- (NSString *)toggleShowHideAptsText {
+ if ([self shouldShowRejectedAndAcceptedAppointments])
+ return @"Hide already accepted and rejected appointments";
+ return @"Show already accepted and rejected appointments";
+}
+
+
+- (NSString *)getUserPartStateFromApt:(id)_apt {
+ NSString *email;
+ NSArray *ps, *pms;
+ unsigned idx;
+
+ email = [self emailForUser];
+ pms = [[_apt valueForKey:@"partmails"]
+ componentsSeparatedByString:@"\n"];
+ idx = [pms indexOfObject:email];
+ if (idx == NSNotFound) return nil;
+ ps = [[_apt valueForKey:@"partstates"]
+ componentsSeparatedByString:@"\n"];
+ return [ps objectAtIndex:idx];
+}
+
/* fetching */
apt = [apts objectAtIndex:i];
orgEmail = [apt objectForKey:@"orgmail"];
- if (orgEmail && [orgEmail isEqualToString:userEmail])
+ if (orgEmail && [orgEmail isEqualToString:userEmail]) {
[self->userApts addObject:apt];
- else
- [self->foreignApts addObject:apt];
+ }
+ else {
+ BOOL shouldAdd = YES;
+
+ if ([self shouldIgnoreAcceptedAppointments] ||
+ [self shouldIgnoreRejectedAppointments])
+ {
+ NSString *userPartStat;
+
+ userPartStat = [self getUserPartStateFromApt:apt];
+ if (userPartStat) {
+ if ([self shouldIgnoreAcceptedAppointments] &&
+ [userPartStat isEqualToString:@"1"])
+ shouldAdd = NO;
+ else if ([self shouldIgnoreRejectedAppointments] &&
+ [userPartStat isEqualToString:@"2"])
+ shouldAdd = NO;
+ }
+ }
+ if (shouldAdd)
+ [self->foreignApts addObject:apt];
+ }
}
[self->userApts sortUsingKeyOrderArray:orders];
[self->foreignApts sortUsingKeyOrderArray:orders];
# Version file
-SUBMINOR_VERSION:=132
+SUBMINOR_VERSION:=133
# v0.9.123 requires Appointments v0.9.35
# v0.9.123 requires SOGoUI v0.9.24
+2005-07-14 Marcus Mueller <znek@mulle-kybernetik.com>
+
+ * UIxCalScheduleOverview.wox: removed functionality for v0.8 on
+ client's request
+
+ * UIxAppointmentView.wox: added accept/decline functionality in
+ participants tab
+
2005-07-14 Helge Hess <helge.hess@opengroupware.org>
* UIxMailAccountView.wox: directly access the clientObject to get share
<td align="left" bgcolor="#E8E8E0" class="aptview_title">
<var:string label:value="Email" />
</td>
- <td align="left" bgcolor="#E8E8E0" class="aptview_title">
+ <td align="left"
+ bgcolor="#E8E8E0"
+ class="aptview_title"
+ colspan="2"
+ >
<var:string label:value="Status" />
</td>
</tr>
<a var:href="attendee.email"
><var:string value="attendee.rfc822Email" /></a>
</td>
- <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+ <td align="left"
+ bgcolor="#FFFFF0"
+ class="aptview_text"
+ var:colspan="attendeeStatusColspan"
+ >
<var:component className="UIxCalParticipationStatusView"
partStat="attendee.participationStatus"
/>
</td>
+ <var:if condition="isAttendeeActiveUser">
+ <td align="left"
+ bgcolor="#FFFFF0"
+ class="button_auto_env"
+ >
+ <var:if condition="showAcceptButton">
+ <a href="accept"
+ class="button_auto"
+ _tab="participants"
+ ><var:string label:value="accept" /></a>
+ </var:if>
+ <var:if condition="showRejectButton">
+ <a href="decline"
+ class="button_auto"
+ _tab="participants"
+ ><var:string label:value="decline" /></a>
+ </var:if>
+ </td>
+ </var:if>
</tr>
</var:foreach>
</table>
class="schedoverview"
>
<tr>
- <th colspan="5" class="schedoverview title">
+ <th colspan="5" class="schedoverview titlefont titleheader">
<var:string label:value="Schedule"/>
<var:string value="startDate" label:dateformat="dayLabelFormat" /> -
<var:string value="endDate" label:dateformat="dayLabelFormat" />
</th>
+ <!-- TODO: maybe enable this at a later stage
+ <th colspan="2"
+ class="titleheader button_auto_env defaultfont buttonheader">
+ <a var:href="ownMethodName"
+ var:queryDictionary="context.request.formValues"
+ var:_dr="toggleShowHideAptsQueryParameter"
+ class="button_auto"
+ ><var:string label:value="$toggleShowHideAptsText"
+ /></a>
+ </th>
+ -->
</tr>
<var:if condition="hasAnyAppointments" const:negate="YES">
<tr>
<td><var:entity const:name="nbsp" /></td>
</tr>
</var:if>
+ <!-- ZNeK: removed for Agenor 0.8 on client's request
<tr>
- <!-- meetings proposed to user -->
<th colspan="5" class="schedoverview_title">
<var:string label:value="Meetings proposed to you" />
</th>
</tr>
+ -->
<tr>
<th class="schedoverview"
><var:string label:value="Start date" /></th>
<var:if-key const:key="participantIndex"
value="userIndex"
>
+ <!-- TODO: exchange with inline updates -->
<var:if-key const:key="userParticipationStatus"
const:value="1"
const:negate="YES"
class="button_auto"
><var:string label:value="accept" /></a>
</var:if-key>
+ <!-- TODO: exchange with inline updates -->
<var:if-key const:key="userParticipationStatus"
const:value="2"
const:negate="YES"