]> err.no Git - scalable-opengroupware.org/blob - SOPE/NGCards/CardElement.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1021 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / SOPE / NGCards / CardElement.m
1 /* CardElement.m - this file is part of SOPE
2  *
3  * Copyright (C) 2006 Inverse groupe conseil
4  *
5  * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
6  *
7  * This file is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This file is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #import <Foundation/NSArray.h>
24 #import <Foundation/NSDictionary.h>
25 #import <Foundation/NSRange.h>
26 #import <Foundation/NSString.h>
27
28 #import "NSArray+NGCards.h"
29 #import "NSDictionary+NGCards.h"
30 #import "CardVersitRenderer.h"
31
32 #import "CardElement.h"
33 #import "CardGroup.h"
34
35 @implementation CardElement
36
37 + (id) elementWithTag: (NSString *) aTag
38 {
39   id newElement;
40
41   newElement = [self new];
42   [newElement autorelease];
43   [newElement setTag: aTag];
44
45   return newElement;
46 }
47
48 + (id) simpleElementWithTag: (NSString *) aTag
49                       value: (NSString *) aValue
50 {
51   id newElement;
52
53   newElement = [self elementWithTag: aTag];
54   [newElement addValue: aValue];
55
56   return newElement;
57 }
58
59 + (id) simpleElementWithTag: (NSString *) aTag
60                  singleType: (NSString *) aType
61                       value: (NSString *) aValue
62 {
63   id newElement;
64
65   newElement = [self simpleElementWithTag: aTag
66                      value: aValue];
67   [newElement addType: aType];
68
69   return newElement;
70 }
71
72 + (id) elementWithTag: (NSString *) aTag
73            attributes: (NSDictionary *) someAttributes
74                values: (NSArray *) someValues
75 {
76   id newElement;
77
78   newElement = [self new];
79   [newElement autorelease];
80   [newElement setTag: aTag];
81   [newElement addAttributes: someAttributes];
82   [newElement addValues: someValues];
83
84   return newElement;
85 }
86
87 - (id) init
88 {
89   if ((self = [super init]))
90     {
91       parent = nil;
92       tag = nil;
93       group = nil;
94       values = [NSMutableArray new];
95       attributes = [NSMutableDictionary new];
96     }
97
98   return self;
99 }
100
101 - (void) dealloc
102 {
103   if (tag)
104     [tag release];
105   [values release];
106   [attributes release];
107   [super dealloc];
108 }
109
110 - (void) setParent: (CardGroup *) aParent
111 {
112   parent = aParent;
113 }
114
115 - (CardGroup *) parent
116 {
117   return parent;
118 }
119
120 - (void) setTag: (NSString *) aTag
121 {
122   if (tag)
123     [tag release];
124   tag = aTag;
125   if (tag)
126     [tag retain];
127 }
128
129 - (void) setGroup: (NSString *) aGroup
130 {
131   if (group)
132     [group release];
133   group = aGroup;
134   if (group)
135     [group retain];
136 }
137
138 - (NSString *) group
139 {
140   return group;
141 }
142
143 - (void) addValue: (NSString *) aValue
144 {
145   [values addObject: aValue];
146 }
147
148 - (void) addValues: (NSArray *) someValues
149 {
150   [values addObjectsFromArray: someValues];
151 }
152
153 - (void) addAttribute: (NSString *) anAttribute
154                 value: (NSString *) aType
155 {
156   NSMutableArray *attrValues;
157
158   attrValues = [attributes objectForCaseInsensitiveKey: anAttribute];
159   if (!attrValues)
160     {
161       attrValues = [NSMutableArray new];
162       [attrValues autorelease];
163       [attributes setObject: attrValues forKey: anAttribute];
164     }
165
166   [attrValues addObject: aType];
167 }
168
169 - (void) removeValue: (NSString *) aValue
170        fromAttribute: (NSString *) anAttribute
171 {
172   NSMutableArray *attrValues;
173   NSString *currentValue;
174
175   attrValues = [attributes objectForCaseInsensitiveKey: anAttribute];
176   if (attrValues)
177     {
178       currentValue = [attrValues valueForCaseInsensitiveString: aValue];
179       while (currentValue)
180         {
181           [attrValues removeObject: currentValue];
182           currentValue = [attrValues valueForCaseInsensitiveString: aValue];
183         }
184     }
185 }
186
187 - (void) addAttributes: (NSDictionary *) someAttributes
188 {
189   NSEnumerator *keys;
190   NSString *currentKey;
191   NSMutableArray *oldValues;
192   NSArray *newValues;
193
194   keys = [[someAttributes allKeys] objectEnumerator];
195   currentKey = [keys nextObject];
196   while (currentKey)
197     {
198       oldValues = [attributes objectForCaseInsensitiveKey: currentKey];
199       newValues = [someAttributes objectForKey: currentKey];
200       if (oldValues)
201         [oldValues addObjectsFromArray: newValues];
202       else
203         [attributes setObject: newValues forKey: currentKey];
204       currentKey = [keys nextObject];
205     }
206 }
207
208 - (void) addType: (NSString *) aType
209 {
210   [self addAttribute: @"type" value: aType];
211 }
212
213 - (NSString *) tag
214 {
215   return tag;
216 }
217
218 - (NSArray *) values
219 {
220   return values;
221 }
222
223 - (NSDictionary *) attributes
224 {
225   return attributes;
226 }
227
228 - (BOOL) hasAttribute: (NSString *) anAttribute
229           havingValue: (NSString *) aValue
230 {
231   NSArray *attribute;
232
233   attribute = [attributes objectForCaseInsensitiveKey: anAttribute];
234
235   return (attribute && [attribute hasCaseInsensitiveString: aValue]);
236 }
237
238 - (void) setValue: (unsigned int) anInt
239                to: (NSString *) aValue
240 {
241   while ([values count] <= anInt)
242     [self addValue: @""];
243   [values replaceObjectAtIndex: anInt withObject: aValue];
244 }
245
246 - (NSString *) value: (unsigned int) anInt
247 {
248   NSString *value;
249
250   if ([values count] <= anInt)
251     value = @"";
252   else
253     value = [values objectAtIndex: anInt];
254
255   return value;
256 }
257
258 - (unsigned int) _namedValue: (NSString *) aValueName
259 {
260   NSString *prefix, *value;
261   unsigned int count, max, result;
262
263   result = NSNotFound;
264
265   prefix = [NSString stringWithFormat: @"%@=", [aValueName uppercaseString]];
266   max = [values count];
267   count = 0;
268
269   while (result == NSNotFound && count < max)
270     {
271       value = [[values objectAtIndex: count] uppercaseString];
272       if ([value hasPrefix: prefix])
273         result = count;
274       else
275         count++;
276     }
277
278   return result;
279 }
280
281 - (void) setNamedValue: (NSString *) aValueName
282                     to: (NSString *) aValue
283 {
284   NSString *newValue;
285   unsigned int index;
286
287   newValue = [NSString stringWithFormat: @"%@=%@",
288                        [aValueName uppercaseString],
289                        aValue];
290   index = [self _namedValue: aValueName];
291   if (index == NSNotFound)
292     [self addValue: newValue];
293   else
294     {
295       if (aValue)
296         [self setValue: index to: newValue];
297       else
298         [values removeObjectAtIndex: index];
299     }
300 }
301
302 - (NSString *) namedValue: (NSString *) aValueName
303 {
304   unsigned int index;
305   NSRange equalSign;
306   NSString *value;
307
308   index = [self _namedValue: aValueName];
309   if (index == NSNotFound)
310     value = @"";
311   else
312     {
313       value = [values objectAtIndex: index];
314       equalSign = [value rangeOfString: @"="];
315       if (equalSign.location != NSNotFound)
316         value = [value substringFromIndex: equalSign.location + 1];
317     }
318
319   return value;
320 }
321
322 - (void) setValue: (unsigned int) anInt
323       ofAttribute: (NSString *) anAttribute
324                to: (NSString *) aValue
325 {
326   NSMutableArray *attrValues;
327
328   attrValues = [attributes objectForCaseInsensitiveKey: anAttribute];
329   if (!attrValues)
330     {
331       attrValues = [NSMutableArray new];
332       [attrValues autorelease];
333       [attributes setObject: attrValues forKey: anAttribute];
334     }
335
336   while ([attrValues count] <= anInt)
337     [attrValues addObject: @""];
338   [attrValues replaceObjectAtIndex: anInt
339               withObject: aValue];
340 }
341
342 - (NSString *) value: (unsigned int) anInt
343          ofAttribute: (NSString *) anAttribute
344 {
345   NSArray *attrValues;
346   NSString *value;
347
348   attrValues = [attributes objectForCaseInsensitiveKey: anAttribute];
349   if (attrValues && [attrValues count] > anInt)
350     value = [attrValues objectAtIndex: anInt];
351   else
352     value = @"";
353
354   return value;
355 }
356
357 - (NSString *) description
358 {
359   NSArray *attrs;
360   NSMutableString *str;
361   unsigned int count, max;
362   NSString *attr;
363
364   str = [NSMutableString stringWithCapacity:64];
365   [str appendFormat:@"<%p[%@]:", self, NSStringFromClass([self class])];
366   if (group)
367     [str appendFormat: @"%@ (group: %@)\n", tag, group];
368   else
369     [str appendFormat: @"%@\n", tag, group];
370
371   attrs = [attributes allKeys];
372   max = [attrs count];
373   if (max > 0)
374     {
375       [str appendFormat: @"\n  %d attributes: {\n", [attrs count]];
376       for (count = 0; count < max; count++)
377         {
378           attr = [attrs objectAtIndex: count];
379           [str appendFormat: @"  %@: %@\n",
380                attr, [attributes objectForKey: attr]];
381         }
382       [str appendFormat: @"}"];
383     }
384
385   max = [values count];
386   if (max > 0)
387     {
388       [str appendFormat: @"\n  %d values: {\n", [values count]];
389       for (count = 0; count < max; count++)
390         [str appendFormat: @"  %@\n", [values objectAtIndex: count]];
391       [str appendFormat: @"}"];
392     }
393
394   [str appendString:@">"];
395
396   return str;
397 }
398
399 - (BOOL) isVoid
400 {
401   BOOL result;
402   NSString *value;
403   NSEnumerator *enu;
404
405   result = YES;
406
407   enu = [values objectEnumerator];
408   value = [enu nextObject];
409   while (value && result)
410     {
411       result = ([value length] == 0);
412       value = [enu nextObject];
413     }
414
415   return result;
416 }
417
418 - (NSString *) versitString
419 {
420   CardVersitRenderer *renderer;
421   NSString *string;
422
423   renderer = [CardVersitRenderer new];
424   string = [renderer render: self];
425   [renderer release];
426
427   return string;
428 }
429
430 - (CardElement *) elementWithClass: (Class) elementClass
431 {
432   CardElement *newElement;
433
434   if ([self isKindOfClass: elementClass])
435     newElement = self;
436   else
437     {
438       newElement = [elementClass new];
439       [newElement autorelease];
440       [newElement setTag: tag];
441       [newElement setValuesAsCopy: values];
442       [newElement setAttributesAsCopy: attributes];
443       if (group)
444         [newElement setGroup: group];
445       if (parent)
446         {
447           [newElement setParent: parent];
448           [parent replaceThisElement: self
449                   withThisOne: newElement];
450         }
451     }
452
453   return newElement;
454 }
455
456 - (void) setValuesAsCopy: (NSMutableArray *) someValues
457 {
458   [values release];
459   values = someValues;
460   [values retain];
461 }
462
463 - (void) setAttributesAsCopy: (NSMutableDictionary *) someAttributes
464 {
465   [attributes release];
466   attributes = someAttributes;
467   [attributes retain];
468 }
469
470 - (CardGroup *) searchParentOfClass: (Class) parentClass
471 {
472   CardGroup *current;
473   CardGroup *found;
474
475   found = nil;
476   current = parent;
477   while (current && !found)
478     if ([current isKindOfClass: parentClass])
479       found = current;
480     else
481       current = [current parent];
482
483   return found;
484 }
485
486 /* NSCopying */
487
488 - (id) copyWithZone: (NSZone *) aZone
489 {
490   CardElement *new;
491
492   new = [[self class] new];
493   [new setTag: [tag copyWithZone: aZone]];
494   [new setGroup: [group copyWithZone: aZone]];
495   [new setParent: parent];
496   [new setValuesAsCopy: [values copyWithZone: aZone]];
497   [new setAttributesAsCopy: [attributes copyWithZone: aZone]];
498
499   return new;
500 }
501
502 @end