]> err.no Git - scalable-opengroupware.org/blob - UI/Contacts/UIxContactView.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1073 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / UI / Contacts / UIxContactView.m
1 /*
2   Copyright (C) 2004 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
5
6   OGo is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with OGo; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21 // $Id$
22
23 #import <Contacts/SOGoContactObject.h>
24
25 #import <NGCards/NGVCard.h>
26 #import <NGCards/CardElement.h>
27 #import <NGCards/NSArray+NGCards.h>
28 #import <NGExtensions/NSString+Ext.h>
29
30 #import "common.h"
31
32 #import "UIxContactView.h"
33
34 @implementation UIxContactView
35
36 /* accessors */
37
38 - (NSString *)tabSelection {
39   NSString *selection;
40     
41   selection = [self queryParameterForKey:@"tab"];
42   if (selection == nil)
43     selection = @"attributes";
44   return selection;
45 }
46
47 - (NSString *) _cardStringWithLabel: (NSString *) label
48                               value: (NSString *) value
49 {
50   NSMutableString *cardString;
51
52   cardString = [NSMutableString new];
53   [cardString autorelease];
54
55   if (value && [value length] > 0)
56     {
57       if (label)
58         [cardString appendFormat: @"%@&nbsp;%@<br />\n",
59                     [self labelForKey: label], value];
60       else
61         [cardString appendFormat: @"%@<br />\n", value];
62     }
63
64   return cardString;
65 }
66
67 - (NSString *) contactCardTitle
68 {
69   return [NSString stringWithFormat:
70                      [self labelForKey: @"Card for %@"],
71                    [card fn]];
72 }
73
74 - (NSString *) displayName
75 {
76   return [self _cardStringWithLabel: @"Display Name:"
77                value: [card fn]];
78 }
79
80 - (NSString *) nickName
81 {
82   return [self _cardStringWithLabel: @"Nickname:"
83                value: [card nickname]];
84 }
85
86 - (NSString *) primaryEmail
87 {
88   NSString *email, *mailTo;
89
90   email = [card preferredEMail];
91   if ([email length] > 0)
92     mailTo = [NSString stringWithFormat: @"<a href=\"mailto:%@\""
93                        @" onclick=\"return onContactMailTo(this);\">"
94                        @"%@</a>", email, email];
95   else
96     mailTo = nil;
97
98   return [self _cardStringWithLabel: @"Email:"
99                value: mailTo];
100 }
101
102 - (NSString *) secondaryEmail
103 {
104   NSString *email, *mailTo;
105   NSMutableArray *emails;
106
107   emails = [NSMutableArray new];
108   [emails addObjectsFromArray: [card childrenWithTag: @"email"]];
109   [emails removeObjectsInArray: [card childrenWithTag: @"email"
110                                       andAttribute: @"type"
111                                       havingValue: @"pref"]];
112
113   if ([emails count] > 1)
114     {
115       email = [[emails objectAtIndex: 0] value: 0];
116       mailTo = [NSString stringWithFormat: @"<a href=\"mailto:%@\""
117                          @" onclick=\"return onContactMailTo(this);\">"
118                          @"%@</a>", email, email];
119     }
120   else
121     mailTo = nil;
122
123   return [self _cardStringWithLabel: @"Additional Email:"
124                value: mailTo];
125 }
126
127 - (NSString *) screenName
128 {
129   NSString *screenName, *goim;
130
131   screenName = [[card uniqueChildWithTag: @"x-aim"] value: 0];
132   if ([screenName length] > 0)
133     goim = [NSString stringWithFormat: @"<a href=\"aim:goim?screenname=%@\""
134                      @">%@</a>", screenName, screenName];
135   else
136     goim = nil;
137
138   return [self _cardStringWithLabel: @"Screen Name:" value: goim];
139 }
140
141 - (NSString *) preferredTel
142 {
143   return [self _cardStringWithLabel: @"Phone Number:"
144                value: [card preferredTel]];
145 }
146
147 - (NSString *) preferredAddress
148 {
149   return @"";
150 }
151
152 - (BOOL) hasTelephones
153 {
154   if (!phones)
155     phones = [card childrenWithTag: @"tel"];
156
157   return ([phones count] > 0);
158 }
159
160 - (NSString *) _phoneOfType: (NSString *) aType
161                   withLabel: (NSString *) aLabel
162 {
163   NSArray *elements;
164   NSString *phone;
165
166   elements = [phones cardElementsWithAttribute: @"type"
167                      havingValue: aType];
168
169   if ([elements count] > 0)
170     phone = [[elements objectAtIndex: 0] value: 0];
171   else
172     phone = nil;
173
174   return [self _cardStringWithLabel: aLabel value: phone];
175 }
176
177 - (NSString *) workPhone
178 {
179   return [self _phoneOfType: @"work" withLabel: @"Work:"];
180 }
181
182 - (NSString *) homePhone
183 {
184   return [self _phoneOfType: @"home" withLabel: @"Home:"];
185 }
186
187 - (NSString *) fax
188 {
189   return [self _phoneOfType: @"fax" withLabel: @"Fax:"];
190 }
191
192 - (NSString *) mobile
193 {
194   return [self _phoneOfType: @"cell" withLabel: @"Mobile:"];
195 }
196
197 - (NSString *) pager
198 {
199   return [self _phoneOfType: @"pager" withLabel: @"Pager:"];
200 }
201
202 - (BOOL) hasHomeInfos
203 {
204   BOOL result;
205   NSArray *elements;
206
207   elements = [card childrenWithTag: @"adr"
208                    andAttribute: @"type"
209                    havingValue: @"home"];
210   if ([elements count] > 0)
211     {
212       result = YES;
213       homeAdr = [elements objectAtIndex: 0];
214     }
215   else
216     result = ([[card childrenWithTag: @"url"
217                      andAttribute: @"type"
218                      havingValue: @"home"] count] > 0);
219
220   return result;
221 }
222
223 - (NSString *) homePobox
224 {
225   return [self _cardStringWithLabel: nil value: [homeAdr value: 0]];
226 }
227
228 - (NSString *) homeExtendedAddress
229 {
230   return [self _cardStringWithLabel: nil value: [homeAdr value: 1]];
231 }
232
233 - (NSString *) homeStreetAddress
234 {
235   return [self _cardStringWithLabel: nil value: [homeAdr value: 2]];
236 }
237
238 - (NSString *) homeCityAndProv
239 {
240   NSString *city, *prov;
241   NSMutableString *data;
242
243   city = [homeAdr value: 3];
244   prov = [homeAdr value: 4];
245
246   data = [NSMutableString new];
247   [data autorelease];
248   [data appendString: city];
249   if ([city length] > 0 && [prov length] > 0)
250     [data appendString: @", "];
251   [data appendString: prov];
252
253   return [self _cardStringWithLabel: nil value: data];
254 }
255
256 - (NSString *) homePostalCodeAndCountry
257 {
258   NSString *postalCode, *country;
259   NSMutableString *data;
260
261   postalCode = [homeAdr value: 5];
262   country = [homeAdr value: 6];
263
264   data = [NSMutableString new];
265   [data autorelease];
266   [data appendString: postalCode];
267   if ([postalCode length] > 0 && [country length] > 0)
268     [data appendFormat: @", ", country];
269   [data appendString: country];
270
271   return [self _cardStringWithLabel: nil value: data];
272 }
273
274 - (NSString *) _urlOfType: (NSString *) aType
275 {
276   NSArray *elements;
277   NSString *data, *url;
278
279   elements = [card childrenWithTag: @"url"
280                    andAttribute: @"type"
281                    havingValue: aType];
282   if ([elements count] > 0)
283     {
284       url = [[elements objectAtIndex: 0] value: 0];
285       data = [NSString stringWithFormat:
286                          @"<a href=\"%@\">%@</a>",
287                        url, url];
288     }
289   else
290     data = nil;
291
292   return [self _cardStringWithLabel: nil value: data];
293 }
294
295 - (NSString *) homeUrl
296 {
297   return [self _urlOfType: @"home"];
298 }
299
300 - (BOOL) hasWorkInfos
301 {
302   BOOL result;
303   NSArray *elements;
304
305   elements = [card childrenWithTag: @"adr"
306                    andAttribute: @"type"
307                    havingValue: @"work"];
308   if ([elements count] > 0)
309     {
310       result = YES;
311       workAdr = [elements objectAtIndex: 0];
312     }
313   else
314     result = (([[card childrenWithTag: @"url"
315                       andAttribute: @"type"
316                      havingValue: @"work"] count] > 0)
317               || [[card childrenWithTag: @"org"] count] > 0);
318
319   return result;
320 }
321
322 - (NSString *) workTitle
323 {
324   return [self _cardStringWithLabel: nil value: [card title]];
325 }
326
327 - (NSString *) workService
328 {
329   NSArray *org, *orgServices;
330   NSRange aRange;
331   NSString *services;
332
333   org = [card org];
334   if (org && [org count] > 1)
335     {
336       aRange = NSMakeRange (1, [org count] - 1);
337       orgServices = [org subarrayWithRange: aRange];
338       services = [orgServices componentsJoinedByString: @", "];
339     }
340   else
341     services = nil;
342
343   return [self _cardStringWithLabel: nil value: services];
344 }
345
346 - (NSString *) workCompany
347 {
348   NSArray *org;
349   NSString *company;
350
351   org = [card org];
352   if (org && [org count] > 0)
353     company = [org objectAtIndex: 0];
354   else
355     company = nil;
356
357   return [self _cardStringWithLabel: nil value: company];
358 }
359
360 - (NSString *) workPobox
361 {
362   return [self _cardStringWithLabel: nil value: [workAdr value: 0]];
363 }
364
365 - (NSString *) workExtendedAddress
366 {
367   return [self _cardStringWithLabel: nil value: [workAdr value: 1]];
368 }
369
370 - (NSString *) workStreetAddress
371 {
372   return [self _cardStringWithLabel: nil value: [workAdr value: 2]];
373 }
374
375 - (NSString *) workCityAndProv
376 {
377   NSString *city, *prov;
378   NSMutableString *data;
379
380   city = [workAdr value: 3];
381   prov = [workAdr value: 4];
382
383   data = [NSMutableString new];
384   [data autorelease];
385   [data appendString: city];
386   if ([city length] > 0 && [prov length] > 0)
387     [data appendString: @", "];
388   [data appendString: prov];
389
390   return [self _cardStringWithLabel: nil value: data];
391 }
392
393 - (NSString *) workPostalCodeAndCountry
394 {
395   NSString *postalCode, *country;
396   NSMutableString *data;
397
398   postalCode = [workAdr value: 5];
399   country = [workAdr value: 6];
400
401   data = [NSMutableString new];
402   [data autorelease];
403   [data appendString: postalCode];
404   if ([postalCode length] > 0 && [country length] > 0)
405     [data appendFormat: @", ", country];
406   [data appendString: country];
407
408   return [self _cardStringWithLabel: nil value: data];
409 }
410
411 - (NSString *) workUrl
412 {
413   return [self _urlOfType: @"work"];
414 }
415
416 - (BOOL) hasOtherInfos
417 {
418   return ([[card note] length] > 0
419           || [[card bday] length] > 0
420           || [[card tz] length] > 0);
421 }
422
423 - (NSString *) bday
424 {
425   return [self _cardStringWithLabel: @"Birthday:" value: [card bday]];
426 }
427
428 - (NSString *) tz
429 {
430   return [self _cardStringWithLabel: @"Timezone:" value: [card tz]];
431 }
432
433 - (NSString *) note
434 {
435   NSString *note;
436
437   note = [card note];
438   if (note)
439     {
440       note = [note stringByReplacingString: @"\r\n"
441                    withString: @"<br />"];
442       note = [note stringByReplacingString: @"\n"
443                    withString: @"<br />"];
444     }
445
446   return [self _cardStringWithLabel: @"Note:" value: note];
447 }
448
449 /* hrefs */
450
451 - (NSString *) completeHrefForMethod: (NSString *) _method
452                        withParameter: (NSString *) _param
453                               forKey: (NSString *) _key
454 {
455   NSString *href;
456
457   [self setQueryParameter:_param forKey:_key];
458   href = [self completeHrefForMethod:[self ownMethodName]];
459   [self setQueryParameter:nil forKey:_key];
460
461   return href;
462 }
463
464 - (NSString *)attributesTabLink {
465   return [self completeHrefForMethod:[self ownMethodName]
466                withParameter:@"attributes"
467                forKey:@"tab"];
468 }
469 - (NSString *)debugTabLink {
470   return [self completeHrefForMethod:[self ownMethodName]
471                withParameter:@"debug"
472                forKey:@"tab"];
473 }
474
475 /* action */
476
477 - (id <WOActionResults>) vcardAction
478 {
479   WOResponse *response;
480
481   card = [[self clientObject] vCard];
482   if (card)
483     {
484       response = [WOResponse new];
485       [response autorelease];
486       [response setHeader: @"text/vcard" forKey: @"Content-type"];
487       [response appendContentString: [card versitString]];
488     }
489   else
490     return [NSException exceptionWithHTTPStatus: 404 /* Not Found */
491                         reason:@"could not locate contact"];
492
493   return response;
494 }
495
496 - (id <WOActionResults>) defaultAction
497 {
498   card = [[self clientObject] vCard];
499   if (card)
500     {
501       phones = nil;
502       homeAdr = nil;
503       workAdr = nil;
504     }
505   else
506     return [NSException exceptionWithHTTPStatus: 404 /* Not Found */
507                         reason: @"could not locate contact"];
508
509   return self;
510 }
511
512 - (BOOL) isDeletableClientObject
513 {
514   return [[self clientObject] respondsToSelector: @selector(delete)];
515 }
516
517 - (id) deleteAction
518 {
519   NSException *ex;
520   id url;
521
522   if (![self isDeletableClientObject])
523     /* return 400 == Bad Request */
524     return [NSException exceptionWithHTTPStatus:400
525                         reason:@"method cannot be invoked on "
526                         @"the specified object"];
527
528   ex = [[self clientObject] delete];
529   if (ex)
530     {
531     // TODO: improve error handling
532       [self debugWithFormat:@"failed to delete: %@", ex];
533
534       return ex;
535     }
536
537   url = [[[self clientObject] container] baseURLInContext:[self context]];
538
539   return [self redirectToLocation:url];
540 }
541
542 @end /* UIxContactView */