Monotone-Parent: 2b628a62ac49757d2bbeda1275fc38d69079752a
Monotone-Revision: 59d4ff7e6c2fe24e74adbe4891af30ece4f5e858 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2011-11-14T03:26:50 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
97dcdcb97a
commit
a137e1679e
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
2011-11-13 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreContactsMessage.m (-getPrBody:inMemCtx:):
|
||||
same as below.
|
||||
|
||||
* OpenChange/MAPIStoreAppointmentWrapper.m (-getPrBody:inMemCtx:):
|
||||
removed parsing hack since things are now done properly from
|
||||
NGCards.
|
||||
|
||||
* Tests/Unit/TestVersit.m (-test_rendering, -test_parsing):
|
||||
adapted to new NGCards data structure and improved to test further
|
||||
important use cases.
|
||||
|
||||
2011-11-10 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* Tests/Unit/TestVersit.m: new test module for versit parsing and
|
||||
|
|
|
@ -39,27 +39,19 @@
|
|||
{
|
||||
NSMutableDictionary *fields;
|
||||
NSArray *values;
|
||||
CardElement *adr;
|
||||
CardElement *element;
|
||||
NSString *value;
|
||||
unsigned int max;
|
||||
|
||||
fields = [NSMutableDictionary dictionaryWithCapacity: 16];
|
||||
|
||||
value = [vCard fn];
|
||||
if (value)
|
||||
[fields setObject: value forKey: @"c_cn"];
|
||||
values = [vCard n];
|
||||
if (values)
|
||||
{
|
||||
max = [values count];
|
||||
if (max > 0)
|
||||
{
|
||||
[fields setObject: [values objectAtIndex: 0] forKey: @"c_sn"];
|
||||
if (max > 1)
|
||||
[fields setObject: [values objectAtIndex: 1]
|
||||
forKey: @"c_givenName"];
|
||||
}
|
||||
}
|
||||
element = [vCard n];
|
||||
[fields setObject: [element flattenedValueAtIndex: 0 forKey: @""]
|
||||
forKey: @"c_sn"];
|
||||
[fields setObject: [element flattenedValueAtIndex: 1 forKey: @""]
|
||||
forKey: @"c_givenName"];
|
||||
value = [vCard preferredTel];
|
||||
if (value)
|
||||
[fields setObject: value forKey: @"c_telephoneNumber"];
|
||||
|
@ -67,18 +59,17 @@
|
|||
if (![value isNotNull])
|
||||
value = @"";
|
||||
[fields setObject: value forKey: @"c_mail"];
|
||||
values = [vCard org];
|
||||
max = [values count];
|
||||
if (max > 0)
|
||||
{
|
||||
[fields setObject: [values objectAtIndex: 0] forKey: @"c_o"];
|
||||
if (max > 1)
|
||||
[fields setObject: [values objectAtIndex: 1] forKey: @"c_ou"];
|
||||
}
|
||||
adr = [vCard preferredAdr];
|
||||
if (adr)
|
||||
[fields setObject: [adr value: 3] forKey: @"c_l"];
|
||||
value = [[vCard uniqueChildWithTag: @"X-AIM"] value: 0];
|
||||
element = [vCard org];
|
||||
[fields setObject: [element flattenedValueAtIndex: 0 forKey: @""]
|
||||
forKey: @"c_o"];
|
||||
[fields setObject: [element flattenedValueAtIndex: 1 forKey: @""]
|
||||
forKey: @"c_ou"];
|
||||
element = [vCard preferredAdr];
|
||||
if (element && ![element isVoid])
|
||||
[fields setObject: [element flattenedValueAtIndex: 3
|
||||
forKey: @""]
|
||||
forKey: @"c_l"];
|
||||
value = [[vCard uniqueChildWithTag: @"X-AIM"] flattenedValuesForKey: @""];
|
||||
[fields setObject: value forKey: @"c_screenname"];
|
||||
values = [[vCard categories] trimmedComponents];
|
||||
if ([values count] > 0)
|
||||
|
|
|
@ -1026,17 +1026,11 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
{
|
||||
int rc = MAPISTORE_SUCCESS;
|
||||
NSString *stringValue;
|
||||
NSArray *values;
|
||||
|
||||
/* FIXME: there is a confusion in NGCards around "comment" and "description" */
|
||||
stringValue = [event comment];
|
||||
if ([stringValue length] > 0)
|
||||
{
|
||||
/* FIXME: this is a temporary hack: we unescape things although NGVCards
|
||||
should already have done it at this stage... */
|
||||
values = [stringValue asCardAttributeValues];
|
||||
*data = [[values objectAtIndex: 0] asUnicodeInMemCtx: memCtx];
|
||||
}
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
else
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
|
||||
|
@ -1411,7 +1405,8 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
|||
{
|
||||
startDate = [event startDate];
|
||||
relation = [[trigger relationType] lowercaseString];
|
||||
interval = [[trigger value] durationAsTimeInterval];
|
||||
interval = [[trigger flattenedValuesForKey: @""]
|
||||
durationAsTimeInterval];
|
||||
if ([relation isEqualToString: @"end"])
|
||||
relationDate = [event endDate];
|
||||
else
|
||||
|
|
|
@ -607,7 +607,9 @@
|
|||
[alarm setAction: @"DISPLAY"];
|
||||
trigger = [iCalTrigger elementWithTag: @"trigger"];
|
||||
[trigger setValueType: @"DURATION"];
|
||||
[trigger setValue: [NSString stringWithFormat: @"-PT%@M", delta]];
|
||||
[trigger
|
||||
setSingleValue: [NSString stringWithFormat: @"-PT%@M", delta]
|
||||
forKey: @""];
|
||||
[alarm setTrigger: trigger];
|
||||
[newEvent addToAlarms: alarm];
|
||||
[alarm release];
|
||||
|
|
|
@ -142,7 +142,8 @@ extern NSTimeZone *utcTZ;
|
|||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
if (!photoData)
|
||||
ASSIGN (photoData, [[photo value: 0] dataByDecodingBase64]);
|
||||
ASSIGN (photoData,
|
||||
[[photo flattenedValuesForKey: @""] dataByDecodingBase64]);
|
||||
|
||||
*data = [photoData asBinaryInMemCtx: memCtx];
|
||||
|
||||
|
@ -153,7 +154,8 @@ extern NSTimeZone *utcTZ;
|
|||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
if (!photoData)
|
||||
ASSIGN (photoData, [[photo value: 0] dataByDecodingBase64]);
|
||||
ASSIGN (photoData,
|
||||
[[photo flattenedValuesForKey: @""] dataByDecodingBase64]);
|
||||
|
||||
*data = MAPILongValue (memCtx, [photoData length]);
|
||||
|
||||
|
|
|
@ -149,18 +149,11 @@
|
|||
- (int) getPrCompanyName: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
NSArray *values;
|
||||
NSString *stringValue;
|
||||
CardElement *org;
|
||||
|
||||
values = [[sogoObject vCard] org];
|
||||
stringValue = nil;
|
||||
|
||||
if ([values count] > 0)
|
||||
stringValue = [values objectAtIndex: 0];
|
||||
else
|
||||
stringValue = @"";
|
||||
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
org = [[sogoObject vCard] org];
|
||||
*data = [[org flattenedValueAtIndex: 0 forKey: @""]
|
||||
asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -168,18 +161,11 @@
|
|||
- (int) getPrDepartmentName: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
NSArray *values;
|
||||
NSString *stringValue;
|
||||
CardElement *org;
|
||||
|
||||
values = [[sogoObject vCard] org];
|
||||
stringValue = nil;
|
||||
|
||||
if ([values count] > 1)
|
||||
stringValue = [values objectAtIndex: 1];
|
||||
else
|
||||
stringValue = @"";
|
||||
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
org = [[sogoObject vCard] org];
|
||||
*data = [[org flattenedValueAtIndex: 1 forKey: @""]
|
||||
asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -314,7 +300,7 @@
|
|||
max = [emails count];
|
||||
for (count = 0; !stringValue && count < max; count++)
|
||||
{
|
||||
email = [[emails objectAtIndex: count] value: 0];
|
||||
email = [[emails objectAtIndex: count] flattenedValuesForKey: @""];
|
||||
|
||||
if ([email caseInsensitiveCompare: [card preferredEMail]] != NSOrderedSame)
|
||||
stringValue = email;
|
||||
|
@ -339,16 +325,10 @@
|
|||
{
|
||||
int rc = MAPISTORE_SUCCESS;
|
||||
NSString *stringValue;
|
||||
NSArray *values;
|
||||
|
||||
stringValue = [[sogoObject vCard] note];
|
||||
if ([stringValue length] > 0)
|
||||
{
|
||||
/* FIXME: this is a temporary hack: we unescape things although NGVCards
|
||||
should already have done it at this stage... */
|
||||
values = [stringValue asCardAttributeValues];
|
||||
*data = [[values objectAtIndex: 0] asUnicodeInMemCtx: memCtx];
|
||||
}
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
else
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
|
||||
|
@ -380,7 +360,7 @@
|
|||
ce = [elements objectAtIndex: count];
|
||||
if (!aTypeToExclude
|
||||
|| ![ce hasAttribute: @"type" havingValue: aTypeToExclude])
|
||||
stringValue = [ce value: pos];
|
||||
stringValue = [ce flattenedValueAtIndex: pos forKey: @""];
|
||||
}
|
||||
|
||||
if (!stringValue)
|
||||
|
@ -471,7 +451,7 @@
|
|||
NSString *stringValue;
|
||||
|
||||
stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-aim"]
|
||||
value: 0];
|
||||
flattenedValuesForKey: @""];
|
||||
if (!stringValue)
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
|
@ -705,7 +685,9 @@
|
|||
{
|
||||
NSString *stringValue;
|
||||
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] value: 0];
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"]
|
||||
flattenedValueAtIndex: 0
|
||||
forKey: @""];
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
|
@ -716,7 +698,9 @@
|
|||
{
|
||||
NSString *stringValue;
|
||||
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] value: 1];
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"]
|
||||
flattenedValueAtIndex: 1
|
||||
forKey: @""];
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
|
@ -727,7 +711,9 @@
|
|||
{
|
||||
NSString *stringValue;
|
||||
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] value: 2];
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"]
|
||||
flattenedValueAtIndex: 2
|
||||
forKey: @""];
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
|
@ -738,7 +724,9 @@
|
|||
{
|
||||
NSString *stringValue;
|
||||
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] value: 3];
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"]
|
||||
flattenedValueAtIndex: 3
|
||||
forKey: @""];
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
|
@ -749,7 +737,9 @@
|
|||
{
|
||||
NSString *stringValue;
|
||||
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] value: 4];
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"]
|
||||
flattenedValueAtIndex: 4
|
||||
forKey: @""];
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
|
@ -844,9 +834,9 @@
|
|||
to: photoType];
|
||||
[photo setValue: 0 ofAttribute: @"encoding"
|
||||
to: @"b"];
|
||||
[photo setValue: 0
|
||||
to: [content stringByReplacingString: @"\n"
|
||||
withString: @""]];
|
||||
[photo setSingleValue: [content stringByReplacingString: @"\n"
|
||||
withString: @""]
|
||||
atIndex: 0 forKey: @""];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -893,7 +883,7 @@
|
|||
if (value)
|
||||
{
|
||||
if ([elements count] > 0)
|
||||
[[elements objectAtIndex: 0] setValue: 0 to: value];
|
||||
[[elements objectAtIndex: 0] setSingleValue: value forKey: @""];
|
||||
else
|
||||
[newCard addEmail: value
|
||||
types: [NSArray arrayWithObject: @"pref"]];
|
||||
|
@ -902,7 +892,7 @@
|
|||
if (value)
|
||||
{
|
||||
if ([elements count] > 1)
|
||||
[[elements objectAtIndex: 1] setValue: 0 to: value];
|
||||
[[elements objectAtIndex: 1] setSingleValue: value forKey: @""];
|
||||
else
|
||||
[newCard addEmail: value types: nil];
|
||||
}
|
||||
|
@ -910,7 +900,7 @@
|
|||
if (value)
|
||||
{
|
||||
if ([elements count] > 2)
|
||||
[[elements objectAtIndex: 2] setValue: 0 to: value];
|
||||
[[elements objectAtIndex: 2] setSingleValue: value forKey: @""];
|
||||
else
|
||||
[newCard addEmail: value types: nil];
|
||||
}
|
||||
|
@ -950,7 +940,7 @@
|
|||
[element addAttribute: @"type"
|
||||
value: @"pref"];
|
||||
}
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value forKey: @""];
|
||||
}
|
||||
|
||||
elements = [newCard childrenWithTag: @"adr"
|
||||
|
@ -968,22 +958,22 @@
|
|||
[element addAttribute: @"type" value: @"pref"];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressPostOfficeBox)];
|
||||
if (value)
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value atIndex: 0 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressStreet)];
|
||||
if (value)
|
||||
[element setValue: 2 to: value];
|
||||
[element setSingleValue: value atIndex: 2 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressCity)];
|
||||
if (value)
|
||||
[element setValue: 3 to: value];
|
||||
[element setSingleValue: value atIndex: 3 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressState)];
|
||||
if (value)
|
||||
[element setValue: 4 to: value];
|
||||
[element setSingleValue: value atIndex: 4 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressPostalCode)];
|
||||
if (value)
|
||||
[element setValue: 5 to: value];
|
||||
[element setSingleValue: value atIndex: 5 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressCountry)];
|
||||
if (value)
|
||||
[element setValue: 6 to: value];
|
||||
[element setSingleValue: value atIndex: 6 forKey: @""];
|
||||
|
||||
//
|
||||
// home postal addresses handling
|
||||
|
@ -1009,7 +999,7 @@
|
|||
[element addAttribute: @"type"
|
||||
value: @"pref"];
|
||||
}
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value forKey: @""];
|
||||
}
|
||||
|
||||
elements = [newCard childrenWithTag: @"adr"
|
||||
|
@ -1028,22 +1018,22 @@
|
|||
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_POST_OFFICE_BOX_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value atIndex: 0 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey( PR_HOME_ADDRESS_STREET_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 2 to: value];
|
||||
[element setSingleValue: value atIndex: 2 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_CITY_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 3 to: value];
|
||||
[element setSingleValue: value atIndex: 3 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_STATE_OR_PROVINCE_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 4 to: value];
|
||||
[element setSingleValue: value atIndex: 4 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_POSTAL_CODE_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 5 to: value];
|
||||
[element setSingleValue: value atIndex: 5 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_COUNTRY_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 6 to: value];
|
||||
[element setSingleValue: value atIndex: 6 forKey: @""];
|
||||
|
||||
|
||||
//
|
||||
|
@ -1052,27 +1042,27 @@
|
|||
element = [self _elementWithTag: @"tel" ofType: @"work" forCard: newCard];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_OFFICE_TELEPHONE_NUMBER_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value forKey: @""];
|
||||
|
||||
element = [self _elementWithTag: @"tel" ofType: @"home" forCard: newCard];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_HOME_TELEPHONE_NUMBER_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value forKey: @""];
|
||||
|
||||
element = [self _elementWithTag: @"tel" ofType: @"fax" forCard: newCard];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_BUSINESS_FAX_NUMBER_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value forKey: @""];
|
||||
|
||||
element = [self _elementWithTag: @"tel" ofType: @"pager" forCard: newCard];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_PAGER_TELEPHONE_NUMBER_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value forKey: @""];
|
||||
|
||||
element = [self _elementWithTag: @"tel" ofType: @"cell" forCard: newCard];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_MOBILE_TELEPHONE_NUMBER_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value forKey: @""];
|
||||
|
||||
|
||||
//
|
||||
|
@ -1100,15 +1090,14 @@
|
|||
if (value)
|
||||
{
|
||||
[[self _elementWithTag: @"url" ofType: @"work" forCard: newCard]
|
||||
setValue: 0 to: value];
|
||||
setSingleValue: value forKey: @""];
|
||||
}
|
||||
|
||||
value = [properties objectForKey: MAPIPropertyKey(PidLidInstantMessagingAddress)];
|
||||
if (value)
|
||||
{
|
||||
[[newCard uniqueChildWithTag: @"x-aim"]
|
||||
setValue: 0
|
||||
to: value];
|
||||
setSingleValue: value forKey: @""];
|
||||
}
|
||||
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_BIRTHDAY)];
|
||||
|
|
|
@ -96,7 +96,7 @@
|
|||
[rule setFrequency: iCalRecurrenceFrequenceYearly];
|
||||
[rule setRepeatInterval: rp->Period / 12];
|
||||
month = [NSString stringWithFormat: @"%d", [startDate monthOfYear]];
|
||||
[rule setNamedValue: @"bymonth" to: month];
|
||||
[rule setSingleValue: month forKey: @"bymonth"];
|
||||
}
|
||||
else
|
||||
[self errorWithFormat:
|
||||
|
@ -116,7 +116,7 @@
|
|||
else
|
||||
monthDay = [NSString stringWithFormat: @"%d",
|
||||
rp->PatternTypeSpecific.MonthRecurrencePattern.N];
|
||||
[rule setNamedValue: @"bymonthday" to: monthDay];
|
||||
[rule setSingleValue: monthDay forKey: @"bymonthday"];
|
||||
}
|
||||
else if ((rp->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern
|
||||
== 0x3e) /* Nth week day */
|
||||
|
@ -139,8 +139,9 @@
|
|||
else
|
||||
bySetPos = rp->PatternTypeSpecific.MonthRecurrencePattern.N;
|
||||
|
||||
[rule setNamedValue: @"bysetpos"
|
||||
to: [NSString stringWithFormat: @"%d", bySetPos]];
|
||||
[rule
|
||||
setSingleValue: [NSString stringWithFormat: @"%d", bySetPos]
|
||||
forKey: @"bysetpos"];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -167,9 +168,10 @@
|
|||
|| (rp->PatternType & 4) == 4)
|
||||
{
|
||||
/* MonthEnd, HjMonth and HjMonthEnd */
|
||||
[rule setNamedValue: @"bymonthday"
|
||||
to: [NSString stringWithFormat: @"%d",
|
||||
rp->PatternTypeSpecific.Day]];
|
||||
[rule
|
||||
setSingleValue: [NSString stringWithFormat: @"%d",
|
||||
rp->PatternTypeSpecific.Day]
|
||||
forKey: @"bymonthday"];
|
||||
}
|
||||
else
|
||||
[self errorWithFormat: @"invalid value for PatternType: %.4x",
|
||||
|
@ -348,7 +350,7 @@
|
|||
if (mask)
|
||||
{
|
||||
rp->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern = mask;
|
||||
bySetPos = [self namedValue: @"bysetpos"];
|
||||
bySetPos = [self flattenedValuesForKey: @"bysetpos"];
|
||||
if ([bySetPos length])
|
||||
rp->PatternTypeSpecific.MonthRecurrencePattern.N
|
||||
= ([bySetPos hasPrefix: @"-"]
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
@interface CardElement : NSObject <NSCopying, NSMutableCopying>
|
||||
{
|
||||
NSString *tag;
|
||||
NSMutableArray *values;
|
||||
NSMutableDictionary *values;
|
||||
NSMutableDictionary *attributes;
|
||||
NSString *group;
|
||||
CardGroup *parent;
|
||||
|
@ -51,31 +51,44 @@
|
|||
singleType: (NSString *) aType
|
||||
value: (NSString *) aValue;
|
||||
|
||||
+ (id) elementWithTag: (NSString *) aTag
|
||||
attributes: (NSDictionary *) someAttributes
|
||||
values: (NSArray *) someValues;
|
||||
|
||||
- (void) setParent: (CardGroup *) aParent;
|
||||
- (id) parent;
|
||||
|
||||
- (void) setTag: (NSString *) aTag;
|
||||
- (NSString *) tag;
|
||||
|
||||
- (void) setGroup: (NSString *) aGroup;
|
||||
- (NSString *) group;
|
||||
|
||||
- (void) addValue: (NSString *) aValue;
|
||||
- (void) addValues: (NSArray *) someValues;
|
||||
- (BOOL) isVoid;
|
||||
|
||||
- (void) setValue: (unsigned int) anInt
|
||||
to: (NSString *) aValue;
|
||||
- (NSString *) value: (unsigned int) anInt;
|
||||
- (void) setValues: (NSMutableDictionary *) newValues;
|
||||
- (NSMutableDictionary *) values;
|
||||
|
||||
- (void) setNamedValue: (NSString *) aValueName
|
||||
to: (NSString *) aValue;
|
||||
- (NSString *) namedValue: (NSString *) aValueName;
|
||||
/* ELEM:...;value1,value2,...;... */
|
||||
- (void) setValues: (NSMutableArray *) newValues
|
||||
atIndex: (NSUInteger) idx
|
||||
forKey: (NSString *) key;
|
||||
|
||||
- (void) setCommaSeparatedValues: (NSArray *) values;
|
||||
/* ELEM:...;value;... */
|
||||
- (void) setSingleValue: (NSString *) newValue
|
||||
atIndex: (NSUInteger) idx
|
||||
forKey: (NSString *) key;
|
||||
/* ELEM:value */
|
||||
- (void) setSingleValue: (NSString *) newValue
|
||||
forKey: (NSString *) key;
|
||||
|
||||
- (NSMutableArray *) valuesForKey: (NSString *) key;
|
||||
- (NSMutableArray *) valuesAtIndex: (NSUInteger) idx
|
||||
forKey: (NSString *) key;
|
||||
|
||||
/* This joins all subvalues with "," and ordered values with ";". Handy for
|
||||
retrieving data from clients which don't escape their data properly. */
|
||||
- (NSString *) flattenedValuesForKey: (NSString *) key;
|
||||
- (NSString *) flattenedValueAtIndex: (NSUInteger) idx
|
||||
forKey: (NSString *) key;
|
||||
|
||||
/* attribute values */
|
||||
- (void) setValue: (unsigned int) anInt
|
||||
ofAttribute: (NSString *) anAttribute
|
||||
to: (NSString *) aValue;
|
||||
|
@ -87,17 +100,11 @@
|
|||
- (void) addAttributes: (NSDictionary *) someAttributes;
|
||||
- (void) removeValue: (NSString *) aValue
|
||||
fromAttribute: (NSString *) anAttribute;
|
||||
|
||||
- (void) addType: (NSString *) aType;
|
||||
|
||||
- (NSString *) tag;
|
||||
- (void) setValues: (NSArray *) newValues;
|
||||
- (NSArray *) values;
|
||||
- (NSDictionary *) attributes;
|
||||
- (NSMutableDictionary *) attributes;
|
||||
- (BOOL) hasAttribute: (NSString *) aType
|
||||
havingValue: (NSString *) aValue;
|
||||
|
||||
- (BOOL) isVoid;
|
||||
- (void) addType: (NSString *) aType;
|
||||
|
||||
- (NSString *) versitString;
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
id newElement;
|
||||
|
||||
newElement = [self elementWithTag: aTag];
|
||||
[newElement addValue: aValue];
|
||||
[newElement setSingleValue: aValue forKey: @""];
|
||||
|
||||
return newElement;
|
||||
}
|
||||
|
@ -74,21 +74,6 @@
|
|||
return newElement;
|
||||
}
|
||||
|
||||
+ (id) elementWithTag: (NSString *) aTag
|
||||
attributes: (NSDictionary *) someAttributes
|
||||
values: (NSArray *) someValues
|
||||
{
|
||||
id newElement;
|
||||
|
||||
newElement = [self new];
|
||||
[newElement autorelease];
|
||||
[newElement setTag: aTag];
|
||||
[newElement addAttributes: someAttributes];
|
||||
[newElement addValues: someValues];
|
||||
|
||||
return newElement;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
|
@ -96,7 +81,7 @@
|
|||
parent = nil;
|
||||
tag = nil;
|
||||
group = nil;
|
||||
values = [NSMutableArray new];
|
||||
values = [NSMutableDictionary new];
|
||||
attributes = [NSMutableDictionary new];
|
||||
}
|
||||
|
||||
|
@ -142,16 +127,172 @@
|
|||
return group;
|
||||
}
|
||||
|
||||
- (void) addValue: (NSString *) aValue
|
||||
/* values */
|
||||
- (void) setValues: (NSMutableDictionary *) newValues
|
||||
{
|
||||
if (!aValue)
|
||||
aValue = @"";
|
||||
[values addObject: aValue];
|
||||
ASSIGN (values, newValues);
|
||||
}
|
||||
|
||||
- (void) addValues: (NSArray *) someValues
|
||||
- (NSMutableDictionary *) values
|
||||
{
|
||||
[values addObjectsFromArray: someValues];
|
||||
return values;
|
||||
}
|
||||
|
||||
- (void) setValues: (NSMutableArray *) newValues
|
||||
atIndex: (NSUInteger) idx
|
||||
forKey: (NSString *) key
|
||||
{
|
||||
NSMutableArray *oldValues, *subValues;
|
||||
|
||||
oldValues = [self valuesForKey: key];
|
||||
if (!oldValues)
|
||||
{
|
||||
oldValues = [NSMutableArray new];
|
||||
[values setObject: oldValues forKey: key];
|
||||
[oldValues release];
|
||||
}
|
||||
|
||||
while ([oldValues count] < (idx + 1))
|
||||
{
|
||||
subValues = [NSMutableArray new];
|
||||
[oldValues addObject: subValues];
|
||||
[subValues release];
|
||||
}
|
||||
|
||||
if (!newValues)
|
||||
newValues = [NSMutableArray array];
|
||||
[oldValues replaceObjectAtIndex: idx withObject: newValues];
|
||||
}
|
||||
|
||||
- (void) setSingleValue: (NSString *) newValue
|
||||
atIndex: (NSUInteger) idx
|
||||
forKey: (NSString *) key
|
||||
{
|
||||
NSMutableArray *subValues;
|
||||
|
||||
if (newValue)
|
||||
{
|
||||
subValues = [NSMutableArray new];
|
||||
[subValues addObject: newValue];
|
||||
}
|
||||
else
|
||||
subValues = nil;
|
||||
[self setValues: subValues atIndex: idx forKey: key];
|
||||
[subValues release];
|
||||
}
|
||||
|
||||
- (void) setSingleValue: (NSString *) newValue
|
||||
forKey: (NSString *) key
|
||||
{
|
||||
[self setSingleValue: newValue
|
||||
atIndex: 0 forKey: key];
|
||||
}
|
||||
|
||||
- (NSMutableArray *) valuesForKey: (NSString *) key
|
||||
{
|
||||
return [values objectForKey: [key lowercaseString]];
|
||||
}
|
||||
|
||||
- (NSMutableArray *) valuesAtIndex: (NSUInteger) idx
|
||||
forKey: (NSString *) key
|
||||
{
|
||||
return [[self valuesForKey: key] objectAtIndex: idx];
|
||||
}
|
||||
|
||||
- (NSString *) flattenedValueAtIndex: (NSUInteger) idx
|
||||
forKey: (NSString *) key
|
||||
{
|
||||
NSMutableArray *orderedValues, *sValues;
|
||||
NSUInteger count, max;
|
||||
NSMutableString *flattenedValues;
|
||||
NSString *encoding, *realValue, *value;
|
||||
|
||||
flattenedValues = [NSMutableString string];
|
||||
|
||||
orderedValues = [self valuesForKey: key];
|
||||
max = [orderedValues count];
|
||||
if (max > idx)
|
||||
{
|
||||
encoding = [[self value: 0 ofAttribute: @"encoding"]
|
||||
lowercaseString];
|
||||
sValues = [orderedValues objectAtIndex: idx];
|
||||
max = [sValues count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
if (count > 0)
|
||||
[flattenedValues appendString: @","];
|
||||
realValue = [sValues objectAtIndex: count];
|
||||
if ([encoding isEqualToString: @"quoted-printable"])
|
||||
value = [realValue stringByDecodingQuotedPrintable];
|
||||
else if ([encoding isEqualToString: @"base64"])
|
||||
value = [realValue stringByDecodingBase64];
|
||||
else
|
||||
{
|
||||
value = realValue;
|
||||
if ([encoding length] && ![encoding isEqualToString: @"8bit"])
|
||||
[self logWithFormat: @"unknown encoding '%@'", encoding];
|
||||
}
|
||||
|
||||
[flattenedValues appendString: value];
|
||||
}
|
||||
}
|
||||
|
||||
return flattenedValues;
|
||||
}
|
||||
|
||||
- (NSString *) flattenedValuesForKey: (NSString *) key
|
||||
{
|
||||
NSMutableArray *orderedValues, *sValues;
|
||||
NSUInteger count, max, sCount, sMax;
|
||||
NSMutableString *flattenedValues;
|
||||
NSString *encoding, *realValue, *value;
|
||||
|
||||
encoding = [[self value: 0 ofAttribute: @"encoding"]
|
||||
lowercaseString];
|
||||
|
||||
flattenedValues = [NSMutableString string];
|
||||
|
||||
orderedValues = [self valuesForKey: key];
|
||||
max = [orderedValues count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
if (count > 0)
|
||||
[flattenedValues appendString: @";"];
|
||||
sValues = [orderedValues objectAtIndex: count];
|
||||
sMax = [sValues count];
|
||||
for (sCount = 0; sCount < sMax; sCount++)
|
||||
{
|
||||
if (sCount > 0)
|
||||
[flattenedValues appendString: @","];
|
||||
realValue = [sValues objectAtIndex: sCount];
|
||||
if ([encoding isEqualToString: @"quoted-printable"])
|
||||
value = [realValue stringByDecodingQuotedPrintable];
|
||||
else if ([encoding isEqualToString: @"base64"])
|
||||
value = [realValue stringByDecodingBase64];
|
||||
else
|
||||
{
|
||||
value = realValue;
|
||||
if ([encoding length] && ![encoding isEqualToString: @"8bit"])
|
||||
[self logWithFormat: @"unknown encoding '%@'", encoding];
|
||||
}
|
||||
|
||||
[flattenedValues appendString: value];
|
||||
}
|
||||
}
|
||||
|
||||
return flattenedValues;
|
||||
}
|
||||
|
||||
/* attributes */
|
||||
|
||||
- (NSMutableDictionary *) attributes
|
||||
{
|
||||
return attributes;
|
||||
}
|
||||
|
||||
- (void) setAttributesAsCopy: (NSMutableDictionary *) someAttributes
|
||||
{
|
||||
ASSIGN (attributes, someAttributes);
|
||||
}
|
||||
|
||||
- (void) addAttribute: (NSString *) anAttribute
|
||||
|
@ -219,26 +360,6 @@
|
|||
[self addAttribute: @"type" value: aType];
|
||||
}
|
||||
|
||||
- (void) setValues: (NSArray *) newValues
|
||||
{
|
||||
if (![newValues isKindOfClass: [NSMutableArray class]])
|
||||
{
|
||||
newValues = [newValues mutableCopy];
|
||||
[newValues autorelease];
|
||||
}
|
||||
ASSIGN (values, newValues);
|
||||
}
|
||||
|
||||
- (NSArray *) values
|
||||
{
|
||||
return values;
|
||||
}
|
||||
|
||||
- (NSDictionary *) attributes
|
||||
{
|
||||
return attributes;
|
||||
}
|
||||
|
||||
- (BOOL) hasAttribute: (NSString *) anAttribute
|
||||
havingValue: (NSString *) aValue
|
||||
{
|
||||
|
@ -249,141 +370,6 @@
|
|||
return (attribute && [attribute hasCaseInsensitiveString: aValue]);
|
||||
}
|
||||
|
||||
- (void) setValue: (unsigned int) anInt
|
||||
to: (NSString *) aValue
|
||||
{
|
||||
unsigned int count, max;
|
||||
|
||||
if (!aValue)
|
||||
aValue = @"";
|
||||
max = [values count];
|
||||
for (count = max; count <= anInt; count++)
|
||||
[self addValue: @""];
|
||||
|
||||
[values replaceObjectAtIndex: anInt withObject: aValue];
|
||||
}
|
||||
|
||||
- (NSString *) value: (unsigned int) anInt
|
||||
{
|
||||
NSString *realValue, *value, *encoding;
|
||||
|
||||
if ([values count] <= anInt)
|
||||
value = @"";
|
||||
else
|
||||
{
|
||||
realValue = [values objectAtIndex: anInt];
|
||||
encoding = [[self value: 0 ofAttribute: @"encoding"] lowercaseString];
|
||||
if ([encoding length])
|
||||
{
|
||||
if ([encoding isEqualToString: @"quoted-printable"])
|
||||
value = [realValue stringByDecodingQuotedPrintable];
|
||||
else if ([encoding isEqualToString: @"base64"])
|
||||
value = [realValue stringByDecodingBase64];
|
||||
else
|
||||
{
|
||||
value = realValue;
|
||||
if (![encoding isEqualToString: @"8bit"])
|
||||
[self logWithFormat: @"unknown encoding '%@'", encoding];
|
||||
}
|
||||
}
|
||||
else
|
||||
value = realValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
- (unsigned int) _namedValue: (NSString *) aValueName
|
||||
{
|
||||
NSString *prefix, *value;
|
||||
unsigned int count, max, result;
|
||||
|
||||
result = NSNotFound;
|
||||
|
||||
prefix = [NSString stringWithFormat: @"%@=", [aValueName uppercaseString]];
|
||||
max = [values count];
|
||||
count = 0;
|
||||
|
||||
while (result == NSNotFound && count < max)
|
||||
{
|
||||
value = [[values objectAtIndex: count] uppercaseString];
|
||||
if ([value hasPrefix: prefix])
|
||||
result = count;
|
||||
else
|
||||
count++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void) setNamedValue: (NSString *) aValueName
|
||||
to: (NSString *) aValue
|
||||
{
|
||||
NSString *newValue;
|
||||
unsigned int index;
|
||||
|
||||
if (!aValue)
|
||||
aValue = @"";
|
||||
newValue = [NSString stringWithFormat: @"%@=%@",
|
||||
[aValueName uppercaseString],
|
||||
aValue];
|
||||
index = [self _namedValue: aValueName];
|
||||
if (index == NSNotFound)
|
||||
{
|
||||
if ([aValue length])
|
||||
[self addValue: newValue];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([aValue length])
|
||||
[self setValue: index to: newValue];
|
||||
else
|
||||
[values removeObjectAtIndex: index];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *) namedValue: (NSString *) aValueName
|
||||
{
|
||||
unsigned int index;
|
||||
NSRange equalSign;
|
||||
NSString *value;
|
||||
|
||||
index = [self _namedValue: aValueName];
|
||||
if (index == NSNotFound)
|
||||
value = @"";
|
||||
else
|
||||
{
|
||||
value = [values objectAtIndex: index];
|
||||
equalSign = [value rangeOfString: @"="];
|
||||
if (equalSign.location != NSNotFound)
|
||||
value = [value substringFromIndex: equalSign.location + 1];
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
- (void) setCommaSeparatedValues: (NSArray *) newValues
|
||||
{
|
||||
NSMutableString *newValue;
|
||||
NSUInteger count, max;
|
||||
NSString *currentValue;
|
||||
|
||||
newValue = [NSMutableString stringWithCapacity: 250];
|
||||
|
||||
max = [newValues count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
currentValue = [[newValues objectAtIndex: count]
|
||||
stringByReplacingString: @","
|
||||
withString: @"\\,"];
|
||||
if (count > 0)
|
||||
[newValue appendFormat: @",%@", currentValue];
|
||||
else
|
||||
[newValue appendString: currentValue];
|
||||
}
|
||||
[self setValues: [NSArray arrayWithObject: newValue]];
|
||||
}
|
||||
|
||||
- (void) setValue: (unsigned int) anInt
|
||||
ofAttribute: (NSString *) anAttribute
|
||||
to: (NSString *) aValue
|
||||
|
@ -423,10 +409,7 @@
|
|||
|
||||
- (NSString *) description
|
||||
{
|
||||
NSArray *attrs;
|
||||
NSMutableString *str;
|
||||
unsigned int count, max;
|
||||
NSString *attr;
|
||||
|
||||
str = [NSMutableString stringWithCapacity:64];
|
||||
[str appendFormat:@"<%p[%@]:", self, NSStringFromClass([self class])];
|
||||
|
@ -435,48 +418,56 @@
|
|||
else
|
||||
[str appendFormat: @"%@\n", tag, group];
|
||||
|
||||
attrs = [attributes allKeys];
|
||||
max = [attrs count];
|
||||
if (max > 0)
|
||||
{
|
||||
[str appendFormat: @"\n %d attributes: {\n", [attrs count]];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
attr = [attrs objectAtIndex: count];
|
||||
[str appendFormat: @" %@: %@\n",
|
||||
attr, [attributes objectForKey: attr]];
|
||||
}
|
||||
[str appendFormat: @"}"];
|
||||
}
|
||||
|
||||
max = [values count];
|
||||
if (max > 0)
|
||||
{
|
||||
[str appendFormat: @"\n %d values: {\n", [values count]];
|
||||
for (count = 0; count < max; count++)
|
||||
[str appendFormat: @" %@\n", [values objectAtIndex: count]];
|
||||
[str appendFormat: @"}"];
|
||||
}
|
||||
|
||||
[str appendString:@">"];
|
||||
[str appendString: [self versitString]];
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
- (BOOL) isVoid
|
||||
static inline BOOL
|
||||
_subValuesAreVoid (NSArray *subValues)
|
||||
{
|
||||
BOOL result;
|
||||
NSString *value;
|
||||
NSEnumerator *enu;
|
||||
BOOL result = YES;
|
||||
NSUInteger count, max;
|
||||
|
||||
result = YES;
|
||||
|
||||
enu = [values objectEnumerator];
|
||||
value = [enu nextObject];
|
||||
while (value && result)
|
||||
max = [subValues count];
|
||||
for (count = 0; result && count < max; count++)
|
||||
result = ([[subValues objectAtIndex: count] length] == 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
_orderedValuesAreVoid (NSArray *orderedValues)
|
||||
{
|
||||
BOOL result = YES;
|
||||
NSUInteger count, max;
|
||||
|
||||
result = YES;
|
||||
|
||||
max = [orderedValues count];
|
||||
for (count = 0; result && count < max; count++)
|
||||
result = _subValuesAreVoid ([orderedValues objectAtIndex: count]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (BOOL) isVoid
|
||||
{
|
||||
BOOL result = YES;
|
||||
NSArray *keys;
|
||||
NSMutableArray *orderedValues;
|
||||
NSUInteger count, max;
|
||||
|
||||
result = YES;
|
||||
|
||||
keys = [values allKeys];
|
||||
max = [keys count];
|
||||
for (count = 0; result && count < max; count++)
|
||||
{
|
||||
result = ([value length] == 0);
|
||||
value = [enu nextObject];
|
||||
orderedValues = [values objectForKey: [keys objectAtIndex: count]];
|
||||
result = _orderedValuesAreVoid (orderedValues);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -523,11 +514,6 @@
|
|||
return newElement;
|
||||
}
|
||||
|
||||
- (void) setAttributesAsCopy: (NSMutableDictionary *) someAttributes
|
||||
{
|
||||
ASSIGN (attributes, someAttributes);
|
||||
}
|
||||
|
||||
- (CardGroup *) searchParentOfClass: (Class) parentClass
|
||||
{
|
||||
CardGroup *current;
|
||||
|
@ -594,7 +580,7 @@
|
|||
newGroup = [group copyWithZone: aZone];
|
||||
[new setGroup: newGroup];
|
||||
[newGroup release];
|
||||
[new setValues: [self deepCopyOfArray: values withZone: aZone]];
|
||||
[new setValues: [self deepCopyOfDictionary: values withZone: aZone]];
|
||||
[new setAttributesAsCopy: [self deepCopyOfDictionary: attributes
|
||||
withZone: aZone]];
|
||||
|
||||
|
@ -604,22 +590,7 @@
|
|||
/* NSMutableCopying */
|
||||
- (id) mutableCopyWithZone: (NSZone *) aZone
|
||||
{
|
||||
#warning this method really is the same as "copyWithZone:"
|
||||
CardElement *new;
|
||||
NSString *newTag, *newGroup;
|
||||
|
||||
new = [[self class] new];
|
||||
newTag = [tag copyWithZone: aZone];
|
||||
[new setTag: newTag];
|
||||
[newTag release];
|
||||
newGroup = [group copyWithZone: aZone];
|
||||
[new setGroup: newGroup];
|
||||
[newGroup release];
|
||||
[new setValues: [self deepCopyOfArray: values withZone: aZone]];
|
||||
[new setAttributesAsCopy: [self deepCopyOfDictionary: attributes
|
||||
withZone: aZone]];
|
||||
|
||||
return new;
|
||||
return [self copyWithZone: aZone];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -281,7 +281,7 @@ static NGCardsSaxHandler *sax = nil;
|
|||
havingValue: (NSString *) aValue
|
||||
{
|
||||
return [children cardElementsWithAttribute: anAttribute
|
||||
havingValue: aValue];
|
||||
havingValue: aValue];
|
||||
}
|
||||
|
||||
- (NSArray *) childrenWithTag: (NSString *) aTag
|
||||
|
@ -293,7 +293,7 @@ static NGCardsSaxHandler *sax = nil;
|
|||
elements = [self childrenWithTag: aTag];
|
||||
|
||||
return [elements cardElementsWithAttribute: anAttribute
|
||||
havingValue: aValue];
|
||||
havingValue: aValue];
|
||||
}
|
||||
|
||||
- (NSArray *) childrenGroupWithTag: (NSString *) aTag
|
||||
|
@ -313,7 +313,8 @@ static NGCardsSaxHandler *sax = nil;
|
|||
{
|
||||
if ([element isKindOfClass: [CardGroup class]])
|
||||
{
|
||||
value = [[element uniqueChildWithTag: aChild] value: 0];
|
||||
value = [[element uniqueChildWithTag: aChild]
|
||||
flattenedValuesForKey: @""];
|
||||
if ([value isEqualToString: aValue])
|
||||
[elements addObject: element];
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#import "CardGroup.h"
|
||||
|
||||
#import "NSString+NGCards.h"
|
||||
#import "NSArray+NGCards.h"
|
||||
#import "NSDictionary+NGCards.h"
|
||||
|
||||
#import "CardVersitRenderer.h"
|
||||
|
||||
|
@ -55,9 +55,8 @@
|
|||
{
|
||||
NSMutableString *rendering;
|
||||
NSDictionary *attributes;
|
||||
NSEnumerator *keys;
|
||||
NSArray *values, *renderedAttrs;
|
||||
NSString *key, *finalRendering, *tag;
|
||||
NSMutableDictionary *values;
|
||||
NSString *finalRendering, *tag;
|
||||
|
||||
if (![anElement isVoid])
|
||||
{
|
||||
|
@ -76,41 +75,16 @@
|
|||
|
||||
/* parameters */
|
||||
attributes = [anElement attributes];
|
||||
keys = [[attributes allKeys] objectEnumerator];
|
||||
while ((key = [keys nextObject]))
|
||||
if ([attributes count])
|
||||
{
|
||||
NSString *s;
|
||||
int i, c;
|
||||
|
||||
renderedAttrs = [[attributes objectForKey: key] renderedForCards];
|
||||
c = [renderedAttrs count];
|
||||
if (c > 0)
|
||||
{
|
||||
[rendering appendFormat: @";%@=", [key uppercaseString]];
|
||||
|
||||
for (i = 0; i < c; i++)
|
||||
{
|
||||
s = [renderedAttrs objectAtIndex: i];
|
||||
|
||||
/* We MUST quote attribute values that have a ":" in them
|
||||
and that not already quoted */
|
||||
if ([s length] > 2 && [s rangeOfString: @":"].length &&
|
||||
[s characterAtIndex: 0] != '"' && ![s hasSuffix: @"\""])
|
||||
s = [NSString stringWithFormat: @"\"%@\"", s];
|
||||
|
||||
[rendering appendFormat: @"%@", s];
|
||||
|
||||
if (i+1 < c)
|
||||
[rendering appendString: @","];
|
||||
}
|
||||
}
|
||||
[rendering appendString: @";"];
|
||||
[attributes versitRenderInString: rendering asAttributes: YES];
|
||||
}
|
||||
|
||||
/* values */
|
||||
values = [anElement values];
|
||||
if ([values count] > 0)
|
||||
[rendering appendFormat: @":%@",
|
||||
[[values renderedForCards] componentsJoinedByString: @";"]];
|
||||
[rendering appendString: @":"];
|
||||
[values versitRenderInString: rendering asAttributes: NO];
|
||||
|
||||
if ([rendering length] > 0)
|
||||
[rendering appendString: @"\r\n"];
|
||||
|
@ -143,12 +117,8 @@
|
|||
groupTag = [groupTag uppercaseString];
|
||||
[rendering appendFormat: @"BEGIN:%@\r\n", groupTag];
|
||||
children = [[aGroup children] objectEnumerator];
|
||||
currentChild = [children nextObject];
|
||||
while (currentChild)
|
||||
{
|
||||
[rendering appendString: [self render: currentChild]];
|
||||
currentChild = [children nextObject];
|
||||
}
|
||||
while ((currentChild = [children nextObject]))
|
||||
[rendering appendString: [self render: currentChild]];
|
||||
[rendering appendFormat: @"END:%@\r\n", groupTag];
|
||||
|
||||
return rendering;
|
||||
|
|
|
@ -1,3 +1,31 @@
|
|||
2011-11-13 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* iCalTrigger.m (-setValue:, value): removed useless accessors.
|
||||
|
||||
* iCalAttachment.m (-setValue:, value): removed useless accessors.
|
||||
|
||||
* iCalRecurrenceRule.m (-setRrule): now makes use of the existing
|
||||
parsing algorithm and get the values from the parsed element.
|
||||
|
||||
* iCalEntityObject.m (-setCategories:): now take an array as
|
||||
parameter.
|
||||
|
||||
* NSString+NGCards.m (-vCardSubvalues): new method adapted to the
|
||||
new CardElement data structure, replaces
|
||||
"vCardSubvaluesWithSeparator:", since we now know how to properly
|
||||
separate or escape elements.
|
||||
|
||||
* CardElement.m (-init): "values" in now an NSMutableDictionary.
|
||||
(-setValues:, -values): new primitive accessors;
|
||||
(-setValues:atIndex:forKey:, -setSingleValue:atIndex:forKey:)
|
||||
(setSingleValue:forKey:): new helper setters.
|
||||
(-flattenedValueAtIndex:forKey:, -flattenedValues:forKey:): new
|
||||
"flattened" helper getters. "Flattening" meaning here that the
|
||||
first and/or second level array are merged with "," and ";", to
|
||||
support clients that badly escape(d) their output for fields
|
||||
taking only one value or a specific set of values.
|
||||
(-valuesForKey:,-valuesAtIndex:forKey:): new helper getters
|
||||
|
||||
2011-11-09 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* NSString+NGCards.m (-escapedForCards): restored the escaping of
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
/* content */
|
||||
|
||||
- (void) startCollectingContent;
|
||||
- (NSArray *) finishCollectingContent;
|
||||
- (NSMutableDictionary *) finishCollectingContent;
|
||||
|
||||
- (void) startGroupElement: (NSString *) _localName;
|
||||
- (void) endGroupElement;
|
||||
|
|
|
@ -181,7 +181,7 @@
|
|||
else if ([_localName isEqualToString: @"container"])
|
||||
[self endGroupElement];
|
||||
else
|
||||
[currentElement addValues: [self finishCollectingContent]];
|
||||
[currentElement setValues: [self finishCollectingContent]];
|
||||
}
|
||||
|
||||
/* content */
|
||||
|
@ -197,9 +197,9 @@
|
|||
vcs.collectContent = 1;
|
||||
}
|
||||
|
||||
- (NSArray *) finishCollectingContent
|
||||
- (NSMutableDictionary *) finishCollectingContent
|
||||
{
|
||||
NSArray *contentValues;
|
||||
NSMutableDictionary *contentValues;
|
||||
NSString *s;
|
||||
|
||||
vcs.collectContent = 0;
|
||||
|
@ -211,7 +211,7 @@
|
|||
free (content);
|
||||
content = NULL;
|
||||
// NSLog (@"content: '%@'", s);
|
||||
contentValues = [s vCardSubvaluesWithSeparator: ';'];
|
||||
contentValues = [s vCardSubvalues];
|
||||
}
|
||||
else
|
||||
contentValues = nil;
|
||||
|
|
|
@ -117,11 +117,12 @@ typedef enum
|
|||
additional: (NSString *) additional
|
||||
prefixes: (NSString *) prefixes
|
||||
suffixes: (NSString *) suffixes;
|
||||
- (NSArray *) n;
|
||||
/* returns an array of single values */
|
||||
- (CardElement *) n;
|
||||
|
||||
- (void) setOrg: (NSString *) anOrg
|
||||
units: (NSArray *) someUnits;
|
||||
- (NSArray *) org;
|
||||
- (CardElement *) org;
|
||||
|
||||
- (void) setCategories: (NSArray *) newCategories;
|
||||
- (NSArray *) categories;
|
||||
|
|
|
@ -116,134 +116,134 @@
|
|||
|
||||
/* accessors */
|
||||
|
||||
- (void) setVersion: (NSString *) _version
|
||||
- (void) setVersion: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"version"] setValue: 0 to: _version];
|
||||
[[self uniqueChildWithTag: @"version"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) version
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"version"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"version"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setUid: (NSString *) _uid
|
||||
- (void) setUid: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"uid"] setValue: 0 to: _uid];
|
||||
[[self uniqueChildWithTag: @"uid"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) uid
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"uid"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"uid"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setVClass: (NSString *) _class
|
||||
- (void) setVClass: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"class"] setValue: 0 to: _class];
|
||||
[[self uniqueChildWithTag: @"class"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) vClass
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"class"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"class"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setProdID: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"prodid"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"prodid"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) prodID
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"prodid"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"prodid"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setProfile: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"profile"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"profile"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) profile
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"profile"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"profile"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setSource: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"source"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"source"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) source
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"source"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"source"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setFn: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"fn"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"fn"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) fn
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"fn"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"fn"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setRole: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"role"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"role"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) role
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"role"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"role"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setTitle: (NSString *) _title
|
||||
- (void) setTitle: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"title"] setValue: 0 to: _title];
|
||||
[[self uniqueChildWithTag: @"title"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) title
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"title"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"title"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setBday: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"bday"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"bday"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) bday
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"bday"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"bday"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setNote: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"note"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"note"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) note
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"note"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"note"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setTz: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"tz"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"tz"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) tz
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"tz"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"tz"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setNickname: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"nickname"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"nickname"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) nickname
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"nickname"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"nickname"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) addTel: (NSString *) phoneNumber
|
||||
|
@ -270,20 +270,20 @@
|
|||
|
||||
n = [self uniqueChildWithTag: @"n"];
|
||||
if (family)
|
||||
[n setValue: 0 to: family];
|
||||
[n setSingleValue: family atIndex: 0 forKey: @""];
|
||||
if (given)
|
||||
[n setValue: 1 to: given];
|
||||
[n setSingleValue: given atIndex: 1 forKey: @""];
|
||||
if (additional)
|
||||
[n setValue: 2 to: additional];
|
||||
[n setSingleValue: additional atIndex: 2 forKey: @""];
|
||||
if (prefixes)
|
||||
[n setValue: 3 to: prefixes];
|
||||
[n setSingleValue: prefixes atIndex: 3 forKey: @""];
|
||||
if (suffixes)
|
||||
[n setValue: 4 to: suffixes];
|
||||
[n setSingleValue: suffixes atIndex: 4 forKey: @""];
|
||||
}
|
||||
|
||||
- (NSArray *) n
|
||||
- (CardElement *) n
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"n"] values];
|
||||
return [self uniqueChildWithTag: @"n"];
|
||||
}
|
||||
|
||||
- (void) setOrg: (NSString *) anOrg
|
||||
|
@ -294,35 +294,30 @@
|
|||
|
||||
org = [self uniqueChildWithTag: @"org"];
|
||||
if (anOrg)
|
||||
[org setValue: 0 to: anOrg];
|
||||
[org setSingleValue: anOrg atIndex: 0 forKey: @""];
|
||||
if (someUnits)
|
||||
{
|
||||
max = [someUnits count];
|
||||
for (count = 0; count < max; count++)
|
||||
[org setValue: count + 1 to: [someUnits objectAtIndex: count]];
|
||||
[org setSingleValue: [someUnits objectAtIndex: count]
|
||||
atIndex: count + 1 forKey: @""];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *) org
|
||||
- (CardElement *) org
|
||||
{
|
||||
NSArray *elements, *org;
|
||||
|
||||
elements = [self childrenWithTag: @"org"];
|
||||
if ([elements count] > 0)
|
||||
org = [[elements objectAtIndex: 0] values];
|
||||
else
|
||||
org = nil;
|
||||
|
||||
return org;
|
||||
return [self uniqueChildWithTag: @"org"];
|
||||
}
|
||||
|
||||
- (void) setCategories: (NSArray *) newCategories
|
||||
{
|
||||
CardElement *cats;
|
||||
NSMutableArray *copy;
|
||||
|
||||
cats = [self uniqueChildWithTag: @"categories"];
|
||||
|
||||
[cats setCommaSeparatedValues: newCategories];
|
||||
copy = [newCategories mutableCopy];
|
||||
[cats setValues: copy atIndex: 0 forKey: @""];
|
||||
[copy release];
|
||||
}
|
||||
|
||||
- (NSArray *) categories
|
||||
|
@ -331,7 +326,7 @@
|
|||
|
||||
cats = [self uniqueChildWithTag: @"categories"];
|
||||
|
||||
return [[cats value: 0] vCardSubvaluesWithSeparator: ','];
|
||||
return [cats valuesAtIndex: 0 forKey: @""];
|
||||
}
|
||||
|
||||
// - (void) setOrg: (NGVCardOrg *) _v
|
||||
|
@ -461,12 +456,12 @@
|
|||
|
||||
- (NSString *) preferredEMail
|
||||
{
|
||||
return [[self _preferredElementWithTag: @"email"] value: 0];
|
||||
return [[self _preferredElementWithTag: @"email"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) preferredTel
|
||||
{
|
||||
return [[self _preferredElementWithTag: @"tel"] value: 0];
|
||||
return [[self _preferredElementWithTag: @"tel"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (CardElement *) preferredAdr
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
#import <NGExtensions/NGBase64Coding.h>
|
||||
|
@ -61,9 +62,11 @@
|
|||
{
|
||||
/* We bypass -[values:] because we want to obtain the undecoded
|
||||
value first. */
|
||||
if ([values count] > 0)
|
||||
if ([values count] > 0 && [[values objectForKey: @""] count] > 0 &&
|
||||
[[[values objectForKey: @""] objectAtIndex: 0] count] > 0)
|
||||
{
|
||||
value = [values objectAtIndex: 0];
|
||||
value = [[[values objectForKey: @""] objectAtIndex: 0]
|
||||
componentsJoinedByString: @","];
|
||||
decodedContent = [value dataByDecodingBase64];
|
||||
}
|
||||
else
|
||||
|
|
|
@ -48,12 +48,12 @@
|
|||
|
||||
- (void) setReference: (NSString *) newReference
|
||||
{
|
||||
[self setValue: 0 to: newReference];
|
||||
[self setSingleValue: newReference forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) reference
|
||||
{
|
||||
return [self value: 0];
|
||||
return [self flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -77,45 +77,45 @@
|
|||
|
||||
- (void) setProdID: (NSString *) newProdID
|
||||
{
|
||||
[[self uniqueChildWithTag: @"prodid"] setValue: 0 to: newProdID];
|
||||
[[self uniqueChildWithTag: @"prodid"] setSingleValue: newProdID forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) prodID
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"prodid"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"prodid"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setVersion: (NSString *) newVersion
|
||||
{
|
||||
[[self uniqueChildWithTag: @"version"] setValue: 0
|
||||
to: newVersion];
|
||||
[[self uniqueChildWithTag: @"version"] setSingleValue: newVersion
|
||||
forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) version
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"version"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"version"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setUid: (NSString *) newUid
|
||||
{
|
||||
[[self uniqueChildWithTag: @"uid"] setValue: 0
|
||||
to: newUid];
|
||||
[[self uniqueChildWithTag: @"uid"] setSingleValue: newUid
|
||||
forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) uid
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"uid"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"uid"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setAccessClass: (NSString *) newAccessClass
|
||||
{
|
||||
[[self uniqueChildWithTag: @"class"] setValue: 0
|
||||
to: newAccessClass];
|
||||
[[self uniqueChildWithTag: @"class"] setSingleValue: newAccessClass
|
||||
forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) accessClass
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"class"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"class"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (NGCardsAccessClass) symbolicAccessClass
|
||||
|
@ -141,34 +141,34 @@
|
|||
|
||||
- (void) setFn: (NSString *) newFn
|
||||
{
|
||||
[[self uniqueChildWithTag: @"fn"] setValue: 0 to: newFn];
|
||||
[[self uniqueChildWithTag: @"fn"] setSingleValue: newFn forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) fn
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"fn"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"fn"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setNickname: (NSString *) newNickname
|
||||
{
|
||||
[[self uniqueChildWithTag: @"nickname"] setValue: 0
|
||||
to: newNickname];
|
||||
[[self uniqueChildWithTag: @"nickname"] setSingleValue: newNickname
|
||||
forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) nickname
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"nickname"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"nickname"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setDescription: (NSString *) newDescription
|
||||
{
|
||||
[[self uniqueChildWithTag: @"description"] setValue: 0
|
||||
to: newDescription];
|
||||
[[self uniqueChildWithTag: @"description"] setSingleValue: newDescription
|
||||
forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) description
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"description"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"description"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) addCardReference: (NGVCardReference *) newCardRef
|
||||
|
|
|
@ -35,8 +35,6 @@
|
|||
- (NSArray *) cardElementsWithAttribute: (NSString *) anAttribute
|
||||
havingValue: (NSString *) aValue;
|
||||
|
||||
- (NSArray *) renderedForCards;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* NSARRAY_NGCARDS_H */
|
||||
|
|
|
@ -99,32 +99,4 @@
|
|||
return matchingElements;
|
||||
}
|
||||
|
||||
- (NSArray *) renderedForCards
|
||||
{
|
||||
NSMutableArray *purified;
|
||||
NSString *string;
|
||||
int count, max, lastInsert;
|
||||
|
||||
max = [self count];
|
||||
purified = [NSMutableArray arrayWithCapacity: max];
|
||||
|
||||
lastInsert = -1;
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
string = [self objectAtIndex: count];
|
||||
if ([string length] > 0)
|
||||
{
|
||||
while (lastInsert < (count - 1))
|
||||
{
|
||||
[purified addObject: @""];
|
||||
lastInsert++;
|
||||
}
|
||||
[purified addObject: [string escapedForCards]];
|
||||
lastInsert = count;
|
||||
}
|
||||
}
|
||||
|
||||
return purified;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
|
||||
- (id) objectForCaseInsensitiveKey: (NSString *) aKey;
|
||||
|
||||
- (void) versitRenderInString: (NSMutableString *) aString
|
||||
asAttributes: (BOOL) asAttribute; /* handling of ":" */
|
||||
|
||||
@end
|
||||
|
||||
#endif /* NSDICTIONARY_NGCARDS_H */
|
||||
|
|
|
@ -20,10 +20,95 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
#import "NSArray+NGCards.h"
|
||||
#import "NSString+NGCards.h"
|
||||
|
||||
#import "NSDictionary+NGCards.h"
|
||||
|
||||
@interface NSArray (NGCardsVersit)
|
||||
|
||||
- (BOOL) _renderAsSubValuesInString: (NSMutableString *) aString
|
||||
asAttributes: (BOOL) asAttributes;
|
||||
- (BOOL) _renderAsOrderedValuesInString: (NSMutableString *) aString
|
||||
withKey: (NSString *) key;
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSArray (NGCardsVersit)
|
||||
|
||||
- (BOOL) _renderAsSubValuesInString: (NSMutableString *) aString
|
||||
asAttributes: (BOOL) asAttributes
|
||||
{
|
||||
NSUInteger count, max;
|
||||
NSString *subValue, *escaped;
|
||||
BOOL previousWasEmpty = YES, rendered = NO;
|
||||
|
||||
max = [self count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
if (!previousWasEmpty)
|
||||
[aString appendString: @","];
|
||||
subValue = [self objectAtIndex: count];
|
||||
|
||||
/* We MUST quote attribute values that have a ":" in them
|
||||
and that not already quoted */
|
||||
if (asAttributes && [subValue length] > 2
|
||||
&& [subValue rangeOfString: @":"].length
|
||||
&& [subValue characterAtIndex: 0] != '"'
|
||||
&& ![subValue hasSuffix: @"\""])
|
||||
subValue = [NSString stringWithFormat: @"\"%@\"", subValue];
|
||||
|
||||
escaped = [subValue escapedForCards];
|
||||
if ([escaped length] > 0)
|
||||
{
|
||||
[aString appendString: escaped];
|
||||
previousWasEmpty = NO;
|
||||
rendered = YES;
|
||||
}
|
||||
else
|
||||
previousWasEmpty = YES;
|
||||
}
|
||||
|
||||
return rendered;
|
||||
}
|
||||
|
||||
- (BOOL) _renderAsOrderedValuesInString: (NSMutableString *) aString
|
||||
withKey: (NSString *) key
|
||||
{
|
||||
NSUInteger count, max, lastRendered = 0;
|
||||
BOOL rendered = NO;
|
||||
NSArray *subValues;
|
||||
NSMutableString *substring;
|
||||
|
||||
max = [self count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
subValues = [self objectAtIndex: count];
|
||||
substring = [NSMutableString string];
|
||||
if ([subValues _renderAsSubValuesInString: substring
|
||||
asAttributes: NO])
|
||||
{
|
||||
if (lastRendered == 0 && [key length] > 0)
|
||||
[aString appendFormat: @"%@=", key];
|
||||
|
||||
while (lastRendered < count)
|
||||
{
|
||||
[aString appendString: @";"];
|
||||
lastRendered++;
|
||||
}
|
||||
[aString appendString: substring];
|
||||
rendered = YES;
|
||||
}
|
||||
}
|
||||
|
||||
return rendered;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSDictionary (NGCardsExtension)
|
||||
|
||||
- (id) objectForCaseInsensitiveKey: (NSString *) aKey
|
||||
|
@ -37,4 +122,43 @@
|
|||
return ((realKey) ? [self objectForKey: realKey] : nil);
|
||||
}
|
||||
|
||||
- (void) versitRenderInString: (NSMutableString *) aString
|
||||
asAttributes: (BOOL) asAttributes
|
||||
{
|
||||
NSArray *keys;
|
||||
NSUInteger count, max, rendered = 0;
|
||||
NSArray *orderedValues;
|
||||
NSString *key;
|
||||
NSMutableString *substring;
|
||||
|
||||
keys = [self allKeys];
|
||||
max = [keys count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
key = [keys objectAtIndex: count];
|
||||
orderedValues = [self objectForKey: key];
|
||||
substring = [NSMutableString string];
|
||||
if (asAttributes)
|
||||
{
|
||||
if ([orderedValues _renderAsSubValuesInString: substring
|
||||
asAttributes: YES])
|
||||
{
|
||||
if (rendered > 0)
|
||||
[aString appendString: @";"];
|
||||
[aString appendFormat: @"%@=%@",
|
||||
[key uppercaseString], substring];
|
||||
rendered++;
|
||||
}
|
||||
}
|
||||
else if ([orderedValues _renderAsOrderedValuesInString: substring
|
||||
withKey: [key uppercaseString]])
|
||||
{
|
||||
if (rendered > 0)
|
||||
[aString appendString: @";"];
|
||||
[aString appendString: substring];
|
||||
rendered++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
@class NSArray;
|
||||
@class NSCalendarDate;
|
||||
@class NSMutableDictionary;
|
||||
@class NSTimeZone;
|
||||
|
||||
@interface NSString (NGCardsExtensions)
|
||||
|
@ -40,7 +41,7 @@
|
|||
- (NSCalendarDate *) asCalendarDate;
|
||||
- (BOOL) isAllDayDate;
|
||||
|
||||
- (NSArray *) vCardSubvaluesWithSeparator: (unichar) separator;
|
||||
- (NSMutableDictionary *) vCardSubvalues;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSEnumerator.h>
|
||||
#import <Foundation/NSRange.h>
|
||||
|
@ -316,25 +317,35 @@
|
|||
return ([self length] == 8);
|
||||
}
|
||||
|
||||
- (NSArray *) vCardSubvaluesWithSeparator: (unichar) separator
|
||||
- (NSMutableDictionary *) vCardSubvalues
|
||||
{
|
||||
NSMutableArray *components;
|
||||
/* This schema enables things like this:
|
||||
ELEM;...:KEY1=subvalue1;KEY2=subvalue1,subvalue2
|
||||
or
|
||||
ELEM;...:subvalue1;subvalue1,subvalue2 (where KEY = @"") */
|
||||
NSMutableDictionary *values; /* key <> ordered values associations */
|
||||
NSMutableArray *orderedValues = nil; /* those are separated by ';' and contain
|
||||
subvalues, may or may not be named */
|
||||
NSMutableArray *subValues = nil; /* those are separeted by ',' */
|
||||
unichar *stringBuffer, *substringBuffer;
|
||||
NSString *substring;
|
||||
NSString *valuesKey, *substring;
|
||||
unichar currentChar;
|
||||
NSUInteger substringLength, count, max;
|
||||
BOOL escaped;
|
||||
BOOL escaped = NO;
|
||||
|
||||
components = [NSMutableArray arrayWithCapacity: 5];
|
||||
values = [NSMutableDictionary dictionary];
|
||||
valuesKey = @"";
|
||||
|
||||
max = [self length];
|
||||
stringBuffer = NSZoneMalloc (NULL, sizeof (unichar) * max);
|
||||
stringBuffer = NSZoneMalloc (NULL, sizeof (unichar) * max + 1);
|
||||
[self getCharacters: stringBuffer];
|
||||
substringLength = 0;
|
||||
escaped = NO;
|
||||
stringBuffer[max] = 0;
|
||||
|
||||
substringBuffer = NSZoneMalloc (NULL, sizeof (unichar) * max);
|
||||
substringLength = 0;
|
||||
|
||||
max += 1; /* we add one step to force the inclusion of the ending '\0' in
|
||||
the loop */
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
currentChar = stringBuffer[count];
|
||||
|
@ -343,7 +354,7 @@
|
|||
escaped = NO;
|
||||
if (currentChar == 'n' || currentChar == 'N')
|
||||
substringBuffer[substringLength] = '\n';
|
||||
else if (currentChar == 'r')
|
||||
else if (currentChar == 'r' || currentChar == 'R')
|
||||
substringBuffer[substringLength] = '\r';
|
||||
else
|
||||
substringBuffer[substringLength] = currentChar;
|
||||
|
@ -353,16 +364,48 @@
|
|||
{
|
||||
if (currentChar == '\\')
|
||||
escaped = YES;
|
||||
else if (currentChar == separator)
|
||||
else if (currentChar == ',' || currentChar == ';' || currentChar == 0)
|
||||
{
|
||||
substring
|
||||
= [[NSString alloc] initWithCharactersNoCopy: substringBuffer
|
||||
length: substringLength
|
||||
freeWhenDone: YES];
|
||||
[components addObject: substring];
|
||||
[substring release];
|
||||
substringBuffer = NSZoneMalloc (NULL, sizeof (unichar) * max);
|
||||
= [[NSString alloc] initWithCharacters: substringBuffer
|
||||
length: substringLength];
|
||||
substringLength = 0;
|
||||
|
||||
orderedValues = [values objectForKey: valuesKey];
|
||||
if (!orderedValues)
|
||||
{
|
||||
orderedValues = [NSMutableArray new];
|
||||
[values setObject: orderedValues forKey: valuesKey];
|
||||
[orderedValues release];
|
||||
}
|
||||
if (!subValues)
|
||||
{
|
||||
subValues = [NSMutableArray new];
|
||||
[orderedValues addObject: subValues];
|
||||
[subValues release];
|
||||
}
|
||||
if ([substring length] > 0)
|
||||
[subValues addObject: substring];
|
||||
[substring release];
|
||||
|
||||
if (currentChar != ',')
|
||||
{
|
||||
orderedValues = nil;
|
||||
subValues = nil;
|
||||
valuesKey = @"";
|
||||
}
|
||||
}
|
||||
/* hack: 16 chars is an arbitrary limit to distinguish between
|
||||
"named properties" and the base64 padding character. This might
|
||||
need further tweaking... */
|
||||
else if (currentChar == '=' && substringLength < 16)
|
||||
{
|
||||
substring
|
||||
= [[NSString alloc] initWithCharacters: substringBuffer
|
||||
length: substringLength];
|
||||
[substring autorelease];
|
||||
substringLength = 0;
|
||||
valuesKey = [substring lowercaseString];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -372,21 +415,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
if (substringLength > 0)
|
||||
{
|
||||
substring = [[NSString alloc] initWithCharactersNoCopy: substringBuffer
|
||||
length: substringLength
|
||||
freeWhenDone: YES];
|
||||
[components addObject: substring];
|
||||
[substring release];
|
||||
}
|
||||
|
||||
NSZoneFree (NULL, stringBuffer);
|
||||
NSZoneFree (NULL, substringBuffer);
|
||||
|
||||
return components;
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
- (NSString *) rfc822Email
|
||||
{
|
||||
unsigned idx;
|
||||
|
|
|
@ -82,41 +82,41 @@
|
|||
|
||||
- (void) setAction: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"action"] setValue: 0
|
||||
to: _value];
|
||||
[[self uniqueChildWithTag: @"action"] setSingleValue: _value
|
||||
forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) action
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"action"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"action"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setSummary: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"summary"] setValue: 0
|
||||
to: _value];
|
||||
[[self uniqueChildWithTag: @"summary"] setSingleValue: _value
|
||||
forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) summary
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"summary"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"summary"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setComment: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"description"] setValue: 0
|
||||
to: _value];
|
||||
[[self uniqueChildWithTag: @"description"] setSingleValue: _value
|
||||
forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) comment
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"description"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"description"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setRecurrenceRule: (NSString *) _recurrenceRule
|
||||
- (void) setRecurrenceRule: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"rrule"] setValue: 0
|
||||
to: _recurrenceRule];
|
||||
[[self uniqueChildWithTag: @"rrule"] setSingleValue: _value
|
||||
forKey: @""];
|
||||
}
|
||||
|
||||
- (void) setAttendees: (NSArray *) attendees
|
||||
|
@ -137,7 +137,7 @@
|
|||
|
||||
- (NSString *) recurrenceRule
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"rrule"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"rrule"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) nextAlarmDate
|
||||
|
@ -161,7 +161,8 @@
|
|||
== NSOrderedSame)
|
||||
{
|
||||
relation = [aTrigger relationType];
|
||||
anInterval = [[aTrigger value] durationAsTimeInterval];
|
||||
anInterval = [[aTrigger flattenedValuesForKey: @""]
|
||||
durationAsTimeInterval];
|
||||
if ([relation caseInsensitiveCompare: @"END"] == NSOrderedSame)
|
||||
{
|
||||
if ([parent isKindOfClass: [iCalEvent class]])
|
||||
|
|
|
@ -28,9 +28,6 @@
|
|||
|
||||
@interface iCalAttachment : CardElement
|
||||
|
||||
- (void) setValue: (NSString *) aValue;
|
||||
- (NSString *) value;
|
||||
|
||||
- (void) setValueType: (NSString *) aType;
|
||||
- (NSString *) valueType;
|
||||
|
||||
|
|
|
@ -26,16 +26,6 @@
|
|||
|
||||
/* accessors */
|
||||
|
||||
- (void) setValue: (NSString *) _value
|
||||
{
|
||||
[self setValue: 0 to: _value];
|
||||
}
|
||||
|
||||
- (NSString *) value
|
||||
{
|
||||
return [self value: 0];
|
||||
}
|
||||
|
||||
- (void) setValueType: (NSString *) _value
|
||||
{
|
||||
[self setValue: 0 ofAttribute: @"type" to: _value];
|
||||
|
|
|
@ -69,45 +69,44 @@
|
|||
|
||||
/* accessors */
|
||||
|
||||
- (void) setCalscale: (NSString *) _calscale
|
||||
- (void) setCalscale: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"calscale"] setValue: 0 to: _calscale];
|
||||
[[self uniqueChildWithTag: @"calscale"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) calscale
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"calscale"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"calscale"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setVersion: (NSString *) _version
|
||||
- (void) setVersion: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"version"] setValue: 0 to: _version];
|
||||
[[self uniqueChildWithTag: @"version"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) version
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"version"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"version"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setProdID: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"prodid"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"prodid"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) prodId
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"prodid"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"prodid"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setMethod: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"method"] setValue: 0
|
||||
to: [_value uppercaseString]];
|
||||
[[self uniqueChildWithTag: @"method"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) method
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"method"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"method"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) addToEvents: (iCalEvent *) _event
|
||||
|
|
|
@ -137,7 +137,7 @@
|
|||
else
|
||||
timeString = @"";
|
||||
|
||||
[self setValue: 0 to: timeString];
|
||||
[self setSingleValue: timeString forKey: @""];
|
||||
}
|
||||
|
||||
- (void) setDateTime: (NSCalendarDate *) dateTime
|
||||
|
@ -160,15 +160,17 @@
|
|||
iCalTimeZone *iTZ;
|
||||
NSString *date;
|
||||
NSCalendarDate *initialDate, *dateTime;
|
||||
NSArray *subValues;
|
||||
NSMutableArray *dates;
|
||||
//NSTimeZone *tz;
|
||||
unsigned count, i;
|
||||
|
||||
count = [[self values] count];
|
||||
subValues = [self valuesAtIndex: 0 forKey: @""];
|
||||
count = [subValues count];
|
||||
dates = [NSMutableArray arrayWithCapacity: count];
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
date = [self value: i];
|
||||
date = [subValues objectAtIndex: i];
|
||||
iTZ = [self timeZone];
|
||||
|
||||
if (iTZ)
|
||||
|
@ -204,7 +206,7 @@
|
|||
|
||||
- (BOOL) isAllDay
|
||||
{
|
||||
return [[self value: 0] isAllDayDate];
|
||||
return [[self flattenedValuesForKey: @""] isAllDayDate];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -67,8 +67,8 @@ typedef enum
|
|||
- (void) setPriority: (NSString *) _value;
|
||||
- (NSString *) priority;
|
||||
|
||||
- (void) setCategories: (NSString *) _value;
|
||||
- (NSString *)categories;
|
||||
- (void) setCategories: (NSArray *) _value;
|
||||
- (NSArray *) categories;
|
||||
|
||||
- (void) setUserComment: (NSString *) _userComment;
|
||||
- (NSString *) userComment;
|
||||
|
|
|
@ -72,55 +72,55 @@
|
|||
|
||||
/* accessors */
|
||||
|
||||
- (void) setUid: (NSString *) _uid
|
||||
- (void) setUid: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"uid"] setValue: 0 to: _uid];
|
||||
[[self uniqueChildWithTag: @"uid"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) uid
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"uid"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"uid"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setSummary: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"summary"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"summary"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) summary
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"summary"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"summary"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setLocation: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"location"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"location"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) location
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"location"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"location"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
#warning the "comment" accessors are actually "description" accessors, the "comment" ones are missing
|
||||
- (void) setComment: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"description"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"description"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) comment
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"description"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"description"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setAccessClass: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"class"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"class"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) accessClass
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"class"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"class"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (iCalAccessClass) symbolicAccessClass
|
||||
|
@ -146,42 +146,47 @@
|
|||
|
||||
- (void) setPriority: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"priority"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"priority"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) priority
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"priority"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"priority"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setCategories: (NSString *) _value
|
||||
- (void) setCategories: (NSArray *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"categories"] setValue: 0 to: _value];
|
||||
NSMutableArray *copy;
|
||||
|
||||
copy = [_value mutableCopy];
|
||||
[[self uniqueChildWithTag: @"categories"] setValues: copy atIndex: 0
|
||||
forKey: @""];
|
||||
[copy release];
|
||||
}
|
||||
|
||||
- (NSString *) categories
|
||||
- (NSArray *) categories
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"categories"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"categories"] valuesAtIndex: 0 forKey: @""];
|
||||
}
|
||||
|
||||
- (void) setUserComment: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"usercomment"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"usercomment"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) userComment
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"usercomment"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"usercomment"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setStatus: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"status"] setValue: 0 to: _value];
|
||||
[[self uniqueChildWithTag: @"status"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) status
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"status"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"status"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setSequence: (NSNumber *)_value
|
||||
|
@ -189,15 +194,15 @@
|
|||
NSString *sequence;
|
||||
|
||||
sequence = [NSString stringWithFormat: @"%@", _value];
|
||||
[[self uniqueChildWithTag: @"sequence"] setValue: 0
|
||||
to: sequence];;
|
||||
[[self uniqueChildWithTag: @"sequence"] setSingleValue: sequence
|
||||
forKey: @""];
|
||||
}
|
||||
|
||||
- (NSNumber *) sequence
|
||||
{
|
||||
NSString *sequence;
|
||||
|
||||
sequence = [[self uniqueChildWithTag: @"sequence"] value: 0];
|
||||
sequence = [[self uniqueChildWithTag: @"sequence"] flattenedValuesForKey: @""];
|
||||
|
||||
return [NSNumber numberWithInt: [sequence intValue]];
|
||||
}
|
||||
|
@ -391,16 +396,16 @@
|
|||
|
||||
- (void) setAttach: (id) _value
|
||||
{
|
||||
NSString *asString;
|
||||
NSString *aString;
|
||||
|
||||
if ([_value isKindOfClass: [NSString class]])
|
||||
asString = _value;
|
||||
aString = _value;
|
||||
else if ([_value isKindOfClass: [NSURL class]])
|
||||
asString = [_value absoluteString];
|
||||
aString = [_value absoluteString];
|
||||
else
|
||||
asString = @"";
|
||||
aString = @"";
|
||||
|
||||
[[self uniqueChildWithTag: @"attach"] setValue: 0 to: asString];
|
||||
[[self uniqueChildWithTag: @"attach"] setSingleValue: aString forKey: @""];
|
||||
}
|
||||
|
||||
- (NSURL *) attach
|
||||
|
@ -408,7 +413,7 @@
|
|||
NSString *stringAttach;
|
||||
NSURL *url;
|
||||
|
||||
stringAttach = [[self uniqueChildWithTag: @"attach"] value: 0];
|
||||
stringAttach = [[self uniqueChildWithTag: @"attach"] flattenedValuesForKey: @""];
|
||||
url = [NSURL URLWithString: stringAttach];
|
||||
|
||||
if (!url && [stringAttach length] > 0)
|
||||
|
@ -419,23 +424,23 @@
|
|||
|
||||
- (void) setUrl: (id) _value
|
||||
{
|
||||
NSString *asString;
|
||||
NSString *aString;
|
||||
|
||||
if ([_value isKindOfClass: [NSString class]])
|
||||
asString = _value;
|
||||
aString = _value;
|
||||
else if ([_value isKindOfClass: [NSURL class]])
|
||||
asString = [_value absoluteString];
|
||||
aString = [_value absoluteString];
|
||||
else
|
||||
asString = @"";
|
||||
aString = @"";
|
||||
|
||||
[[self uniqueChildWithTag: @"url"] setValue: 0 to: asString];
|
||||
[[self uniqueChildWithTag: @"url"] setSingleValue: aString forKey: @""];
|
||||
}
|
||||
|
||||
- (NSURL *) url
|
||||
{
|
||||
NSString *stringUrl;
|
||||
|
||||
stringUrl = [[self uniqueChildWithTag: @"url"] value: 0];
|
||||
stringUrl = [[self uniqueChildWithTag: @"url"] flattenedValuesForKey: @""];
|
||||
|
||||
return [NSURL URLWithString: stringUrl];
|
||||
}
|
||||
|
|
|
@ -104,13 +104,12 @@
|
|||
|
||||
- (void) setDuration: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"duration"] setValue: 0
|
||||
to: _value];
|
||||
[[self uniqueChildWithTag: @"duration"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) duration
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"duration"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"duration"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (BOOL) hasDuration
|
||||
|
@ -148,15 +147,14 @@
|
|||
return interval;
|
||||
}
|
||||
|
||||
- (void) setTransparency: (NSString *) _transparency
|
||||
- (void) setTransparency: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"transp"] setValue: 0
|
||||
to: _transparency];
|
||||
[[self uniqueChildWithTag: @"transp"] setSingleValue: _value forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) transparency
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"transp"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"transp"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
/* convenience */
|
||||
|
|
|
@ -57,13 +57,13 @@
|
|||
{
|
||||
/* iCal.app compatibility:
|
||||
- "mailto" prefix must be in lowercase; */
|
||||
[self setValue: 0
|
||||
to: [NSString stringWithFormat: @"mailto:%@", _s]];
|
||||
[self setSingleValue: [NSString stringWithFormat: @"mailto:%@", _s]
|
||||
forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) email
|
||||
{
|
||||
return [self value: 0];
|
||||
return [self flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) rfc822Email
|
||||
|
|
|
@ -194,6 +194,7 @@
|
|||
#import "NSCalendarDate+NGCards.h"
|
||||
#import "NSString+NGCards.h"
|
||||
|
||||
#import "CardGroup.h"
|
||||
#import "iCalByDayMask.h"
|
||||
#import "iCalRecurrenceRule.h"
|
||||
|
||||
|
@ -234,8 +235,7 @@ NSString *iCalWeekDayString[] = { @"SU", @"MO", @"TU", @"WE", @"TH", @"FR",
|
|||
iCalRecurrenceRule *rule;
|
||||
|
||||
rule = [self elementWithTag: @"rrule"];
|
||||
if ([_iCalRep length] > 0)
|
||||
[rule addValues: [_iCalRep componentsSeparatedByString: @";"]];
|
||||
[rule setRrule: _iCalRep];
|
||||
|
||||
return rule;
|
||||
}
|
||||
|
@ -269,15 +269,19 @@ NSString *iCalWeekDayString[] = { @"SU", @"MO", @"TU", @"WE", @"TH", @"FR",
|
|||
|
||||
- (void) setRrule: (NSString *) _rrule
|
||||
{
|
||||
NSEnumerator *newValues;
|
||||
NSString *newValue;
|
||||
CardGroup *mockParent;
|
||||
NSString *wrappedRule;
|
||||
CardElement *mockRule;
|
||||
|
||||
newValues = [[_rrule componentsSeparatedByString: @";"] objectEnumerator];
|
||||
newValue = [newValues nextObject];
|
||||
while (newValue)
|
||||
if ([_rrule length] > 0)
|
||||
{
|
||||
[self addValue: newValue];
|
||||
newValue = [newValues nextObject];
|
||||
wrappedRule = [NSString stringWithFormat:
|
||||
@"BEGIN:MOCK\r\nRRULE:%@\r\nEND:MOCK",
|
||||
_rrule];
|
||||
mockParent = [CardGroup parseSingleFromSource: wrappedRule];
|
||||
mockRule = [mockParent uniqueChildWithTag: @"rrule"];
|
||||
[values release];
|
||||
values = [[mockRule values] mutableCopy];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -350,75 +354,73 @@ NSString *iCalWeekDayString[] = { @"SU", @"MO", @"TU", @"WE", @"TH", @"FR",
|
|||
|
||||
- (void) setFrequency: (iCalRecurrenceFrequency) _frequency
|
||||
{
|
||||
[self setNamedValue: @"freq" to: [self frequencyForValue: _frequency]];
|
||||
[self setSingleValue: [self frequencyForValue: _frequency] forKey: @"freq"];
|
||||
}
|
||||
|
||||
- (iCalRecurrenceFrequency) frequency
|
||||
{
|
||||
return [self valueForFrequency: [self namedValue: @"freq"]];
|
||||
}
|
||||
|
||||
- (void) setRepeatCount: (int) _repeatCount
|
||||
{
|
||||
[self setNamedValue: @"count"
|
||||
to: [NSString stringWithFormat: @"%d", _repeatCount]];
|
||||
}
|
||||
|
||||
- (int) repeatCount
|
||||
{
|
||||
return [[self namedValue: @"count"] intValue];
|
||||
return [self valueForFrequency: [self flattenedValuesForKey: @"freq"]];
|
||||
}
|
||||
|
||||
- (void) setUntilDate: (NSCalendarDate *) _untilDate
|
||||
{
|
||||
[self setNamedValue: @"until"
|
||||
to: [_untilDate icalString]];
|
||||
[self setSingleValue: [_untilDate icalString] forKey: @"until"];
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) untilDate
|
||||
{
|
||||
#warning handling of default timezone needs to be implemented
|
||||
return [[self namedValue: @"until"] asCalendarDate];
|
||||
return [[self flattenedValuesForKey: @"until"] asCalendarDate];
|
||||
}
|
||||
|
||||
- (void) setInterval: (NSString *) _interval
|
||||
{
|
||||
if (_interval && [_interval intValue] == 1)
|
||||
[self setNamedValue: @"interval" to: nil];
|
||||
if ([_interval intValue] < 2)
|
||||
[self setSingleValue: nil forKey: @"interval"];
|
||||
else
|
||||
[self setNamedValue: @"interval" to: _interval];
|
||||
}
|
||||
|
||||
- (void) setCount: (NSString *) _count
|
||||
{
|
||||
[self setNamedValue: @"count" to: _count];
|
||||
}
|
||||
|
||||
- (void) setUntil: (NSString *) _until
|
||||
{
|
||||
[self setNamedValue: @"until" to: _until];
|
||||
[self setSingleValue: _interval forKey: @"interval"];
|
||||
}
|
||||
|
||||
- (void) setRepeatInterval: (int) _repeatInterval
|
||||
{
|
||||
[self setNamedValue: @"interval"
|
||||
to: [NSString stringWithFormat: @"%d", _repeatInterval]];
|
||||
[self setInterval: [NSString stringWithFormat: @"%d", _repeatInterval]];
|
||||
}
|
||||
|
||||
- (int) repeatInterval
|
||||
{
|
||||
int interval;
|
||||
|
||||
interval = [[self namedValue: @"interval"] intValue];
|
||||
interval = [[self flattenedValuesForKey: @"interval"] intValue];
|
||||
if (interval < 1)
|
||||
interval = 1;
|
||||
|
||||
return interval;
|
||||
}
|
||||
|
||||
- (void) setRepeatCount: (int) _repeatCount
|
||||
{
|
||||
[self setSingleValue: [NSString stringWithFormat: @"%d", _repeatCount]
|
||||
forKey: @"count"];
|
||||
}
|
||||
|
||||
- (int) repeatCount
|
||||
{
|
||||
return [[self flattenedValuesForKey: @"count"] intValue];
|
||||
}
|
||||
|
||||
- (void) setCount: (NSString *) _count
|
||||
{
|
||||
[self setSingleValue: _count forKey: @"count"];
|
||||
}
|
||||
|
||||
- (void) setUntil: (NSString *) _until
|
||||
{
|
||||
[self setSingleValue: _until forKey: @"until"];
|
||||
}
|
||||
|
||||
- (void) setWkst: (NSString *) _weekStart
|
||||
{
|
||||
[self setNamedValue: @"wkst" to: _weekStart];
|
||||
[self setSingleValue: _weekStart forKey: @"wkst"];
|
||||
}
|
||||
|
||||
#warning we also should handle the user weekstarts
|
||||
|
@ -426,7 +428,7 @@ NSString *iCalWeekDayString[] = { @"SU", @"MO", @"TU", @"WE", @"TH", @"FR",
|
|||
{
|
||||
NSString *start;
|
||||
|
||||
start = [self namedValue: @"wkst"];
|
||||
start = [self flattenedValuesForKey: @"wkst"];
|
||||
if (![start length])
|
||||
start = @"MO";
|
||||
|
||||
|
@ -445,12 +447,16 @@ NSString *iCalWeekDayString[] = { @"SU", @"MO", @"TU", @"WE", @"TH", @"FR",
|
|||
|
||||
- (void) setByDay: (NSString *) newByDay
|
||||
{
|
||||
[self setNamedValue: @"byday" to: newByDay];
|
||||
NSMutableArray *byDays;
|
||||
|
||||
byDays = [[newByDay componentsSeparatedByString: @","] mutableCopy];
|
||||
[self setValues: byDays atIndex: 0 forKey: @"byday"];
|
||||
[byDays release];
|
||||
}
|
||||
|
||||
- (NSString *) byDay
|
||||
{
|
||||
return [self namedValue: @"byday"];
|
||||
return [self flattenedValuesForKey: @"byday"];
|
||||
}
|
||||
|
||||
- (void) setByDayMask: (iCalByDayMask *) newByDayMask
|
||||
|
@ -472,12 +478,9 @@ NSString *iCalWeekDayString[] = { @"SU", @"MO", @"TU", @"WE", @"TH", @"FR",
|
|||
- (NSArray *) byMonthDay
|
||||
{
|
||||
NSArray *byMonthDay;
|
||||
NSString *byMonthDayStr;
|
||||
|
||||
byMonthDayStr = [self namedValue: @"bymonthday"];
|
||||
if ([byMonthDayStr length])
|
||||
byMonthDay = [byMonthDayStr componentsSeparatedByString: @","];
|
||||
else
|
||||
byMonthDay = [self valuesAtIndex: 0 forKey: @"bymonthday"];
|
||||
if (![byMonthDay count])
|
||||
byMonthDay = nil;
|
||||
|
||||
return byMonthDay;
|
||||
|
@ -486,12 +489,9 @@ NSString *iCalWeekDayString[] = { @"SU", @"MO", @"TU", @"WE", @"TH", @"FR",
|
|||
- (NSArray *) byMonth
|
||||
{
|
||||
NSArray *byMonth;
|
||||
NSString *byMonthStr;
|
||||
|
||||
byMonthStr = [self namedValue: @"bymonth"];
|
||||
if ([byMonthStr length])
|
||||
byMonth = [byMonthStr componentsSeparatedByString: @","];
|
||||
else
|
||||
byMonth = [self valuesAtIndex: 0 forKey: @"bymonth"];
|
||||
if (![byMonth count])
|
||||
byMonth = nil;
|
||||
|
||||
return byMonth;
|
||||
|
@ -507,9 +507,9 @@ NSString *iCalWeekDayString[] = { @"SU", @"MO", @"TU", @"WE", @"TH", @"FR",
|
|||
* - BYSECOND
|
||||
* - BYSETPOS
|
||||
*/
|
||||
return ([[self namedValue: @"bymonthday"] length] ||
|
||||
[[self namedValue: @"byday"] length] ||
|
||||
[[self namedValue: @"bymonth"] length]);
|
||||
return ([[self valuesAtIndex: 0 forKey: @"bymonthday"] count] ||
|
||||
[[self valuesAtIndex: 0 forKey: @"byday"] count] ||
|
||||
[[self valuesAtIndex: 0 forKey: @"bymonth"] count]);
|
||||
}
|
||||
|
||||
- (BOOL) isInfinite
|
||||
|
|
|
@ -247,7 +247,7 @@
|
|||
|
||||
while ((dateString = [dateList nextObject]))
|
||||
{
|
||||
exDates = [(iCalDateTime*) dateString values];
|
||||
exDates = [(iCalDateTime*) dateString valuesAtIndex: 0 forKey: @""];
|
||||
for (i = 0; i < [exDates count]; i++)
|
||||
{
|
||||
dateString = [exDates objectAtIndex: i];
|
||||
|
|
|
@ -179,12 +179,12 @@ static NSArray *knownTimeZones;
|
|||
|
||||
- (void) setTzId: (NSString *) tzId
|
||||
{
|
||||
[[self uniqueChildWithTag: @"tzid"] setValue: 0 to: tzId];
|
||||
[[self uniqueChildWithTag: @"tzid"] setSingleValue: tzId forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) tzId
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"tzid"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"tzid"] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) _occurrenceForPeriodNamed: (NSString *) pName
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSTimeZone.h>
|
||||
|
@ -63,7 +64,7 @@
|
|||
seconds = 0;
|
||||
|
||||
offsetTo = [[self uniqueChildWithTag: offsetName]
|
||||
value: 0];
|
||||
flattenedValuesForKey: @""];
|
||||
length = [offsetTo length];
|
||||
negative = [offsetTo hasPrefix: @"-"];
|
||||
if (negative)
|
||||
|
@ -140,7 +141,7 @@
|
|||
|
||||
[tzStart setTimeZone: [NSTimeZone timeZoneWithName: @"GMT"]];
|
||||
tmpDate = [NSCalendarDate dateWithYear: [refDate yearOfCommonEra]
|
||||
month: [[rrule namedValue: @"bymonth"] intValue]
|
||||
month: [[[rrule byMonth] objectAtIndex: 0] intValue]
|
||||
day: 1 hour: [tzStart hourOfDay]
|
||||
minute: [tzStart minuteOfHour] second: 0
|
||||
timeZone: [NSTimeZone timeZoneWithName: @"GMT"]];
|
||||
|
|
|
@ -47,13 +47,14 @@
|
|||
|
||||
- (void) setPercentComplete: (NSString *) _value
|
||||
{
|
||||
[[self uniqueChildWithTag: @"percent-complete"] setValue: 0
|
||||
to: _value];
|
||||
[[self uniqueChildWithTag: @"percent-complete"] setSingleValue: _value
|
||||
forKey: @""];
|
||||
}
|
||||
|
||||
- (NSString *) percentComplete
|
||||
{
|
||||
return [[self uniqueChildWithTag: @"percent-complete"] value: 0];
|
||||
return [[self uniqueChildWithTag: @"percent-complete"]
|
||||
flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (void) setDue: (NSCalendarDate *) newDueDate
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
|
||||
@interface iCalTrigger : CardElement
|
||||
|
||||
- (void) setValue: (NSString *) theValue;
|
||||
- (NSString *) value;
|
||||
|
||||
- (void) setValueType: (NSString *) theType;
|
||||
- (NSString *) valueType;
|
||||
|
||||
|
|
|
@ -27,16 +27,6 @@
|
|||
|
||||
/* accessors */
|
||||
|
||||
- (void) setValue: (NSString *) theValue
|
||||
{
|
||||
[self setValue: 0 to: theValue];
|
||||
}
|
||||
|
||||
- (NSString *) value
|
||||
{
|
||||
return [self value: 0];
|
||||
}
|
||||
|
||||
- (void) setValueType: (NSString *) theValue
|
||||
{
|
||||
[self setValue: 0 ofAttribute: @"value" to: theValue];
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
*/
|
||||
|
||||
/* This class implements most of the XML iCalendar spec as defined here:
|
||||
http://tools.ietf.org/html/draft-daboo-et-al-icalendar-in-xml-04 */
|
||||
http://tools.ietf.org/html/rfc6321 */
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSEnumerator.h>
|
||||
|
@ -161,28 +161,38 @@
|
|||
- (NSString *) _xmlRenderValue
|
||||
{
|
||||
NSMutableString *rendering;
|
||||
NSString *valueTag, *currentValue;
|
||||
int count, max;
|
||||
BOOL displayed;
|
||||
NSArray *keys, *orderedValues, *subValues;
|
||||
NSString *key, *valueTag;
|
||||
NSUInteger count, max, oCount, oMax, sCount, sMax;
|
||||
|
||||
#warning this code should be fix to comply better with the RFC
|
||||
rendering = [NSMutableString stringWithCapacity: 64];
|
||||
|
||||
valueTag = [self xmlValueTag];
|
||||
rendering = [NSMutableString stringWithCapacity: 64];
|
||||
max = [values count];
|
||||
displayed = NO;
|
||||
|
||||
keys = [values allKeys];
|
||||
max = [keys count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
currentValue = [[values objectAtIndex: count]
|
||||
stringByEscapingXMLString];
|
||||
if ([currentValue length] > 0)
|
||||
key = [keys objectAtIndex: count];
|
||||
orderedValues = [values objectForKey: key];
|
||||
oMax = [orderedValues count];
|
||||
for (oCount = 0; oCount < oMax; oCount++)
|
||||
{
|
||||
if (!displayed)
|
||||
{
|
||||
[self _appendPaddingValues: count withTag: valueTag
|
||||
intoString: rendering];
|
||||
displayed = YES;
|
||||
}
|
||||
[rendering appendFormat: @"<%@>%@</%@>",
|
||||
valueTag, currentValue, valueTag];
|
||||
if ([key length] > 0)
|
||||
[rendering appendFormat: @"<%@>", [key lowercaseString]];
|
||||
else
|
||||
[rendering appendFormat: @"<%@>", valueTag];
|
||||
|
||||
subValues = [orderedValues objectAtIndex: oCount];
|
||||
sMax = [subValues count];
|
||||
for (sCount = 0; sCount < sMax; sCount++)
|
||||
[rendering appendString: [[subValues objectAtIndex: sCount] stringByEscapingXMLString]];
|
||||
|
||||
if ([key length] > 0)
|
||||
[rendering appendFormat: @"</%@>", [key lowercaseString]];
|
||||
else
|
||||
[rendering appendFormat: @"</%@>", valueTag];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,39 +257,39 @@
|
|||
|
||||
@end
|
||||
|
||||
@implementation iCalRecurrenceRule (iCalXMLExtension)
|
||||
// @implementation iCalRecurrenceRule (iCalXMLExtension)
|
||||
|
||||
- (NSString *) _xmlRenderValue
|
||||
{
|
||||
NSMutableString *rendering;
|
||||
NSArray *valueParts;
|
||||
NSString *valueTag, *currentValue;
|
||||
int count, max;
|
||||
// - (NSString *) _xmlRenderValue
|
||||
// {
|
||||
// NSMutableString *rendering;
|
||||
// NSArray *valueParts;
|
||||
// NSString *valueTag, *currentValue;
|
||||
// int count, max;
|
||||
|
||||
max = [values count];
|
||||
rendering = [NSMutableString stringWithCapacity: 64];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
currentValue = [[values objectAtIndex: count]
|
||||
stringByEscapingXMLString];
|
||||
if ([currentValue length] > 0)
|
||||
{
|
||||
valueParts = [currentValue componentsSeparatedByString: @"="];
|
||||
if ([valueParts count] == 2)
|
||||
{
|
||||
valueTag = [[valueParts objectAtIndex: 0] lowercaseString];
|
||||
[rendering appendFormat: @"<%@>%@</%@>",
|
||||
valueTag,
|
||||
[valueParts objectAtIndex: 1],
|
||||
valueTag];
|
||||
}
|
||||
}
|
||||
}
|
||||
// max = [values count];
|
||||
// rendering = [NSMutableString stringWithCapacity: 64];
|
||||
// for (count = 0; count < max; count++)
|
||||
// {
|
||||
// currentValue = [[values objectAtIndex: count]
|
||||
// stringByEscapingXMLString];
|
||||
// if ([currentValue length] > 0)
|
||||
// {
|
||||
// valueParts = [currentValue componentsSeparatedByString: @"="];
|
||||
// if ([valueParts count] == 2)
|
||||
// {
|
||||
// valueTag = [[valueParts objectAtIndex: 0] lowercaseString];
|
||||
// [rendering appendFormat: @"<%@>%@</%@>",
|
||||
// valueTag,
|
||||
// [valueParts objectAtIndex: 1],
|
||||
// valueTag];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
return rendering;
|
||||
}
|
||||
// return rendering;
|
||||
// }
|
||||
|
||||
@end
|
||||
// @end
|
||||
|
||||
@implementation iCalUTCOffset (iCalXMLExtension)
|
||||
|
||||
|
|
|
@ -857,8 +857,9 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
|||
NSArray *rules, *exRules, *exDates, *ranges;
|
||||
NSArray *elements, *components;
|
||||
NSString *content;
|
||||
NSCalendarDate *checkStartDate, *checkEndDate, *firstStartDate,
|
||||
*firstEndDate;
|
||||
iCalDateTime *dtstart;
|
||||
NSCalendarDate *checkStartDate, *checkEndDate, *firstStartDate, *firstEndDate;
|
||||
iCalEvent *component;
|
||||
iCalTimeZone *eventTimeZone;
|
||||
unsigned count, max, offset;
|
||||
|
@ -898,8 +899,8 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
|||
{
|
||||
// Retrieve the range of the first/master event
|
||||
component = [components objectAtIndex: 0];
|
||||
dtstart = (iCalDateTime *)[component uniqueChildWithTag: @"dtstart"];
|
||||
firstStartDate = [[[dtstart values] lastObject] asCalendarDate];
|
||||
dtstart = (iCalDateTime *) [component uniqueChildWithTag: @"dtstart"];
|
||||
firstStartDate = [dtstart dateTime];
|
||||
firstEndDate = [firstStartDate addTimeInterval: [component occurenceInterval]];
|
||||
|
||||
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: firstStartDate
|
||||
|
@ -2655,7 +2656,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
|||
tz = nil;
|
||||
element = [components objectAtIndex: i];
|
||||
// Use the timezone of the start date.
|
||||
startDate = (iCalDateTime *)[element uniqueChildWithTag: @"dtstart"];
|
||||
startDate = (iCalDateTime *) [element uniqueChildWithTag: @"dtstart"];
|
||||
if (startDate)
|
||||
{
|
||||
timezone = [startDate timeZone];
|
||||
|
|
|
@ -271,21 +271,16 @@
|
|||
*/
|
||||
- (NGCalendarDateRange *) firstOccurenceRange
|
||||
{
|
||||
iCalDateTime *firstStartDate;
|
||||
NSCalendarDate *start, *end;
|
||||
NGCalendarDateRange *firstRange;
|
||||
|
||||
firstRange = nil;
|
||||
|
||||
firstStartDate = (iCalDateTime *)[self uniqueChildWithTag: @"dtstart"];
|
||||
if ([[firstStartDate values] count] > 0)
|
||||
{
|
||||
start = [[[firstStartDate values] lastObject] asCalendarDate];
|
||||
end = [start addTimeInterval: [self occurenceInterval]];
|
||||
start = [self startDate];
|
||||
end = [start addTimeInterval: [self occurenceInterval]];
|
||||
|
||||
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: start
|
||||
endDate: end];
|
||||
}
|
||||
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: start
|
||||
endDate: end];
|
||||
|
||||
return firstRange;
|
||||
}
|
||||
|
|
|
@ -27,10 +27,12 @@
|
|||
#import <Foundation/NSTimeZone.h>
|
||||
|
||||
#import <NGCards/iCalDateTime.h>
|
||||
#import <NGCards/iCalEvent.h>
|
||||
#import <NGCards/iCalRecurrenceRule.h>
|
||||
#import <NGCards/iCalRecurrenceCalculator.h>
|
||||
#import <NGCards/iCalTimeZone.h>
|
||||
#import <NGCards/NSString+NGCards.h>
|
||||
#import <NGCards/NSDictionary+NGCards.h>
|
||||
#import <NGExtensions/NGCalendarDateRange.h>
|
||||
|
||||
#import "iCalRepeatableEntityObject+SOGo.h"
|
||||
|
@ -40,10 +42,12 @@
|
|||
- (NSArray *) _indexedRules: (NSArray *) rules
|
||||
{
|
||||
NSMutableArray *ma;
|
||||
unsigned int i, count;
|
||||
NSString *valuesString;
|
||||
NSUInteger i, count;
|
||||
NSMutableString *ruleString;
|
||||
iCalRecurrenceRule *rule;
|
||||
|
||||
#warning we could return an NSArray instead and feed it as such to the iCalRecurrenceRule in SOGoAppointmentFolder...
|
||||
|
||||
ma = nil;
|
||||
|
||||
count = [rules count];
|
||||
|
@ -53,9 +57,11 @@
|
|||
for (i = 0; i < count; i++)
|
||||
{
|
||||
rule = [rules objectAtIndex:i];
|
||||
#warning we could return an NSArray instead and feed it as such to the iCalRecurrenceRule in SOGoAppointmentFolder...
|
||||
valuesString = [[rule values] componentsJoinedByString: @";"];
|
||||
[ma addObject: valuesString];
|
||||
ruleString = [NSMutableString new];
|
||||
[[rule values] versitRenderInString: ruleString
|
||||
asAttributes: NO];
|
||||
[ma addObject: ruleString];
|
||||
[ruleString release];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,7 +144,7 @@
|
|||
else
|
||||
{
|
||||
startDate = theOccurenceDate;
|
||||
if ([self isAllDay])
|
||||
if ([self isKindOfClass: [iCalEvent class]] && [(iCalEvent *) self isAllDay])
|
||||
{
|
||||
// The event lasts all-day and has no timezone (floating); we convert the range of the first event
|
||||
// to the occurence's timezone.
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
NSArray *array;
|
||||
NSMutableArray *marray;
|
||||
NSMutableDictionary *entry;
|
||||
CardElement *element;
|
||||
id tmp;
|
||||
|
||||
entry = [NSMutableDictionary dictionary];
|
||||
|
@ -49,13 +50,14 @@
|
|||
@"organizationalPerson", @"inetOrgPerson",
|
||||
@"mozillaAbPersonObsolete", nil]
|
||||
forKey: @"objectclass"];
|
||||
|
||||
tmp = ([[self n] count] > 1 ? [[self n] objectAtIndex: 1] : nil);
|
||||
if (tmp)
|
||||
|
||||
element = [self n];
|
||||
tmp = [element flattenedValueAtIndex: 1 forKey: @""];
|
||||
if ([tmp length] > 0)
|
||||
[entry setObject: tmp forKey: @"givenName"];
|
||||
|
||||
tmp = ([[self n] count] ? [[self n] objectAtIndex: 0] : nil);
|
||||
if (tmp)
|
||||
tmp = [element flattenedValueAtIndex: 0 forKey: @""];
|
||||
if ([tmp length] > 0)
|
||||
[entry setObject: tmp forKey: @"sn"];
|
||||
|
||||
tmp = [self fn];
|
||||
|
@ -74,11 +76,12 @@
|
|||
|
||||
marray = [NSMutableArray arrayWithArray: [self childrenWithTag: @"email"]];
|
||||
[marray removeObjectsInArray: [self childrenWithTag: @"email"
|
||||
andAttribute: @"type"
|
||||
havingValue: @"pref"]];
|
||||
andAttribute: @"type"
|
||||
havingValue: @"pref"]];
|
||||
if ([marray count])
|
||||
{
|
||||
buffer = [[marray objectAtIndex: [marray count]-1] value: 0];
|
||||
buffer = [[marray objectAtIndex: [marray count]-1]
|
||||
flattenedValuesForKey: @""];
|
||||
|
||||
if ([buffer caseInsensitiveCompare: [self preferredEMail]] != NSOrderedSame)
|
||||
[entry setObject: buffer forKey: @"mozillaSecondEmail"];
|
||||
|
@ -86,58 +89,75 @@
|
|||
|
||||
array = [self childrenWithTag: @"tel" andAttribute: @"type" havingValue: @"home"];
|
||||
if ([array count])
|
||||
[entry setObject: [[array objectAtIndex: 0] value: 0] forKey: @"homePhone"];
|
||||
[entry setObject: [[array objectAtIndex: 0] flattenedValuesForKey: @""]
|
||||
forKey: @"homePhone"];
|
||||
array = [self childrenWithTag: @"tel" andAttribute: @"type" havingValue: @"fax"];
|
||||
if ([array count])
|
||||
[entry setObject: [[array objectAtIndex: 0] value: 0] forKey: @"fax"];
|
||||
[entry setObject: [[array objectAtIndex: 0] flattenedValuesForKey: @""]
|
||||
forKey: @"fax"];
|
||||
array = [self childrenWithTag: @"tel" andAttribute: @"type" havingValue: @"cell"];
|
||||
if ([array count])
|
||||
[entry setObject: [[array objectAtIndex: 0] value: 0] forKey: @"mobile"];
|
||||
[entry setObject: [[array objectAtIndex: 0] flattenedValuesForKey: @""]
|
||||
forKey: @"mobile"];
|
||||
array = [self childrenWithTag: @"tel" andAttribute: @"type" havingValue: @"pager"];
|
||||
if ([array count])
|
||||
[entry setObject: [[array objectAtIndex: 0] value: 0] forKey: @"pager"];
|
||||
[entry setObject: [[array objectAtIndex: 0] flattenedValuesForKey: @""]
|
||||
forKey: @"pager"];
|
||||
|
||||
array = [self childrenWithTag: @"adr" andAttribute: @"type" havingValue: @"home"];
|
||||
if ([array count])
|
||||
{
|
||||
tmp = [array objectAtIndex: 0];
|
||||
[entry setObject: [tmp value: 1] forKey: @"mozillaHomeStreet2"];
|
||||
[entry setObject: [tmp value: 2] forKey: @"homeStreet"];
|
||||
[entry setObject: [tmp value: 3] forKey: @"mozillaHomeLocalityName"];
|
||||
[entry setObject: [tmp value: 4] forKey: @"mozillaHomeState"];
|
||||
[entry setObject: [tmp value: 5] forKey: @"mozillaHomePostalCode"];
|
||||
[entry setObject: [tmp value: 6] forKey: @"mozillaHomeCountryName"];
|
||||
[entry setObject: [tmp flattenedValueAtIndex: 1 forKey: @""]
|
||||
forKey: @"mozillaHomeStreet2"];
|
||||
[entry setObject: [tmp flattenedValueAtIndex: 2 forKey: @""]
|
||||
forKey: @"homeStreet"];
|
||||
[entry setObject: [tmp flattenedValueAtIndex: 3 forKey: @""]
|
||||
forKey: @"mozillaHomeLocalityName"];
|
||||
[entry setObject: [tmp flattenedValueAtIndex: 4 forKey: @""]
|
||||
forKey: @"mozillaHomeState"];
|
||||
[entry setObject: [tmp flattenedValueAtIndex: 5 forKey: @""]
|
||||
forKey: @"mozillaHomePostalCode"];
|
||||
[entry setObject: [tmp flattenedValueAtIndex: 6 forKey: @""]
|
||||
forKey: @"mozillaHomeCountryName"];
|
||||
}
|
||||
|
||||
array = [self org];
|
||||
if (array && [array count])
|
||||
[entry setObject: [array objectAtIndex: 0] forKey: @"o"];
|
||||
element = [self org];
|
||||
tmp = [element flattenedValueAtIndex: 0 forKey: @""];
|
||||
if ([tmp length] > 0)
|
||||
[entry setObject: tmp forKey: @"o"];
|
||||
|
||||
array = [self childrenWithTag: @"adr" andAttribute: @"type" havingValue: @"work"];
|
||||
if ([array count])
|
||||
{
|
||||
tmp = [array objectAtIndex: 0];
|
||||
[entry setObject: [tmp value: 1] forKey: @"mozillaWorkStreet2"];
|
||||
[entry setObject: [tmp value: 2] forKey: @"street"];
|
||||
[entry setObject: [tmp value: 3] forKey: @"l"];
|
||||
[entry setObject: [tmp value: 4] forKey: @"st"];
|
||||
[entry setObject: [tmp value: 5] forKey: @"postalCode"];
|
||||
[entry setObject: [tmp value: 6] forKey: @"c"];
|
||||
[entry setObject: [tmp flattenedValueAtIndex: 1 forKey: @""]
|
||||
forKey: @"mozillaWorkStreet2"];
|
||||
[entry setObject: [tmp flattenedValueAtIndex: 2 forKey: @""]
|
||||
forKey: @"street"];
|
||||
[entry setObject: [tmp flattenedValueAtIndex: 3 forKey: @""]
|
||||
forKey: @"l"];
|
||||
[entry setObject: [tmp flattenedValueAtIndex: 4 forKey: @""]
|
||||
forKey: @"st"];
|
||||
[entry setObject: [tmp flattenedValueAtIndex: 5 forKey: @""]
|
||||
forKey: @"postalCode"];
|
||||
[entry setObject: [tmp flattenedValueAtIndex: 6 forKey: @""]
|
||||
forKey: @"c"];
|
||||
}
|
||||
|
||||
array = [self childrenWithTag: @"tel" andAttribute: @"type" havingValue: @"work"];
|
||||
if ([array count])
|
||||
[entry setObject: [[array objectAtIndex: 0] value: 0]
|
||||
[entry setObject: [[array objectAtIndex: 0] flattenedValuesForKey: @""]
|
||||
forKey: @"telephoneNumber"];
|
||||
|
||||
array = [self childrenWithTag: @"url" andAttribute: @"type" havingValue: @"work"];
|
||||
if ([array count])
|
||||
[entry setObject: [[array objectAtIndex: 0] value: 0]
|
||||
[entry setObject: [[array objectAtIndex: 0] flattenedValuesForKey: @""]
|
||||
forKey: @"workurl"];
|
||||
|
||||
array = [self childrenWithTag: @"url" andAttribute: @"type" havingValue: @"home"];
|
||||
if ([array count])
|
||||
[entry setObject: [[array objectAtIndex: 0] value: 0]
|
||||
[entry setObject: [[array objectAtIndex: 0] flattenedValuesForKey: @""]
|
||||
forKey: @"homeurl"];
|
||||
|
||||
tmp = [self note];
|
||||
|
|
|
@ -77,7 +77,8 @@
|
|||
if ([photo isInline])
|
||||
data = [photo decodedContent];
|
||||
else
|
||||
data = [[photo value: 0] dataUsingEncoding: NSISOLatin1StringEncoding];
|
||||
data = [[photo flattenedValuesForKey: @""]
|
||||
dataUsingEncoding: NSISOLatin1StringEncoding];
|
||||
if (data)
|
||||
{
|
||||
response = [localContext response];
|
||||
|
|
|
@ -178,36 +178,34 @@
|
|||
if (!country)
|
||||
country = [ldifEntry objectForKey: @"countryname"];
|
||||
|
||||
element = [CardElement elementWithTag: @"adr"
|
||||
attributes: nil values: nil];
|
||||
element = [CardElement elementWithTag: @"adr"];
|
||||
[element setValue: 0 ofAttribute: @"type" to: @"work"];
|
||||
|
||||
if (streetAddress)
|
||||
[element setValue: 2 to: streetAddress];
|
||||
[element setSingleValue: streetAddress atIndex: 2 forKey: @""];
|
||||
if (location)
|
||||
[element setValue: 3 to: location];
|
||||
[element setSingleValue: location atIndex: 3 forKey: @""];
|
||||
if (region)
|
||||
[element setValue: 4 to: region];
|
||||
[element setSingleValue: region atIndex: 4 forKey: @""];
|
||||
if (postalCode)
|
||||
[element setValue: 5 to: postalCode];
|
||||
[element setSingleValue: postalCode atIndex: 5 forKey: @""];
|
||||
if (country)
|
||||
[element setValue: 6 to: country];
|
||||
[element setSingleValue: country atIndex: 6 forKey: @""];
|
||||
|
||||
if (streetAddress || location || region || postalCode || country)
|
||||
[vcard addChild: element];
|
||||
|
||||
// We handle the org/orgunit stuff
|
||||
element = [CardElement elementWithTag: @"org"
|
||||
attributes: nil values: nil];
|
||||
element = [CardElement elementWithTag: @"org"];
|
||||
org = [ldifEntry objectForKey: @"o"];
|
||||
orgunit = [ldifEntry objectForKey: @"ou"];
|
||||
if (!orgunit)
|
||||
orgunit = [ldifEntry objectForKey: @"orgunit"];
|
||||
|
||||
if (org)
|
||||
[element setValue: 0 to: org];
|
||||
[element setSingleValue: org atIndex: 0 forKey: @""];
|
||||
if (orgunit)
|
||||
[element setValue: 1 to: orgunit];
|
||||
[element setSingleValue: orgunit atIndex: 1 forKey: @""];
|
||||
|
||||
if (org || orgunit)
|
||||
[vcard addChild: element];
|
||||
|
|
|
@ -43,42 +43,95 @@
|
|||
|
||||
/* 1. simple value */
|
||||
element = [CardElement elementWithTag: @"elem"];
|
||||
[element setValue: 0 to: @"value"];
|
||||
[element setSingleValue: @"value" forKey: @""];
|
||||
result = [renderer render: element];
|
||||
testEquals(result, @"ELEM:value\r\n");
|
||||
|
||||
/* 2. two values */
|
||||
element = [CardElement elementWithTag: @"elem"];
|
||||
[element setValue: 0 to: @"value1"];
|
||||
[element setValue: 1 to: @"value2"];
|
||||
[element setSingleValue: @"value2" atIndex: 1
|
||||
forKey: @""];
|
||||
[element setSingleValue: @"value1" atIndex: 0
|
||||
forKey: @""];
|
||||
result = [renderer render: element];
|
||||
testEquals(result, @"ELEM:value1;value2\r\n");
|
||||
|
||||
/* 3. one value with commma */
|
||||
element = [CardElement elementWithTag: @"elem"];
|
||||
[element setValue: 0 to: @"value1, with a comma"];
|
||||
[element setSingleValue: @"value1, with a comma" forKey: @""];
|
||||
result = [renderer render: element];
|
||||
testEquals(result, @"ELEM:value1\\, with a comma\r\n");
|
||||
|
||||
/* 4. one value with a semicolon */
|
||||
element = [CardElement elementWithTag: @"elem"];
|
||||
[element setValue: 0 to: @"value1; with a semi-colon"];
|
||||
[element setSingleValue: @"value1; with a semi-colon" forKey: @""];
|
||||
result = [renderer render: element];
|
||||
testEquals(result, @"ELEM:value1\\; with a semi-colon\r\n");
|
||||
|
||||
/* 4. 3 named values:
|
||||
/* 5. 3 named values:
|
||||
1. with multiple subvalues
|
||||
2. with commas
|
||||
3. with semicolon */
|
||||
element = [CardElement elementWithTag: @"elem"];
|
||||
[element setNamedValue: @"named1"
|
||||
to: [NSArray arrayWithObjects: @"1", @"2", @"3", nil]];
|
||||
[element setNamedValue: @"named2"
|
||||
to: @"1,2,3"];
|
||||
[element setNamedValue: @"named3"
|
||||
to: @"text1;text2"];
|
||||
[element setValues: [NSArray arrayWithObjects: @"1", @"2", @"3", nil]
|
||||
atIndex: 0 forKey: @"named1"];
|
||||
[element setSingleValue: @"1,2,3" forKey: @"named2"];
|
||||
[element setSingleValue: @"text1;text2" forKey: @"named3"];
|
||||
result = [renderer render: element];
|
||||
testEquals(result, @"ELEM:NAMED1=1,2,3;NAMED2=1\\,2\\,3;NAMED3:text1\\;text2\r\n");
|
||||
testEquals(result, @"ELEM:NAMED1=1,2,3;NAMED2=1\\,2\\,3;NAMED3=text1\\;text2\r\n");
|
||||
|
||||
/* 6. values with 1 ordered value with a whitespace starting subvalues */
|
||||
element = [CardElement elementWithTag: @"elem"];
|
||||
[element setValues: [NSArray arrayWithObjects: @"", @"1", nil]
|
||||
atIndex: 0 forKey: @""];
|
||||
result = [renderer render: element];
|
||||
testEquals(result, @"ELEM:1\r\n");
|
||||
|
||||
/* 7. values with 1 ordered value with a subvalue, a whitespace and another subvalue */
|
||||
element = [CardElement elementWithTag: @"elem"];
|
||||
[element setValues: [NSArray arrayWithObjects: @"1", @"", @"2", nil]
|
||||
atIndex: 0 forKey: @""];
|
||||
result = [renderer render: element];
|
||||
testEquals(result, @"ELEM:1,2\r\n");
|
||||
|
||||
/* 8.a. values with 1 empty ordered value and another non-empty one */
|
||||
element = [CardElement elementWithTag: @"elem"];
|
||||
[element setValues: [NSArray arrayWithObjects: nil]
|
||||
atIndex: 0 forKey: @""];
|
||||
[element setValues: [NSArray arrayWithObjects: @"1", nil]
|
||||
atIndex: 1 forKey: @""];
|
||||
result = [renderer render: element];
|
||||
testEquals(result, @"ELEM:;1\r\n");
|
||||
|
||||
/* 8.b. a variant thereof: array with spaces */
|
||||
[element setValues: [NSArray arrayWithObjects: @"", @"", nil]
|
||||
atIndex: 0 forKey: @""];
|
||||
result = [renderer render: element];
|
||||
testEquals(result, @"ELEM:;1\r\n");
|
||||
|
||||
/* 8.c. a variant thereof: nil array */
|
||||
[element setValues: nil atIndex: 0 forKey: @""];
|
||||
result = [renderer render: element];
|
||||
testEquals(result, @"ELEM:;1\r\n");
|
||||
|
||||
/* 9. values with 1 non-empty ordered value and another empty one */
|
||||
element = [CardElement elementWithTag: @"elem"];
|
||||
[element setValues: [NSArray arrayWithObjects: @"1", nil]
|
||||
atIndex: 0 forKey: @""];
|
||||
[element setValues: [NSArray arrayWithObjects: nil]
|
||||
atIndex: 1 forKey: @""];
|
||||
result = [renderer render: element];
|
||||
testEquals(result, @"ELEM:1\r\n");
|
||||
|
||||
/* 10. named values with 1 nil value, 1 empty value and another non-nil one */
|
||||
element = [CardElement elementWithTag: @"elem"];
|
||||
[element setSingleValue: nil forKey: @"empty"];
|
||||
[element setSingleValue: nil forKey: @"empty2"];
|
||||
[element setSingleValue: @"coucou" forKey: @"nonempty"];
|
||||
result = [renderer render: element];
|
||||
testEquals(result, @"ELEM:NONEMPTY=coucou\r\n");
|
||||
|
||||
/** tests about parameters handling could be nice */
|
||||
}
|
||||
|
||||
- (void) test_parsing
|
||||
|
@ -87,52 +140,62 @@
|
|||
CardElement *element;
|
||||
NSString *versit;
|
||||
|
||||
versit = @"BEGIN:group1\r\nELEMENT:value\r\nEND:group1\r\n";
|
||||
versit = @"BEGIN:GROUP1\r\nELEMENT:value\r\nEND:GROUP1";
|
||||
group = [CardGroup parseSingleFromSource: versit];
|
||||
testEquals([group versitString], versit);
|
||||
element = [group firstChildWithTag: @"element"];
|
||||
testEquals([element value: 0], @"value");
|
||||
testEquals([element flattenedValueAtIndex: 0 forKey: @""], @"value");
|
||||
|
||||
versit = @"BEGIN:group1\r\nELEMENT:value1;value2\r\nEND:group1\r\n";
|
||||
versit = @"BEGIN:GROUP1\r\nELEMENT:value1;value2\r\nEND:GROUP1";
|
||||
group = [CardGroup parseSingleFromSource: versit];
|
||||
testEquals([group versitString], versit);
|
||||
element = [group firstChildWithTag: @"element"];
|
||||
testEquals([element value: 0], @"value1");
|
||||
testEquals([element value: 1], @"value2");
|
||||
testEquals([element flattenedValueAtIndex: 0 forKey: @""], @"value1");
|
||||
testEquals([element flattenedValueAtIndex: 1 forKey: @""], @"value2");
|
||||
|
||||
versit = @"BEGIN:group1\r\nELEMENT:value\\, with comma\r\nEND:group1\r\n";
|
||||
versit = @"BEGIN:GROUP1\r\nELEMENT:value\\, with comma\r\nEND:GROUP1";
|
||||
group = [CardGroup parseSingleFromSource: versit];
|
||||
testEquals([group versitString], versit);
|
||||
element = [group firstChildWithTag: @"element"];
|
||||
testEquals([element value: 0], @"value, with comma");
|
||||
testEquals([element flattenedValueAtIndex: 0 forKey: @""], @"value, with comma");
|
||||
|
||||
versit = @"BEGIN:group1\r\nELEMENT:value,with comma\r\nEND:group1\r\n";
|
||||
versit = @"BEGIN:GROUP1\r\nELEMENT:value,with comma\r\nEND:GROUP1";
|
||||
group = [CardGroup parseSingleFromSource: versit];
|
||||
testEquals([group versitString], versit);
|
||||
element = [group firstChildWithTag: @"element"];
|
||||
testEquals([element value: 0], ([NSArray arrayWithObjects: @"value", @"with comma", nil]));
|
||||
testEquals([element valuesAtIndex: 0 forKey: @""], ([NSArray arrayWithObjects: @"value", @"with comma", nil]));
|
||||
|
||||
versit = @"BEGIN:group1\r\nELEMENT:NAMED1=subvalue;NAMED2=subvalue1,subvalue2\r\nEND:group1\r\n";
|
||||
versit = @"BEGIN:GROUP1\r\nELEMENT:NAMED1=subvalue;NAMED2=subvalue1,subvalue2\r\nEND:GROUP1";
|
||||
group = [CardGroup parseSingleFromSource: versit];
|
||||
/* we avoid this test here as nothing guarantees that the order of named
|
||||
values will be preserved... */
|
||||
// testEquals([group versitString], versit);
|
||||
element = [group firstChildWithTag: @"element"];
|
||||
testEquals([element namedValue: @"named1"], @"subvalue");
|
||||
testEquals([element namedValue: @"named2"],
|
||||
testEquals([element flattenedValueAtIndex: 0 forKey: @"NAMED1"], @"subvalue");
|
||||
testEquals([element valuesAtIndex: 0 forKey: @"named2"],
|
||||
([NSArray arrayWithObjects: @"subvalue1", @"subvalue2", nil]));
|
||||
|
||||
versit = @"BEGIN:group1\r\nELEMENT;PARAM1=test:value\r\nEND:group1\r\n";
|
||||
versit = @"BEGIN:GROUP1\r\nELEMENT;PARAM1=test:value\r\nEND:GROUP1";
|
||||
group = [CardGroup parseSingleFromSource: versit];
|
||||
testEquals([group versitString], versit);
|
||||
element = [group firstChildWithTag: @"element"];
|
||||
testEquals([element value: 0], @"value");
|
||||
testEquals([element flattenedValueAtIndex: 0 forKey: @""], @"value");
|
||||
testEquals([element value: 0 ofAttribute: @"param1"], @"test");
|
||||
|
||||
versit = @"BEGIN:group1\r\nELEMENT;PARAM1=paramvalue1,paramvalue2:value\r\nEND:group1\r\n";
|
||||
versit = @"BEGIN:GROUP1\r\nELEMENT;PARAM1=paramvalue1,paramvalue2:value\r\nEND:GROUP1";
|
||||
group = [CardGroup parseSingleFromSource: versit];
|
||||
testEquals([group versitString], versit);
|
||||
element = [group firstChildWithTag: @"element"];
|
||||
testEquals([element value: 0], @"value");
|
||||
testEquals([element flattenedValueAtIndex: 0 forKey: @""], @"value");
|
||||
testEquals([element value: 0 ofAttribute: @"param1"], @"paramvalue1");
|
||||
testEquals([element value: 1 ofAttribute: @"param1"], @"paramvalue2");
|
||||
|
||||
versit = @"BEGIN:group1\r\nELEMENT;PARAM1=\"paramvalue1, with comma\":value\r\nEND:group1\r\n";
|
||||
versit = @"BEGIN:GROUP1\r\nELEMENT;PARAM1=paramvalue1\\, with comma:value\r\nEND:GROUP1";
|
||||
group = [CardGroup parseSingleFromSource: versit];
|
||||
testEquals([group versitString], versit);
|
||||
element = [group firstChildWithTag: @"element"];
|
||||
testEquals([element value: 0], @"value");
|
||||
testEquals([element value: 0 ofAttribute: @"param1"], @"value1, with comma");
|
||||
testEquals([element flattenedValueAtIndex: 0 forKey: @""], @"value");
|
||||
testEquals([element value: 0 ofAttribute: @"param1"], @"paramvalue1, with comma");
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
cardReferences = [[self cardReferences] objectEnumerator];
|
||||
|
||||
while ((currentReference = [cardReferences nextObject]))
|
||||
[cardNames addObject: [currentReference value: 0]];
|
||||
[cardNames addObject: [currentReference flattenedValuesForKey: @""]];
|
||||
|
||||
return cardNames;
|
||||
}
|
||||
|
|
|
@ -366,7 +366,7 @@
|
|||
for (i = 0; i < [elements count]; i++)
|
||||
{
|
||||
ce = [elements objectAtIndex: i];
|
||||
value = [ce value: 0];
|
||||
value = [ce flattenedValuesForKey: @""];
|
||||
|
||||
if (!aTypeToExclude)
|
||||
break;
|
||||
|
@ -398,13 +398,13 @@
|
|||
|
||||
if (max > 0)
|
||||
{
|
||||
potential = [[elements objectAtIndex: 0] value: 0];
|
||||
potential = [[elements objectAtIndex: 0] flattenedValuesForKey: @""];
|
||||
if (!workMail)
|
||||
{
|
||||
if (homeMail && homeMail == potential)
|
||||
{
|
||||
if (max > 1)
|
||||
workMail = [[elements objectAtIndex: 1] value: 0];
|
||||
workMail = [[elements objectAtIndex: 1] flattenedValuesForKey: @""];
|
||||
}
|
||||
else
|
||||
workMail = potential;
|
||||
|
@ -412,7 +412,7 @@
|
|||
if (!homeMail && max > 1)
|
||||
{
|
||||
if (workMail && workMail == potential)
|
||||
homeMail = [[elements objectAtIndex: 1] value: 0];
|
||||
homeMail = [[elements objectAtIndex: 1] flattenedValuesForKey: @""];
|
||||
else
|
||||
homeMail = potential;
|
||||
}
|
||||
|
@ -430,32 +430,32 @@
|
|||
[self _setSnapshotValue: @"homeMail" to: homeMail];
|
||||
|
||||
[self _setSnapshotValue: @"mozillaUseHtmlMail"
|
||||
to: [[card uniqueChildWithTag: @"x-mozilla-html"] value: 0]];
|
||||
to: [[card uniqueChildWithTag: @"x-mozilla-html"] flattenedValuesForKey: @""]];
|
||||
}
|
||||
|
||||
- (void) _setupOrgFields
|
||||
{
|
||||
NSMutableArray *orgServices;
|
||||
NSArray *org;
|
||||
NSRange aRange;
|
||||
unsigned int max;
|
||||
CardElement *org;
|
||||
NSString *service;
|
||||
NSUInteger count, max;
|
||||
|
||||
org = [card org];
|
||||
max = [org count];
|
||||
if (max > 0)
|
||||
[self _setSnapshotValue: @"workCompany"
|
||||
to: [org flattenedValueAtIndex: 0 forKey: @""]];
|
||||
max = [[org valuesForKey: @""] count];
|
||||
if (max > 1)
|
||||
{
|
||||
[self _setSnapshotValue: @"workCompany" to: [org objectAtIndex: 0]];
|
||||
if (max > 1)
|
||||
orgServices = [NSMutableArray arrayWithCapacity: max];
|
||||
for (count = 1; count < max; count++)
|
||||
{
|
||||
aRange = NSMakeRange (1, max - 1);
|
||||
orgServices = [NSMutableArray arrayWithArray: [org subarrayWithRange: aRange]];
|
||||
|
||||
while ([orgServices containsObject: @""])
|
||||
[orgServices removeObject: @""];
|
||||
|
||||
[self _setSnapshotValue: @"workService"
|
||||
to: [orgServices componentsJoinedByString: @", "]];
|
||||
service = [org flattenedValueAtIndex: count forKey: @""];
|
||||
if ([service length] > 0)
|
||||
[orgServices addObject: service];
|
||||
}
|
||||
|
||||
[self _setSnapshotValue: @"workService"
|
||||
to: [orgServices componentsJoinedByString: @", "]];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -481,21 +481,14 @@
|
|||
|
||||
- (void) initSnapshot
|
||||
{
|
||||
NSArray *n, *elements;
|
||||
NSArray *elements;
|
||||
CardElement *element;
|
||||
unsigned int max;
|
||||
|
||||
n = [card n];
|
||||
if (n)
|
||||
{
|
||||
max = [n count];
|
||||
if (max > 0)
|
||||
{
|
||||
[self _setSnapshotValue: @"sn" to: [n objectAtIndex: 0]];
|
||||
if (max > 1)
|
||||
[self _setSnapshotValue: @"givenName" to: [n objectAtIndex: 1]];
|
||||
}
|
||||
}
|
||||
element = [card n];
|
||||
[self _setSnapshotValue: @"sn"
|
||||
to: [element flattenedValueAtIndex: 0 forKey: @""]];
|
||||
[self _setSnapshotValue: @"givenName"
|
||||
to: [element flattenedValueAtIndex: 1 forKey: @""]];
|
||||
[self _setSnapshotValue: @"fn" to: [card fn]];
|
||||
[self _setSnapshotValue: @"nickname" to: [card nickname]];
|
||||
|
||||
|
@ -538,7 +531,7 @@
|
|||
[self _setupEmailFields];
|
||||
|
||||
[self _setSnapshotValue: @"screenName"
|
||||
to: [[card uniqueChildWithTag: @"x-aim"] value: 0]];
|
||||
to: [[card uniqueChildWithTag: @"x-aim"] flattenedValuesForKey: @""]];
|
||||
|
||||
elements = [card childrenWithTag: @"adr"
|
||||
andAttribute: @"type" havingValue: @"work"];
|
||||
|
@ -546,17 +539,17 @@
|
|||
{
|
||||
element = [elements objectAtIndex: 0];
|
||||
[self _setSnapshotValue: @"workExtendedAddress"
|
||||
to: [element value: 1]];
|
||||
to: [element flattenedValueAtIndex: 1 forKey: @""]];
|
||||
[self _setSnapshotValue: @"workStreetAddress"
|
||||
to: [element value: 2]];
|
||||
to: [element flattenedValueAtIndex: 2 forKey: @""]];
|
||||
[self _setSnapshotValue: @"workCity"
|
||||
to: [element value: 3]];
|
||||
to: [element flattenedValueAtIndex: 3 forKey: @""]];
|
||||
[self _setSnapshotValue: @"workState"
|
||||
to: [element value: 4]];
|
||||
to: [element flattenedValueAtIndex: 4 forKey: @""]];
|
||||
[self _setSnapshotValue: @"workPostalCode"
|
||||
to: [element value: 5]];
|
||||
to: [element flattenedValueAtIndex: 5 forKey: @""]];
|
||||
[self _setSnapshotValue: @"workCountry"
|
||||
to: [element value: 6]];
|
||||
to: [element flattenedValueAtIndex: 6 forKey: @""]];
|
||||
}
|
||||
|
||||
elements = [card childrenWithTag: @"adr"
|
||||
|
@ -565,17 +558,17 @@
|
|||
{
|
||||
element = [elements objectAtIndex: 0];
|
||||
[self _setSnapshotValue: @"homeExtendedAddress"
|
||||
to: [element value: 1]];
|
||||
to: [element flattenedValueAtIndex: 1 forKey: @""]];
|
||||
[self _setSnapshotValue: @"homeStreetAddress"
|
||||
to: [element value: 2]];
|
||||
to: [element flattenedValueAtIndex: 2 forKey: @""]];
|
||||
[self _setSnapshotValue: @"homeCity"
|
||||
to: [element value: 3]];
|
||||
to: [element flattenedValueAtIndex: 3 forKey: @""]];
|
||||
[self _setSnapshotValue: @"homeState"
|
||||
to: [element value: 4]];
|
||||
to: [element flattenedValueAtIndex: 4 forKey: @""]];
|
||||
[self _setSnapshotValue: @"homePostalCode"
|
||||
to: [element value: 5]];
|
||||
to: [element flattenedValueAtIndex: 5 forKey: @""]];
|
||||
[self _setSnapshotValue: @"homeCountry"
|
||||
to: [element value: 6]];
|
||||
to: [element flattenedValueAtIndex: 6 forKey: @""]];
|
||||
}
|
||||
|
||||
elements = [card childrenWithTag: @"url"];
|
||||
|
@ -591,7 +584,7 @@
|
|||
[elements count] > 0)
|
||||
{
|
||||
[self _setSnapshotValue: @"homeURL"
|
||||
to: [[elements objectAtIndex: 0] value: 0]];
|
||||
to: [[elements objectAtIndex: 0] flattenedValuesForKey: @""]];
|
||||
}
|
||||
// If we do have a "work" URL but no "home" URL but two
|
||||
// values URLs present, let's add the second one as the home URL
|
||||
|
@ -603,11 +596,11 @@
|
|||
|
||||
for (i = 0; i < [elements count]; i++)
|
||||
{
|
||||
if ([[[elements objectAtIndex: i] value: 0]
|
||||
if ([[[elements objectAtIndex: i] flattenedValuesForKey: @""]
|
||||
caseInsensitiveCompare: [snapshot objectForKey: @"workURL"]] != NSOrderedSame)
|
||||
{
|
||||
[self _setSnapshotValue: @"homeURL"
|
||||
to: [[elements objectAtIndex: i] value: 0]];
|
||||
to: [[elements objectAtIndex: i] flattenedValuesForKey: @""]];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -615,7 +608,7 @@
|
|||
|
||||
|
||||
[self _setSnapshotValue: @"calFBURL"
|
||||
to: [[card uniqueChildWithTag: @"FBURL"] value: 0]];
|
||||
to: [[card uniqueChildWithTag: @"FBURL"] flattenedValuesForKey: @""]];
|
||||
|
||||
[self _setSnapshotValue: @"title" to: [card title]];
|
||||
[self _setupOrgFields];
|
||||
|
@ -686,7 +679,7 @@
|
|||
photoURL = [NSString stringWithFormat: @"%@/photo%d",
|
||||
baseInlineURL, count];
|
||||
else
|
||||
photoURL = [photo value: 0];
|
||||
photoURL = [photo flattenedValuesForKey: @""];
|
||||
[photosURL addObject: photoURL];
|
||||
}
|
||||
}
|
||||
|
@ -721,17 +714,16 @@
|
|||
CardElement *phone;
|
||||
|
||||
phone = [self _elementWithTag: @"tel" ofType: @"work"];
|
||||
[phone setValue: 0 to: [snapshot objectForKey: @"telephoneNumber"]];
|
||||
[phone setSingleValue: [snapshot objectForKey: @"telephoneNumber"] forKey: @""];
|
||||
phone = [self _elementWithTag: @"tel" ofType: @"home"];
|
||||
[phone setValue: 0 to: [snapshot objectForKey: @"homeTelephoneNumber"]];
|
||||
[phone setSingleValue: [snapshot objectForKey: @"homeTelephoneNumber"] forKey: @""];
|
||||
phone = [self _elementWithTag: @"tel" ofType: @"cell"];
|
||||
[phone setValue: 0 to: [snapshot objectForKey: @"mobile"]];
|
||||
[phone setSingleValue: [snapshot objectForKey: @"mobile"] forKey: @""];
|
||||
phone = [self _elementWithTag: @"tel" ofType: @"fax"];
|
||||
[phone setValue: 0
|
||||
to: [snapshot objectForKey: @"facsimileTelephoneNumber"]];
|
||||
[phone setSingleValue: [snapshot objectForKey: @"facsimileTelephoneNumber"]
|
||||
forKey: @""];
|
||||
phone = [self _elementWithTag: @"tel" ofType: @"pager"];
|
||||
[phone setValue: 0
|
||||
to: [snapshot objectForKey: @"pager"]];
|
||||
[phone setSingleValue: [snapshot objectForKey: @"pager"] forKey: @""];
|
||||
}
|
||||
|
||||
- (void) _saveEmails
|
||||
|
@ -739,9 +731,9 @@
|
|||
CardElement *workMail, *homeMail;
|
||||
|
||||
workMail = [self _elementWithTag: @"email" ofType: @"work"];
|
||||
[workMail setValue: 0 to: [snapshot objectForKey: @"workMail"]];
|
||||
[workMail setSingleValue: [snapshot objectForKey: @"workMail"] forKey: @""];
|
||||
homeMail = [self _elementWithTag: @"email" ofType: @"home"];
|
||||
[homeMail setValue: 0 to: [snapshot objectForKey: @"homeMail"]];
|
||||
[homeMail setSingleValue: [snapshot objectForKey: @"homeMail"] forKey: @""];
|
||||
if (preferredEmail)
|
||||
{
|
||||
if ([preferredEmail isEqualToString: @"work"])
|
||||
|
@ -751,8 +743,8 @@
|
|||
}
|
||||
|
||||
[[card uniqueChildWithTag: @"x-mozilla-html"]
|
||||
setValue: 0
|
||||
to: [snapshot objectForKey: @"mozillaUseHtmlMail"]];
|
||||
setSingleValue: [snapshot objectForKey: @"mozillaUseHtmlMail"]
|
||||
forKey: @""];
|
||||
}
|
||||
|
||||
- (void) _saveSnapshot
|
||||
|
@ -773,20 +765,32 @@
|
|||
[card setTz: [snapshot objectForKey: @"tz"]];
|
||||
|
||||
element = [self _elementWithTag: @"adr" ofType: @"home"];
|
||||
[element setValue: 1 to: [snapshot objectForKey: @"homeExtendedAddress"]];
|
||||
[element setValue: 2 to: [snapshot objectForKey: @"homeStreetAddress"]];
|
||||
[element setValue: 3 to: [snapshot objectForKey: @"homeCity"]];
|
||||
[element setValue: 4 to: [snapshot objectForKey: @"homeState"]];
|
||||
[element setValue: 5 to: [snapshot objectForKey: @"homePostalCode"]];
|
||||
[element setValue: 6 to: [snapshot objectForKey: @"homeCountry"]];
|
||||
[element setSingleValue: [snapshot objectForKey: @"homeExtendedAddress"]
|
||||
atIndex: 1 forKey: @""];
|
||||
[element setSingleValue: [snapshot objectForKey: @"homeStreetAddress"]
|
||||
atIndex: 2 forKey: @""];
|
||||
[element setSingleValue: [snapshot objectForKey: @"homeCity"]
|
||||
atIndex: 3 forKey: @""];
|
||||
[element setSingleValue: [snapshot objectForKey: @"homeState"]
|
||||
atIndex: 4 forKey: @""];
|
||||
[element setSingleValue: [snapshot objectForKey: @"homePostalCode"]
|
||||
atIndex: 5 forKey: @""];
|
||||
[element setSingleValue: [snapshot objectForKey: @"homeCountry"]
|
||||
atIndex: 6 forKey: @""];
|
||||
|
||||
element = [self _elementWithTag: @"adr" ofType: @"work"];
|
||||
[element setValue: 1 to: [snapshot objectForKey: @"workExtendedAddress"]];
|
||||
[element setValue: 2 to: [snapshot objectForKey: @"workStreetAddress"]];
|
||||
[element setValue: 3 to: [snapshot objectForKey: @"workCity"]];
|
||||
[element setValue: 4 to: [snapshot objectForKey: @"workState"]];
|
||||
[element setValue: 5 to: [snapshot objectForKey: @"workPostalCode"]];
|
||||
[element setValue: 6 to: [snapshot objectForKey: @"workCountry"]];
|
||||
[element setSingleValue: [snapshot objectForKey: @"workExtendedAddress"]
|
||||
atIndex: 1 forKey: @""];
|
||||
[element setSingleValue: [snapshot objectForKey: @"workStreetAddress"]
|
||||
atIndex: 2 forKey: @""];
|
||||
[element setSingleValue: [snapshot objectForKey: @"workCity"]
|
||||
atIndex: 3 forKey: @""];
|
||||
[element setSingleValue: [snapshot objectForKey: @"workState"]
|
||||
atIndex: 4 forKey: @""];
|
||||
[element setSingleValue: [snapshot objectForKey: @"workPostalCode"]
|
||||
atIndex: 5 forKey: @""];
|
||||
[element setSingleValue: [snapshot objectForKey: @"workCountry"]
|
||||
atIndex: 6 forKey: @""];
|
||||
|
||||
element = [CardElement simpleElementWithTag: @"fburl"
|
||||
value: [snapshot objectForKey: @"calFBURL"]];
|
||||
|
@ -799,13 +803,13 @@
|
|||
[self _savePhoneValues];
|
||||
[self _saveEmails];
|
||||
[[self _elementWithTag: @"url" ofType: @"home"]
|
||||
setValue: 0 to: [snapshot objectForKey: @"homeURL"]];
|
||||
setSingleValue: [snapshot objectForKey: @"homeURL"] forKey: @""];
|
||||
[[self _elementWithTag: @"url" ofType: @"work"]
|
||||
setValue: 0 to: [snapshot objectForKey: @"workURL"]];
|
||||
setSingleValue: [snapshot objectForKey: @"workURL"] forKey: @""];
|
||||
|
||||
[[card uniqueChildWithTag: @"x-aim"]
|
||||
setValue: 0
|
||||
to: [snapshot objectForKey: @"screenName"]];
|
||||
setSingleValue: [snapshot objectForKey: @"screenName"]
|
||||
forKey: @""];
|
||||
}
|
||||
|
||||
- (id <WOActionResults>) saveAction
|
||||
|
@ -814,7 +818,6 @@
|
|||
id result;
|
||||
NSString *jsRefreshMethod;
|
||||
SoSecurityManager *sm;
|
||||
NSException *ex;
|
||||
|
||||
contact = [self clientObject];
|
||||
card = [contact vCard];
|
||||
|
@ -836,7 +839,7 @@
|
|||
if (![sm validatePermission: SoPerm_AddDocumentsImagesAndFiles
|
||||
onObject: componentAddressBook
|
||||
inContext: context])
|
||||
ex = [contact moveToFolder: (SOGoGCSFolder *)componentAddressBook]; // TODO: handle exception
|
||||
[contact moveToFolder: (SOGoGCSFolder *)componentAddressBook]; // TODO: handle exception
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,14 +58,6 @@
|
|||
|
||||
/* accessors */
|
||||
|
||||
- (NSString *) _cardStringWithLabel: (NSString *) label
|
||||
value: (NSString *) value
|
||||
{
|
||||
return [self _cardStringWithLabel: label
|
||||
value: value
|
||||
url: nil];
|
||||
}
|
||||
|
||||
- (NSString *) _cardStringWithLabel: (NSString *) label
|
||||
value: (NSString *) value
|
||||
url: (NSString *) url
|
||||
|
@ -89,6 +81,14 @@
|
|||
return cardString;
|
||||
}
|
||||
|
||||
- (NSString *) _cardStringWithLabel: (NSString *) label
|
||||
value: (NSString *) value
|
||||
{
|
||||
return [self _cardStringWithLabel: label
|
||||
value: value
|
||||
url: nil];
|
||||
}
|
||||
|
||||
- (NSString *) displayName
|
||||
{
|
||||
return [self _cardStringWithLabel: @"Display Name:"
|
||||
|
@ -103,25 +103,24 @@
|
|||
|
||||
- (NSString *) fullName
|
||||
{
|
||||
NSArray *n;
|
||||
NSString *fn;
|
||||
unsigned int max;
|
||||
CardElement *n;
|
||||
NSString *fn, *firstName, *lastName;
|
||||
|
||||
fn = [card fn];
|
||||
if ([fn length] == 0)
|
||||
{
|
||||
n = [card n];
|
||||
if (n)
|
||||
{
|
||||
max = [n count];
|
||||
if (max > 0)
|
||||
{
|
||||
if (max > 1)
|
||||
fn = [NSString stringWithFormat: @"%@ %@", [n objectAtIndex: 1], [n objectAtIndex: 0]];
|
||||
else
|
||||
fn = [n objectAtIndex: 0];
|
||||
}
|
||||
}
|
||||
lastName = [n flattenedValueAtIndex: 0 forKey: @""];
|
||||
firstName = [n flattenedValueAtIndex: 1 forKey: @""];
|
||||
if ([firstName length] > 0)
|
||||
{
|
||||
if ([lastName length] > 0)
|
||||
fn = [NSString stringWithFormat: @"%@ %@", firstName, lastName];
|
||||
else
|
||||
fn = firstName;
|
||||
}
|
||||
else
|
||||
fn = lastName;
|
||||
}
|
||||
|
||||
return fn;
|
||||
|
@ -172,7 +171,7 @@
|
|||
|
||||
for (i = 0; i < [emails count]; i++)
|
||||
{
|
||||
email = [[emails objectAtIndex: i] value: 0];
|
||||
email = [[emails objectAtIndex: i] flattenedValuesForKey: @""];
|
||||
|
||||
if ([email caseInsensitiveCompare: [card preferredEMail]] != NSOrderedSame)
|
||||
{
|
||||
|
@ -192,7 +191,7 @@
|
|||
{
|
||||
NSString *screenName, *goim;
|
||||
|
||||
screenName = [[card uniqueChildWithTag: @"x-aim"] value: 0];
|
||||
screenName = [[card uniqueChildWithTag: @"x-aim"] flattenedValuesForKey: @""];
|
||||
if ([screenName length] > 0)
|
||||
goim = [NSString stringWithFormat: @"<a href=\"aim:goim?screenname=%@\""
|
||||
@">%@</a>", screenName, screenName];
|
||||
|
@ -250,7 +249,7 @@
|
|||
for (i = 0; i < [elements count]; i++)
|
||||
{
|
||||
ce = [elements objectAtIndex: i];
|
||||
phone = [ce value: 0];
|
||||
phone = [ce flattenedValuesForKey: @""];
|
||||
|
||||
if (!aTypeToExclude)
|
||||
break;
|
||||
|
@ -315,17 +314,23 @@
|
|||
|
||||
- (NSString *) homePobox
|
||||
{
|
||||
return [self _cardStringWithLabel: nil value: [homeAdr value: 0]];
|
||||
return [self _cardStringWithLabel: nil
|
||||
value: [homeAdr flattenedValueAtIndex: 0
|
||||
forKey: @""]];
|
||||
}
|
||||
|
||||
- (NSString *) homeExtendedAddress
|
||||
{
|
||||
return [self _cardStringWithLabel: nil value: [homeAdr value: 1]];
|
||||
return [self _cardStringWithLabel: nil
|
||||
value: [homeAdr flattenedValueAtIndex: 1
|
||||
forKey: @""]];
|
||||
}
|
||||
|
||||
- (NSString *) homeStreetAddress
|
||||
{
|
||||
return [self _cardStringWithLabel: nil value: [homeAdr value: 2]];
|
||||
return [self _cardStringWithLabel: nil
|
||||
value: [homeAdr flattenedValueAtIndex: 2
|
||||
forKey: @""]];
|
||||
}
|
||||
|
||||
- (NSString *) homeCityAndProv
|
||||
|
@ -333,8 +338,8 @@
|
|||
NSString *city, *prov;
|
||||
NSMutableString *data;
|
||||
|
||||
city = [homeAdr value: 3];
|
||||
prov = [homeAdr value: 4];
|
||||
city = [homeAdr flattenedValueAtIndex: 3 forKey: @""];
|
||||
prov = [homeAdr flattenedValueAtIndex: 4 forKey: @""];
|
||||
|
||||
data = [NSMutableString string];
|
||||
[data appendString: city];
|
||||
|
@ -350,8 +355,8 @@
|
|||
NSString *postalCode, *country;
|
||||
NSMutableString *data;
|
||||
|
||||
postalCode = [homeAdr value: 5];
|
||||
country = [homeAdr value: 6];
|
||||
postalCode = [homeAdr flattenedValueAtIndex: 5 forKey: @""];
|
||||
country = [homeAdr flattenedValueAtIndex: 6 forKey: @""];
|
||||
|
||||
data = [NSMutableString string];
|
||||
[data appendString: postalCode];
|
||||
|
@ -391,7 +396,7 @@
|
|||
andAttribute: @"type"
|
||||
havingValue: aType];
|
||||
if ([elements count] > 0)
|
||||
url = [[elements objectAtIndex: 0] value: 0];
|
||||
url = [[elements objectAtIndex: 0] flattenedValuesForKey: @""];
|
||||
else
|
||||
url = nil;
|
||||
|
||||
|
@ -416,7 +421,7 @@
|
|||
workURL = nil;
|
||||
|
||||
if ([elements count] > 0)
|
||||
workURL = [[elements objectAtIndex: 0] value: 0];
|
||||
workURL = [[elements objectAtIndex: 0] flattenedValuesForKey: @""];
|
||||
|
||||
elements = [card childrenWithTag: @"url"];
|
||||
|
||||
|
@ -424,9 +429,10 @@
|
|||
{
|
||||
for (i = 0; i < [elements count]; i++)
|
||||
{
|
||||
if ([[[elements objectAtIndex: i] value: 0] caseInsensitiveCompare: workURL] != NSOrderedSame)
|
||||
if ([[[elements objectAtIndex: i] flattenedValuesForKey: @""]
|
||||
caseInsensitiveCompare: workURL] != NSOrderedSame)
|
||||
{
|
||||
s = [[elements objectAtIndex: i] value: 0];
|
||||
s = [[elements objectAtIndex: i] flattenedValuesForKey: @""];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -434,7 +440,7 @@
|
|||
}
|
||||
else if (!workURL && [elements count] > 0)
|
||||
{
|
||||
s = [[elements objectAtIndex: 0] value: 0];
|
||||
s = [[elements objectAtIndex: 0] flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
if (s && [s length] > 0)
|
||||
|
@ -474,18 +480,23 @@
|
|||
- (NSString *) workService
|
||||
{
|
||||
NSMutableArray *orgServices;
|
||||
NSArray *org;
|
||||
NSRange aRange;
|
||||
NSString *services;
|
||||
NSArray *values;
|
||||
CardElement *org;
|
||||
NSString *service, *services;
|
||||
NSUInteger count, max;
|
||||
|
||||
org = [card org];
|
||||
if (org && [org count] > 1)
|
||||
values = [org valuesForKey: @""];
|
||||
max = [values count];
|
||||
if (max > 1)
|
||||
{
|
||||
aRange = NSMakeRange(1, [org count]-1);
|
||||
orgServices = [NSMutableArray arrayWithArray: [org subarrayWithRange: aRange]];
|
||||
|
||||
while ([orgServices containsObject: @""])
|
||||
[orgServices removeObject: @""];
|
||||
orgServices = [NSMutableArray arrayWithCapacity: max];
|
||||
for (count = 1; count < max; count++)
|
||||
{
|
||||
service = [org flattenedValueAtIndex: count forKey: @""];
|
||||
if ([service length] > 0)
|
||||
[orgServices addObject: service];
|
||||
}
|
||||
|
||||
services = [orgServices componentsJoinedByString: @", "];
|
||||
}
|
||||
|
@ -497,13 +508,12 @@
|
|||
|
||||
- (NSString *) workCompany
|
||||
{
|
||||
NSArray *org;
|
||||
CardElement *org;
|
||||
NSString *company;
|
||||
|
||||
org = [card org];
|
||||
if (org && [org count] > 0)
|
||||
company = [org objectAtIndex: 0];
|
||||
else
|
||||
company = [org flattenedValueAtIndex: 0 forKey: @""];
|
||||
if ([company length] == 0)
|
||||
company = nil;
|
||||
|
||||
return [self _cardStringWithLabel: nil value: company];
|
||||
|
@ -511,17 +521,23 @@
|
|||
|
||||
- (NSString *) workPobox
|
||||
{
|
||||
return [self _cardStringWithLabel: nil value: [workAdr value: 0]];
|
||||
return [self _cardStringWithLabel: nil
|
||||
value: [workAdr flattenedValueAtIndex: 0
|
||||
forKey: @""]];
|
||||
}
|
||||
|
||||
- (NSString *) workExtendedAddress
|
||||
{
|
||||
return [self _cardStringWithLabel: nil value: [workAdr value: 1]];
|
||||
return [self _cardStringWithLabel: nil
|
||||
value: [workAdr flattenedValueAtIndex: 1
|
||||
forKey: @""]];
|
||||
}
|
||||
|
||||
- (NSString *) workStreetAddress
|
||||
{
|
||||
return [self _cardStringWithLabel: nil value: [workAdr value: 2]];
|
||||
return [self _cardStringWithLabel: nil
|
||||
value: [workAdr flattenedValueAtIndex: 2
|
||||
forKey: @""]];
|
||||
}
|
||||
|
||||
- (NSString *) workCityAndProv
|
||||
|
@ -529,8 +545,8 @@
|
|||
NSString *city, *prov;
|
||||
NSMutableString *data;
|
||||
|
||||
city = [workAdr value: 3];
|
||||
prov = [workAdr value: 4];
|
||||
city = [workAdr flattenedValueAtIndex: 3 forKey: @""];
|
||||
prov = [workAdr flattenedValueAtIndex: 4 forKey: @""];
|
||||
|
||||
data = [NSMutableString string];
|
||||
[data appendString: city];
|
||||
|
@ -546,8 +562,8 @@
|
|||
NSString *postalCode, *country;
|
||||
NSMutableString *data;
|
||||
|
||||
postalCode = [workAdr value: 5];
|
||||
country = [workAdr value: 6];
|
||||
postalCode = [workAdr flattenedValueAtIndex: 5 forKey: @""];
|
||||
country = [workAdr flattenedValueAtIndex: 6 forKey: @""];
|
||||
|
||||
data = [NSMutableString string];
|
||||
[data appendString: postalCode];
|
||||
|
@ -681,7 +697,7 @@
|
|||
photoURL = [NSString stringWithFormat: @"%@/photo%d",
|
||||
baseInlineURL, count];
|
||||
else
|
||||
photoURL = [photo value: 0];
|
||||
photoURL = [photo flattenedValuesForKey: @""];
|
||||
[photosURL addObject: photoURL];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@
|
|||
[newWorkMail setTag: @"email"];
|
||||
[newWorkMail addType: @"work"];
|
||||
[newCard addChild: newWorkMail];
|
||||
[newWorkMail setValue: 0 to: workMail];
|
||||
[newWorkMail setSingleValue: workMail forKey: @""];
|
||||
[newCard setFn: fn];
|
||||
|
||||
// Add vCard to current folder
|
||||
|
|
|
@ -268,10 +268,9 @@
|
|||
|
||||
- (NSString *) formattedMailtoString: (NGVCard *) card
|
||||
{
|
||||
NSString *email;
|
||||
NSString *firstName, *lastName, *email;
|
||||
NSMutableString *fn, *rc = nil;
|
||||
NSArray *n;
|
||||
unsigned int max;
|
||||
CardElement *n;
|
||||
|
||||
if ([card isKindOfClass: [NGVCard class]])
|
||||
email = [card preferredEMail];
|
||||
|
@ -291,17 +290,17 @@
|
|||
&& [card isKindOfClass: [NGVCard class]])
|
||||
{
|
||||
n = [card n];
|
||||
if (n)
|
||||
lastName = [n flattenedValueAtIndex: 0 forKey: @""];
|
||||
firstName = [n flattenedValueAtIndex: 1 forKey: @""];
|
||||
if ([firstName length] > 0)
|
||||
{
|
||||
max = [n count];
|
||||
if (max > 0)
|
||||
{
|
||||
if (max > 1)
|
||||
fn = [NSMutableString stringWithFormat: @"%@ %@", [n objectAtIndex: 1], [n objectAtIndex: 0]];
|
||||
else
|
||||
fn = [NSMutableString stringWithString: [n objectAtIndex: 0]];
|
||||
}
|
||||
if ([lastName length] > 0)
|
||||
fn = [NSMutableString stringWithFormat: @"%@ %@", firstName, lastName];
|
||||
else
|
||||
fn = [NSMutableString stringWithString: firstName];
|
||||
}
|
||||
else if ([lastName length] > 0)
|
||||
fn = [NSMutableString stringWithString: lastName];
|
||||
}
|
||||
if ([fn length] > 0)
|
||||
{
|
||||
|
|
|
@ -292,13 +292,13 @@ iRANGE(2);
|
|||
|
||||
- (void) _loadCategories
|
||||
{
|
||||
NSString *compCategories, *simpleCategory;
|
||||
NSString *simpleCategory;
|
||||
NSArray *compCategories;
|
||||
|
||||
compCategories = [component categories];
|
||||
if ([compCategories length] > 0)
|
||||
if ([compCategories count] > 0)
|
||||
{
|
||||
simpleCategory = [[compCategories componentsSeparatedByString: @","]
|
||||
objectAtIndex: 0];
|
||||
simpleCategory = [compCategories objectAtIndex: 0];
|
||||
ASSIGN (category, simpleCategory);
|
||||
}
|
||||
}
|
||||
|
@ -405,7 +405,7 @@ iRANGE(2);
|
|||
{
|
||||
repeatType = @"3";
|
||||
|
||||
if ([[rule namedValue: @"bymonth"] length])
|
||||
if ([[rule flattenedValuesForKey: @"bymonth"] length])
|
||||
{
|
||||
if ([[rule byDay] length])
|
||||
{
|
||||
|
@ -420,13 +420,13 @@ iRANGE(2);
|
|||
[self setRepeat2: @"1"];
|
||||
[self setRepeat5: [NSString stringWithFormat: @"%d", firstOccurrence]];
|
||||
[self setRepeat6: [NSString stringWithFormat: @"%d", [dayMask firstDay]]];
|
||||
[self setRepeat7: [NSString stringWithFormat: @"%d", [[rule namedValue: @"bymonth"] intValue]-1]];
|
||||
[self setRepeat7: [NSString stringWithFormat: @"%d", [[rule flattenedValuesForKey: @"bymonth"] intValue]-1]];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self setRepeat2: @"0"];
|
||||
[self setRepeat3: [rule namedValue: @"bymonthday"]];
|
||||
[self setRepeat4: [NSString stringWithFormat: @"%d", [[rule namedValue: @"bymonth"] intValue]-1]];
|
||||
[self setRepeat3: [rule flattenedValuesForKey: @"bymonthday"]];
|
||||
[self setRepeat4: [NSString stringWithFormat: @"%d", [[rule flattenedValuesForKey: @"bymonth"] intValue]-1]];
|
||||
}
|
||||
}
|
||||
else if ([rule repeatInterval] == 1)
|
||||
|
@ -440,7 +440,7 @@ iRANGE(2);
|
|||
{
|
||||
repeat = @"CUSTOM";
|
||||
[self setRange1: @"1"];
|
||||
[self setRange2: [rule namedValue: @"count"]];
|
||||
[self setRange2: [rule flattenedValuesForKey: @"count"]];
|
||||
}
|
||||
else if ([rule untilDate])
|
||||
{
|
||||
|
@ -519,7 +519,7 @@ iRANGE(2);
|
|||
|| [reminderAction isEqualToString: @"email"])
|
||||
&& [[aTrigger valueType] caseInsensitiveCompare: @"DURATION"] == NSOrderedSame)
|
||||
{
|
||||
duration = [aTrigger value];
|
||||
duration = [aTrigger flattenedValuesForKey: @""];
|
||||
i = [reminderValues indexOfObject: duration];
|
||||
|
||||
if (i == NSNotFound || [reminderAction isEqualToString: @"email"])
|
||||
|
@ -611,8 +611,7 @@ iRANGE(2);
|
|||
ASSIGN (privacy, [component accessClass]);
|
||||
ASSIGN (priority, [component priority]);
|
||||
ASSIGN (status, [component status]);
|
||||
ASSIGN (categories,
|
||||
[[component categories] vCardSubvaluesWithSeparator: ',']);
|
||||
ASSIGN (categories, [component categories]);
|
||||
if ([[[component organizer] rfc822Email] length])
|
||||
{
|
||||
ASSIGN (organizer, [component organizer]);
|
||||
|
@ -1853,6 +1852,7 @@ RANGE(2);
|
|||
|
||||
{
|
||||
int type, range;
|
||||
NSMutableArray *values;
|
||||
|
||||
// We decode the range
|
||||
range = [[self range1] intValue];
|
||||
|
@ -1990,14 +1990,21 @@ RANGE(2);
|
|||
occurence = [[self repeat3] intValue] + 1;
|
||||
if (occurence > 5) // the first/second/third/fourth/fifth ..
|
||||
occurence = -1; // the last ..
|
||||
[theRule setNamedValue: @"byday"
|
||||
to: [NSString stringWithFormat: @"%d%@",
|
||||
occurence, day]];
|
||||
[theRule setSingleValue: [NSString stringWithFormat: @"%d%@",
|
||||
occurence, day]
|
||||
forKey: @"byday"];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([[self repeat5] intValue] > 0)
|
||||
[theRule setNamedValue: @"bymonthday" to: [self repeat5]];
|
||||
{
|
||||
values = [[[self repeat5]
|
||||
componentsSeparatedByString: @","]
|
||||
mutableCopy];
|
||||
[theRule setValues: values
|
||||
atIndex: 0 forKey: @"bymonthday"];
|
||||
[values release];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2037,22 +2044,27 @@ RANGE(2);
|
|||
occurence = [[self repeat5] intValue] + 1;
|
||||
if (occurence > 5) // the first/second/third/fourth/fifth ..
|
||||
occurence = -1; // the last ..
|
||||
[theRule setNamedValue: @"byday"
|
||||
to: [NSString stringWithFormat: @"%d%@",
|
||||
occurence, day]];
|
||||
[theRule setNamedValue: @"bymonth"
|
||||
to: [NSString stringWithFormat: @"%d",
|
||||
[[self repeat7] intValue] + 1]];
|
||||
[theRule setSingleValue: [NSString stringWithFormat: @"%d%@",
|
||||
occurence, day]
|
||||
forKey: @"byday"];
|
||||
[theRule setSingleValue: [NSString stringWithFormat: @"%d",
|
||||
[[self repeat7] intValue] + 1]
|
||||
forKey: @"bymonth"];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([[self repeat3] intValue] > 0
|
||||
&& [[self repeat4] intValue] > 0)
|
||||
{
|
||||
[theRule setNamedValue: @"bymonthday"
|
||||
to: [self repeat3]];
|
||||
[theRule setNamedValue: @"bymonth"
|
||||
to: [NSString stringWithFormat: @"%d", ([[self repeat4] intValue]+1)]];
|
||||
values = [[[self repeat3]
|
||||
componentsSeparatedByString: @","]
|
||||
mutableCopy];
|
||||
[theRule setValues: values atIndex: 0
|
||||
forKey: @"bymonthday"];
|
||||
[values release];
|
||||
[theRule setSingleValue: [NSString stringWithFormat: @"%d",
|
||||
[[self repeat4] intValue] + 1]
|
||||
forKey: @"bymonth"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2111,7 +2123,7 @@ RANGE(2);
|
|||
[component setComment: comment];
|
||||
[component setAttach: attachUrl];
|
||||
[component setAccessClass: privacy];
|
||||
[component setCategories: category];
|
||||
[component setCategories: categories];
|
||||
[self _handleAttendeesEdition];
|
||||
[self _handleOrganizer];
|
||||
clientObject = [self clientObject];
|
||||
|
@ -2146,7 +2158,7 @@ RANGE(2);
|
|||
if ([aValue length]) {
|
||||
// Predefined alarm
|
||||
[anAlarm setAction: @"DISPLAY"];
|
||||
[aTrigger setValue: aValue];
|
||||
[aTrigger setSingleValue: aValue forKey: @""];
|
||||
}
|
||||
else {
|
||||
// Custom alarm
|
||||
|
@ -2177,7 +2189,7 @@ RANGE(2);
|
|||
aValue = [aValue stringByAppendingFormat: @"%i%@",
|
||||
[reminderQuantity intValue],
|
||||
[reminderUnit substringToIndex: 1]];
|
||||
[aTrigger setValue: aValue];
|
||||
[aTrigger setSingleValue: aValue forKey: @""];
|
||||
[aTrigger setRelationType: reminderRelation];
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue