1/* 2 Copyright (C) 2000-2005 SKYRIX Software AG 3 4 This file is part of SOPE. 5 6 SOPE 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 SOPE 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 SOPE; 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 22#include "WEContextConditional.h" 23#include <NGObjWeb/WODynamicElement.h> 24 25/* 26 27 renders this: 28 _______________________________ 29 | MO | TU | WE | TH | FR | SA | 30 |-----------------------------| 31 | | | | | | 10 | 32 | 0 | 2 | 4 | 6 | 8 | 11 | 33 |____|____|____|____|____|____| 34 | | | | | | SU | 35 | | | | | |----| 36 | | | | | | 12 | 37 | 1 | 3 | 5 | 7 | 9 | 13 | 38 |____|____|____|____|____|____| 39 40 Would be a nice addition: 41 |a |b |c |d |e |f | 42 ------------------------------- 43 |a |b |c |d |e |f | 44 ------------------------------- 45 footerRow = 0 / footerRowList = ( 0, 1, 2, 3, 4 ); 46 headerRow = 0 / headerRowList = ( 0, 1, 2, 3, 4 ); 47 startDate/endDate 48 49 the numbers corresponde to the indxes in the matrix (self->matrix[]) 50 51 Note: it does support additional header and footer rows which can be used 52 to generate content above and below the view itself. 53 54 Usage: 55 WeekOverview: WEWeekOverview { 56 list = list; 57 item = item; 58 weekStart = weekStart; 59 60 titleStyle = "weekview_title"; 61 contentStyle = "weekview_content"; 62 } 63 64 TitleMode: WEWeekOverviewTitleMode {}; 65 InfoMode: WEWeekOverviewInfoMode {}; 66 ContentMode: WEWeekOverviewContentMode {}; 67*/ 68 69// TODO: allow stylesheet classes! 70 71#define SecondsPerWeek (7 * 24 * 60 * 60) 72#define SecondsPerDay (24 * 60 * 60) 73 74@class NSMutableArray; 75 76#define WEWeekOverview_TitleMode @"WEWeekOverview_TitleMode" 77#define WEWeekOverview_TitleModeDidMatch @"WEWeekOverview_TitleModeDidMatch" 78#define WEWeekOverview_InfoMode @"WEWeekOverview_InfoMode" 79#define WEWeekOverview_PMInfoMode @"WEWeekOverview_PMInfoMode" 80#define WEWeekOverview_ContentMode @"WEWeekOverview_ContentMode" 81 82#define WEWeekOverview_FooterRowMode @"WEWeekOverview_FooterRowMode" 83#define WEWeekOverview_HeaderRowMode @"WEWeekOverview_HeaderRowMode" 84 85@interface WEWeekOverview : WODynamicElement 86{ 87@protected 88 WOAssociation *list; 89 WOAssociation *item; 90 WOAssociation *index; 91 WOAssociation *identifier; 92 93 WOAssociation *dayIndex; // 0=firstDay, 1=secondDay, ..., 6=seventh day 94 WOAssociation *weekStart; 95 96 WOAssociation *startDateKey; 97 WOAssociation *endDateKey; 98 99 WOAssociation *titleStyle; 100 WOAssociation *contentStyle; 101 WOAssociation *titleColor; // DEPRECATED 102 WOAssociation *contentColor; // DEPRECATED 103 104 WOAssociation *width; 105 WOAssociation *border; 106 WOAssociation *cellpadding; 107 WOAssociation *cellspacing; 108 109 WOAssociation *footerRows; // list of elements for footer rows 110 WOAssociation *footerRow; // current element in footer row 111 WOAssociation *headerRows; // list of elements for header rows 112 WOAssociation *headerRow; // current element in header row 113 WOAssociation *colIndex; // for header/footer row 114 115 WOAssociation *isInfoItem; // is current item info entry 116 WOAssociation *infoItems; // current info entries 117 118 WOAssociation *hideWeekend; /* should Sa/So be rendered? */ 119 120@private 121 NSMutableArray *matrix[14]; 122 NSMutableArray *infos[14]; 123 BOOL hasOwnTitle; 124 125 WOElement *template; 126} 127@end 128 129#include <math.h> /* Needed for floor() */ 130#include "common.h" 131 132@interface WOContext(WEWeekOverview) 133 134- (void)appendWEIntElementID:(int)_intID; 135 136- (void)enterWEWOMode:(NSString *)_mode elementID:(NSString *)_eid; 137- (void)leaveWEWOMode:(NSString *)_mode; 138 139@end 140 141static NSString *retStrForInt(int i); 142static NSString *WEInfoElementID = @"i"; 143 144@implementation WOContext(WEWeekOverview) 145 146- (void)appendWEIntElementID:(int)_intID { 147 NSString *s; 148 // TODO: could make the number switch in here? 149 150 s = retStrForInt(_intID); 151 [self appendElementIDComponent:s]; 152 [s release]; 153} 154 155- (void)enterWEWOMode:(NSString *)_mode elementID:(NSString *)_eid { 156 [self setObject:@"YES" forKey:_mode]; 157 [self appendElementIDComponent:_eid]; 158} 159- (void)leaveWEWOMode:(NSString *)_mode { 160 [self deleteLastElementIDComponent]; // delete eid 161 [self removeObjectForKey:_mode]; 162} 163 164@end /* WOContext(WEWeekOverview) */ 165 166@implementation WEWeekOverview 167 168// premature: don't know a "good" count 169static NSNumber *smap[10] = { nil,nil,nil,nil,nil,nil,nil,nil,nil,nil }; 170static Class NumClass = Nil; 171static Class StrClass = Nil; 172static NSArray *emptyArray = nil; 173 174+ (void)initialize { 175 static BOOL didInit = NO; 176 int i; 177 if (didInit) return; 178 didInit = YES; 179 180 StrClass = [NSString class]; 181 NumClass = [NSNumber class]; 182 for (i = 0; i < 10; i++) 183 smap[i] = [[NumClass numberWithInt:i] retain]; 184 185 if (emptyArray == nil) emptyArray = [[NSArray alloc] init]; 186} 187 188static NSNumber *numForInt(int i) { 189 if (i >= 0 && i < 10) 190 return smap[i]; 191 return [NumClass numberWithInt:i]; 192} 193static NSString *retStrForInt(int i) { 194 switch(i) { 195 case 0: return @"0"; 196 case 1: return @"1"; 197 case 2: return @"2"; 198 case 3: return @"3"; 199 case 4: return @"4"; 200 case 5: return @"5"; 201 case 6: return @"6"; 202 case 7: return @"7"; 203 case 8: return @"8"; 204 case 9: return @"9"; 205 case 10: return @"10"; 206 // TODO: find useful count! 207 default: { 208 char buf[16]; 209 sprintf(buf, "%i", i); 210 return [[StrClass alloc] initWithCString:buf]; 211 } 212 } 213} 214 215- (id)initWithName:(NSString *)_name 216 associations:(NSDictionary *)_config 217 template:(WOElement *)_tmp 218{ 219 if ((self = [super initWithName:_name associations:_config template:_tmp])) { 220 self->list = WOExtGetProperty(_config, @"list"); 221 self->item = WOExtGetProperty(_config, @"item"); 222 self->index = WOExtGetProperty(_config, @"index"); 223 self->identifier = WOExtGetProperty(_config, @"identifier"); 224 self->dayIndex = WOExtGetProperty(_config, @"dayIndex"); 225 self->weekStart = WOExtGetProperty(_config, @"weekStart"); 226 self->startDateKey = WOExtGetProperty(_config, @"startDateKey"); 227 self->endDateKey = WOExtGetProperty(_config, @"endDateKey"); 228 self->hideWeekend = WOExtGetProperty(_config, @"hideWeekend"); 229 230 self->titleColor = WOExtGetProperty(_config, @"titleColor"); 231 self->titleStyle = WOExtGetProperty(_config, @"titleStyle"); 232 self->contentColor = WOExtGetProperty(_config, @"contentColor"); 233 self->contentStyle = WOExtGetProperty(_config, @"contentStyle"); 234 235 self->width = WOExtGetProperty(_config, @"width"); 236 self->border = WOExtGetProperty(_config, @"border"); 237 self->cellspacing = WOExtGetProperty(_config, @"cellspacing"); 238 self->cellpadding = WOExtGetProperty(_config, @"cellpadding"); 239 240 self->headerRows = WOExtGetProperty(_config, @"headerRows"); 241 self->headerRow = WOExtGetProperty(_config, @"headerRow"); 242 self->footerRows = WOExtGetProperty(_config, @"footerRows"); 243 self->footerRow = WOExtGetProperty(_config, @"footerRow"); 244 self->colIndex = WOExtGetProperty(_config, @"columnIndex"); 245 246 247 if (self->startDateKey == nil) { 248 self->startDateKey = 249 [[WOAssociation associationWithValue:@"startDate"] retain]; 250 } 251 252 if (self->endDateKey == nil) { 253 self->endDateKey = 254 [[WOAssociation associationWithValue:@"endDate"] retain]; 255 } 256 257 if (self->width == nil) 258 self->width = [[WOAssociation associationWithValue:@"100%"] retain]; 259 if (self->border == nil) 260 self->border = [[WOAssociation associationWithValue:@"0"] retain]; 261 if (self->cellspacing == nil) 262 self->cellspacing = [[WOAssociation associationWithValue:@"2"] retain]; 263 if (self->cellpadding == nil) 264 self->cellpadding = [[WOAssociation associationWithValue:@"5"] retain]; 265 266 self->isInfoItem = WOExtGetProperty(_config, @"isInfoItem"); 267 self->infoItems = WOExtGetProperty(_config, @"infoItems"); 268 269 self->template = [_tmp retain]; 270 } 271 return self; 272} 273 274- (void)resetMatrix { 275 int i; 276 277 for (i = 0; i < 14; i++) { 278 [self->matrix[i] release]; self->matrix[i] = nil; 279 [self->infos[i] release]; self->infos[i] = nil; 280 } 281} 282 283- (void)dealloc { 284 [self->hideWeekend release]; 285 [self->list release]; 286 [self->item release]; 287 [self->index release]; 288 [self->identifier release]; 289 [self->dayIndex release]; 290 [self->weekStart release]; 291 [self->startDateKey release]; 292 [self->endDateKey release]; 293 [self->titleColor release]; 294 [self->titleStyle release]; 295 [self->contentColor release]; 296 [self->contentStyle release]; 297 [self->width release]; 298 [self->border release]; 299 [self->cellpadding release]; 300 [self->cellspacing release]; 301 [self->headerRows release]; 302 [self->headerRow release]; 303 [self->footerRows release]; 304 [self->footerRow release]; 305 [self->colIndex release]; 306 [self->infoItems release]; 307 [self->isInfoItem release]; 308 309 [self resetMatrix]; 310 311 [self->template release]; 312 313 [super dealloc]; 314} 315 316static inline void 317_applyIdentifier(WEWeekOverview *self, WOComponent *comp, NSString *_idx) 318{ 319 NSArray *array; 320 unsigned count, cnt; 321 322 array = [self->list valueInComponent:comp]; 323 count = [array count]; 324 325 if (count == 0) 326 return; 327 328 /* find subelement for unique id */ 329 330 for (cnt = 0; cnt < count; cnt++) { 331 NSString *ident; 332 333 if (self->index) 334 [self->index setUnsignedIntValue:cnt inComponent:comp]; 335 336 if (self->item) 337 [self->item setValue:[array objectAtIndex:cnt] inComponent:comp]; 338 339 ident = [self->identifier stringValueInComponent:comp]; 340 341 if ([ident isEqualToString:_idx]) { 342 /* found subelement with unique id */ 343 return; 344 } 345 } 346 347 [comp logWithFormat: 348 @"WEWeekOverview: array did change, " 349 @"unique-id isn't contained."]; 350 [self->item setValue:nil inComponent:comp]; 351 [self->index setUnsignedIntValue:0 inComponent:comp]; 352} 353 354static inline void 355_applyIndex(WEWeekOverview *self, WOComponent *comp, unsigned _idx) 356{ 357 NSArray *array; 358 unsigned count; 359 360 array = [self->list valueInComponent:comp]; 361 362 if (self->index) 363 [self->index setUnsignedIntValue:_idx inComponent:comp]; 364 365 if (self->item == nil) 366 return; 367 368 count = [array count]; 369 if (_idx < count) { 370 [self->item setValue:[array objectAtIndex:_idx] inComponent:comp]; 371 return; 372 } 373 374 [comp logWithFormat: 375 @"WEWeekOverview: array did change, index is invalid."]; 376 [self->item setValue:nil inComponent:comp]; 377 [self->index setUnsignedIntValue:0 inComponent:comp]; 378} 379 380- (void)_calcMatrixInContext:(WOContext *)_ctx { 381 // THREAD: uses temporary ivars 382 WOComponent *comp; 383 NSCalendarDate *startWeek; 384 NSArray *array; 385 NSString *startKey; 386 NSString *endKey; 387 int i, idx, idx2, cnt; 388 389 [self resetMatrix]; 390 391 [_ctx removeObjectForKey:WEWeekOverview_TitleModeDidMatch]; 392 [_ctx setObject:@"YES" forKey:WEWeekOverview_TitleMode]; 393 [self->template appendToResponse:nil inContext:_ctx]; 394 [_ctx removeObjectForKey:WEWeekOverview_TitleMode]; 395 396 if ([_ctx objectForKey:WEWeekOverview_TitleModeDidMatch] != nil) 397 self->hasOwnTitle = YES; 398 else 399 self->hasOwnTitle = NO; 400 401 comp = [_ctx component]; 402 array = [self->list valueInComponent:comp]; 403 startKey = [self->startDateKey stringValueInComponent:comp]; 404 endKey = [self->endDateKey stringValueInComponent:comp]; 405 startWeek = (self->weekStart) 406 ? [self->weekStart valueInComponent:comp] 407 : [NSCalendarDate calendarDate]; 408 409 for (i = 0, cnt = [array count]; i < cnt; i++) { 410 id app; 411 NSCalendarDate *sd, *ed; 412 NSTimeInterval diff; 413 BOOL isInfo; 414 415 app = [array objectAtIndex:i]; 416#if 0 // hh: so muesste es eigentlich sein: !!! 417 [self->item setValue:app inComponent:comp]; 418 419 sd = [self->startDate valueInComponent:comp]; // item.startDate; 420 ed = [self->endDate valueInComponent:comp]; // item.startDate; 421#endif 422 423 sd = [app valueForKey:startKey]; // startDate 424 ed = [app valueForKey:endKey]; // endDate 425 426 if ((sd == nil) && (ed == nil)) continue; 427 428 diff = [(sd ? sd : ed) timeIntervalSinceDate:startWeek]; 429 430 idx = floor((diff / SecondsPerWeek) * 14); 431 432 if ((self->item != nil) && (self->isInfoItem)) { 433 [self->item setValue:app inComponent:comp]; 434 isInfo = [[self->isInfoItem valueInComponent:comp] boolValue]; 435 } 436 else 437 isInfo = NO; 438 439 if ((0 <= idx) && (idx < 14)) { 440 if (isInfo) { 441 if (self->infos[idx] == nil) 442 self->infos[idx] = [[NSMutableArray alloc] initWithCapacity:2]; 443 [self->infos[idx] addObject:numForInt(i)]; 444 } 445 else { 446 if (self->matrix[idx] == nil) 447 self->matrix[idx] = [[NSMutableArray alloc] initWithCapacity:4]; 448 [self->matrix[idx] addObject:numForInt(i)]; 449 } 450 } 451 if (idx >= 0) 452 idx = (idx % 2) ? idx + 1: idx +2; 453 454 diff = [ed timeIntervalSinceDate:startWeek]; 455 456 idx2 = floor((diff / SecondsPerWeek) * 14); 457 idx2 = (idx2 > 13) ? 13 : idx2; 458 459 if (idx2 < 0) continue; 460 461 while (idx <= idx2) { 462 idx = (idx < 0) ? 0 : idx; 463 if (isInfo) { 464 if (self->infos[idx] == nil) 465 self->infos[idx] = [[NSMutableArray alloc] initWithCapacity:2]; 466 // TODO: optimize 467 [self->infos[idx] addObject:numForInt(i)]; 468 } 469 else { 470 if (self->matrix[idx] == nil) 471 self->matrix[idx] = [[NSMutableArray alloc] initWithCapacity:4]; 472 // TODO: optimize 473 [self->matrix[idx] addObject:numForInt(i)]; 474 } 475 idx = idx + 2; 476 } 477 } 478} 479 480/* common template operations */ 481 482- (void)appendTemplateToResponse:(WOResponse *)_r inContext:(WOContext *)_ctx 483 mode:(NSString *)_mode elementID:(NSString *)_modeId 484 index:(int)_idx 485{ 486 [_ctx enterWEWOMode:_mode elementID:_modeId]; 487 [_ctx appendWEIntElementID:_idx]; 488 [self->template appendToResponse:_r inContext:_ctx]; 489 [_ctx deleteLastElementIDComponent]; // delete idx 490 [_ctx leaveWEWOMode:_mode]; 491} 492 493/* header rows */ 494 495- (void)appendHeaderRowToResponse:(WOResponse *)_response 496 inContext:(WOContext *)_ctx 497 column:(int)_col 498{ 499 WOComponent *comp; 500 NSString *bgcolor, *style; 501 502 comp = [_ctx component]; 503 504 if ([self->colIndex isValueSettable]) 505 [self->colIndex setIntValue:_col inComponent:comp]; 506 507 bgcolor = [self->contentColor stringValueInComponent:comp]; 508 style = [self->contentStyle stringValueInComponent:comp]; 509 510 [_response appendContentString: 511 @"<td valign=\"top\" align=\"left\" width=\"17%\""]; 512 if (bgcolor) { 513 [_response appendContentString:@" bgcolor=\""]; 514 [_response appendContentString:bgcolor]; 515 [_response appendContentCharacter:'"']; 516 } 517 if ([style isNotEmpty]) { 518 [_response appendContentString:@" class=\""]; 519 [_response appendContentString:style]; 520 [_response appendContentCharacter:'"']; 521 } 522 [_response appendContentCharacter:'>']; 523 524 [self appendTemplateToResponse:_response inContext:_ctx 525 mode:WEWeekOverview_HeaderRowMode elementID:@"h" 526 index:_col]; 527 528 [_response appendContentString:@"</td>"]; 529} 530- (void)appendHeaderRowToResponse:(WOResponse *)_response 531 inContext:(WOContext *)_ctx 532 row:(id)_rowItem 533{ 534 int i, cnt; 535 536 if ([self->headerRow isValueSettable]) 537 [self->headerRow setValue:_rowItem inComponent:[_ctx component]]; 538 539 /* Saturday/Sunday is the 6th column */ 540 cnt = (self->hideWeekend != nil) 541 ? [self->hideWeekend boolValueInComponent:[_ctx component]] ? 5 : 6 542 : 6; 543 544 for (i = 0; i < cnt; i++) 545 [self appendHeaderRowToResponse:_response inContext:_ctx column:i]; 546} 547- (void)appendHeaderRowsToResponse:(WOResponse *)_response 548 inContext:(WOContext *)_ctx 549{ 550 /* add n <tr> rows */ 551 WOComponent *comp; 552 NSArray *headers; 553 int cnt, i; 554 555 comp = [_ctx component]; 556 if ((headers = [self->headerRows valueInComponent:comp]) == nil) 557 return; 558 559 for (i = 0, cnt = [headers count]; i < cnt; i++) { 560 id one; 561 562 one = [headers objectAtIndex:i]; 563 564 [_response appendContentString:@"<tr>"]; 565 [_ctx appendElementIDComponent:@"hr"]; // header row 566 [_ctx appendWEIntElementID:i]; 567 568 [self appendHeaderRowToResponse:_response inContext:_ctx row:one]; 569 570 [_ctx deleteLastElementIDComponent]; // remove idx (i) 571 [_ctx deleteLastElementIDComponent]; // remove 'hr' 572 [_response appendContentString:@"</tr>"]; 573 } 574} 575 576/* footer rows */ 577 578- (void)appendFooterRowToResponse:(WOResponse *)_response 579 inContext:(WOContext *)_ctx 580 column:(int)_col 581{ 582 WOComponent *comp; 583 NSString *bgcolor; 584 585 comp = [_ctx component]; 586 587 if ([self->colIndex isValueSettable]) 588 [self->colIndex setIntValue:_col inComponent:comp]; 589 590 bgcolor = [self->contentColor stringValueInComponent:comp]; 591 592 [_response appendContentString: 593 @"<td valign=\"top\" align=\"left\" width=\"17%\""]; 594 if (bgcolor) { 595 [_response appendContentString:@" bgcolor=\""]; 596 [_response appendContentString:bgcolor]; 597 [_response appendContentCharacter:'"']; 598 } 599 [_response appendContentCharacter:'>']; 600 601 [self appendTemplateToResponse:_response inContext:_ctx 602 mode:WEWeekOverview_FooterRowMode elementID:@"f" 603 index:_col]; 604 605 [_response appendContentString:@"</td>"]; 606} 607 608- (void)appendFooterRowToResponse:(WOResponse *)_response 609 inContext:(WOContext *)_ctx 610 row:(id)_rowItem 611{ 612 // TODO: this method is a DUP to appendHeaderRowToResponse... => refactor 613 int i, cnt; 614 615 if ([self->footerRow isValueSettable]) 616 [self->footerRow setValue:_rowItem inComponent:[_ctx component]]; 617 618 /* Saturday/Sunday is the 6th column */ 619 cnt = (self->hideWeekend != nil) 620 ? [self->hideWeekend boolValueInComponent:[_ctx component]] ? 5 : 6 621 : 6; 622 623 for (i = 0; i < cnt; i++) 624 [self appendFooterRowToResponse:_response inContext:_ctx column:i]; 625} 626 627- (void)appendFooterRowsToResponse:(WOResponse *)_response 628 inContext:(WOContext *)_ctx 629{ 630 // TODO: this is a copy of the head-row method! 631 WOComponent *comp; 632 NSArray *footers; 633 int i, cnt; 634 635 comp = [_ctx component]; 636 637 if ((footers = [self->footerRows valueInComponent:comp]) == nil) 638 return; 639 640 for (i = 0, cnt = [footers count]; i < cnt; i++) { 641 NSString *s; 642 id one; 643 644 one = [footers objectAtIndex:i]; 645 646 [_response appendContentString:@"<tr>"]; 647 [_ctx appendElementIDComponent:@"fr"]; 648 649 s = retStrForInt(i); 650 [_ctx appendElementIDComponent:s]; 651 [s release]; 652 653 [self appendFooterRowToResponse:_response inContext:_ctx row:one]; 654 655 [_ctx deleteLastElementIDComponent]; // remove idx (i) 656 [_ctx deleteLastElementIDComponent]; // remove 'fr' 657 [_response appendContentString:@"</tr>"]; 658 } 659} 660 661- (void)appendDateTitleToResponse:(WOResponse *)_response 662 inContext:(WOContext *)_ctx 663 day:(int)_day 664{ 665 WOComponent *comp; 666 NSString *bgcolor, *style; 667 668 comp = [_ctx component]; 669 670 if ([self->dayIndex isValueSettable]) 671 [self->dayIndex setIntValue:_day inComponent:comp]; 672 673 bgcolor = [self->titleColor stringValueInComponent:comp]; 674 style = [self->titleStyle stringValueInComponent:comp]; 675 676 // TODO: use CSS for alignment, width and color 677 [_response appendContentString: 678 @"<td valign=\"top\" align=\"left\" width=\"17%\""]; 679 if ([bgcolor isNotEmpty]) { 680 [_response appendContentString:@" bgcolor=\""]; 681 [_response appendContentString:bgcolor]; 682 [_response appendContentCharacter:'"']; 683 } 684 if ([style isNotEmpty]) { 685 [_response appendContentString:@" class=\""]; 686 [_response appendContentString:style]; 687 [_response appendContentCharacter:'"']; 688 } 689 [_response appendContentCharacter:'>']; 690 691 if (self->hasOwnTitle) { 692 [self appendTemplateToResponse:_response inContext:_ctx 693 mode:WEWeekOverview_TitleMode elementID:@"t" 694 index:_day]; 695 } 696 else { 697 NSCalendarDate *date; 698 NSString *s; 699 700 date = (self->weekStart) 701 ? [self->weekStart valueInComponent:comp] 702 : [NSCalendarDate calendarDate]; 703 date = [date addTimeInterval:_day * SecondsPerDay]; 704 705 [_response appendContentString: 706 @"<table cellpadding=\"0\" width=\"100%\" border=\"0\" " 707 @"cellspacing=\"0\">" 708 @"<tr>" 709 @"<td align=\"left\" valign=\"top\">" 710 // TODO: use style for that 711 @"<font color=\"black\" size=\"+2\"><b>"]; 712 713 s = [date descriptionWithCalendarFormat:@"%d"]; // TODO: no cal-desc! 714 [_response appendContentString:s]; 715 716 [_response appendContentString: 717 @"</b></font></td>" 718 @"<td align=\"center\" valign=\"top\">" 719 // TODO: use style for that 720 @"<font color=\"black\">"]; 721 s = [date descriptionWithCalendarFormat:@"%A"]; // TODO: no cal-desc 722 [_response appendContentString:s]; // TODO: do not use cal-desc 723 [_response appendContentString: 724 @"</font>" 725 @"</td></tr></table>"]; 726 } 727 [_response appendContentString:@"</td>"]; 728} 729 730- (void)appendContentToResponse:(WOResponse *)_response 731 inContext:(WOContext *)_ctx 732 index:(int)_index 733{ 734 WOComponent *comp; 735 NSArray *array; 736 id app; 737 int i, cnt, idx, count; 738 739 comp = [_ctx component]; 740 array = [self->list valueInComponent:comp]; 741 count = [array count]; 742 743 /* idx is the dayIndex 0=1stDay ... 6=7thDay (e.g. 0=Mon ... 6=Sun) */ 744 idx = (int)(_index / 2); 745 746 if ([self->dayIndex isValueSettable]) 747 [self->dayIndex setIntValue:idx inComponent:comp]; 748 749 if ([self->infoItems isValueSettable]) { 750 cnt = [self->infos[_index] count]; 751 if (cnt) { 752 NSMutableArray *infoArr; 753 754 infoArr = [[NSMutableArray alloc] initWithCapacity:cnt]; 755 for (i = 0; i < cnt; i++) { 756 idx = [[self->infos[_index] objectAtIndex:i] intValue]; 757 758 if (idx >= count) { 759 [self logWithFormat: 760 @"WARNING: WEWeekOverview: info index out of range"]; 761 continue; 762 } 763 [infoArr addObject:[array objectAtIndex:idx]]; 764 } 765 [self->infoItems setValue:infoArr inComponent:comp]; 766 [infoArr release]; infoArr = nil; 767 } 768 else 769 [self->infoItems setValue:emptyArray inComponent:comp]; 770 } 771 772 // *** append day info 773 if ((_index % 2) == 0) { 774 // if AM-section... 775 776 [self appendTemplateToResponse:_response inContext:_ctx 777 mode:WEWeekOverview_InfoMode elementID:WEInfoElementID 778 index:idx]; 779 } 780 else if (_index < 10) { 781 /* P.M. slot of Monday .. Friday */ 782 [self appendTemplateToResponse:_response inContext:_ctx 783 mode:WEWeekOverview_PMInfoMode elementID:@"p" 784 index:idx]; 785 } 786 787 // *** append day content 788 [_ctx enterWEWOMode:WEWeekOverview_ContentMode elementID:@"c"]; 789 790 // append section id (0 = Mon AM, 1 = Mon PM, 2 = Tue AM, ...) 791 [_ctx appendWEIntElementID:_index]; 792 793 for (i = 0, cnt = [self->matrix[_index] count]; i < cnt; i++) { 794 idx = [[self->matrix[_index] objectAtIndex:i] intValue]; 795 796 if (idx >= count) { 797 NSLog(@"Warning! WEWeekOverview: index out of range"); 798 continue; 799 } 800 801 app = [array objectAtIndex:idx]; 802 803 if ([self->item isValueSettable]) 804 [self->item setValue:app inComponent:comp]; 805 if ([self->index isValueSettable]) 806 [self->index setIntValue:idx inComponent:comp]; 807 808 if (self->identifier == nil) { 809 NSString *s; 810 811 s = retStrForInt(idx); 812 [_ctx appendElementIDComponent:s]; 813 [s release]; 814 } 815 else { 816 NSString *s; 817 818 s = [self->identifier stringValueInComponent:comp]; 819 [_ctx appendElementIDComponent:s]; 820 } 821 [self->template appendToResponse:_response inContext:_ctx]; 822 [_ctx deleteLastElementIDComponent]; 823 } 824 if (cnt == 0) 825 [_response appendContentString:@" "]; 826 827 [_ctx deleteLastElementIDComponent]; // delete section id 828 [_ctx leaveWEWOMode:WEWeekOverview_ContentMode]; 829} 830 831/* processing requests */ 832 833- (void)takeValuesForHeaderRows:(WORequest *)_req 834 ctx:(WOContext *)_ctx 835{ 836 WOComponent *comp; 837 NSArray *headers; 838 int i, cnt; 839 840 comp = [_ctx component]; 841 if ((headers = [self->headerRows valueInComponent:comp]) == nil) 842 return; 843 844 [_ctx setObject:@"YES" forKey:WEWeekOverview_HeaderRowMode]; 845 [_ctx appendElementIDComponent:@"hr"]; // append 'hr' 846 [_ctx appendZeroElementIDComponent]; // append i 847 848 for (i = 0, cnt = [headers count]; i < cnt; i++) { 849 int c; 850 851 [_ctx appendElementIDComponent:@"h"]; // append 'h' 852 [_ctx appendZeroElementIDComponent]; // append c 853 854 if ([self->headerRow isValueSettable]) 855 [self->headerRow setValue:[headers objectAtIndex:i] inComponent:comp]; 856 857 // TODO: do not go over Saturday (6) with hideWeekend=YES 858 for (c = 0; c < 6; c++) { // go throw columns 859 if ([self->colIndex isValueSettable]) 860 [self->colIndex setIntValue:c inComponent:comp]; 861 862 [self->template takeValuesFromRequest:_req inContext:_ctx]; 863 [_ctx incrementLastElementIDComponent]; // increment c 864 } 865 866 [_ctx deleteLastElementIDComponent]; // delete c 867 [_ctx deleteLastElementIDComponent]; // delete 'h' 868 [_ctx incrementLastElementIDComponent]; // increment i 869 } 870 871 [_ctx deleteLastElementIDComponent]; // remove i 872 [_ctx deleteLastElementIDComponent]; // remove 'hr' 873 [_ctx removeObjectForKey:WEWeekOverview_HeaderRowMode]; 874} 875- (void)takeValuesForFooterRows:(WORequest *)_req 876 ctx:(WOContext *)_ctx 877{ 878 // TODO: this is a DUP of the header row 879 // we might implement that code as an internal WODynamicElement? 880 WOComponent *comp; 881 NSArray *footers; 882 int i, cnt; 883 884 comp = [_ctx component]; 885 if ((footers = [self->footerRows valueInComponent:comp]) == nil) 886 return; 887 888 [_ctx setObject:@"YES" forKey:WEWeekOverview_FooterRowMode]; 889 [_ctx appendElementIDComponent:@"hr"]; // append 'fr' 890 [_ctx appendZeroElementIDComponent]; // append i 891 892 for (i = 0, cnt = [footers count]; i < cnt; i++) { 893 int c; 894 [_ctx appendElementIDComponent:@"f"]; // append 'f' 895 [_ctx appendZeroElementIDComponent]; // append c 896 897 if ([self->footerRow isValueSettable]) 898 [self->footerRow setValue:[footers objectAtIndex:i] inComponent:comp]; 899 900 // TODO: do not go over Saturday (6) with hideWeekend=YES 901 for (c = 0; c < 6; c++) { // go throw columns 902 if ([self->colIndex isValueSettable]) 903 [self->colIndex setIntValue:c inComponent:comp]; 904 [self->template takeValuesFromRequest:_req inContext:_ctx]; 905 [_ctx incrementLastElementIDComponent]; // increment c 906 } 907 908 [_ctx deleteLastElementIDComponent]; // delete c 909 [_ctx deleteLastElementIDComponent]; // delete 'f' 910 [_ctx incrementLastElementIDComponent]; // increment i 911 } 912 913 [_ctx deleteLastElementIDComponent]; // remove i 914 [_ctx deleteLastElementIDComponent]; // remove 'fr' 915 [_ctx removeObjectForKey:WEWeekOverview_FooterRowMode]; 916} 917 918- (void)takeValues:(WORequest *)_req 919 mode:(NSString *)_mode modeId:(NSString *)_id 920 ctx:(WOContext *)_ctx 921{ 922 int i; 923 924 [_ctx setObject:@"YES" forKey:_mode]; 925 [_ctx appendElementIDComponent:_id]; // append mode id 926 [_ctx appendZeroElementIDComponent]; // append first day (monday) 927 928 // TODO: do not go over Saturday (5), Sunday(6) with hideWeekend=YES 929 for (i = 0; i < 7; i++) { 930 if ([self->dayIndex isValueSettable]) 931 [self->dayIndex setIntValue:i inComponent:[_ctx component]]; 932 933 [self->template takeValuesFromRequest:_req inContext:_ctx]; 934 [_ctx incrementLastElementIDComponent]; // increment day 935 } 936 [_ctx deleteLastElementIDComponent]; // delete day 937 [_ctx deleteLastElementIDComponent]; // delete title mode 938 [_ctx removeObjectForKey:_mode]; 939} 940 941- (void)takeValuesFromRequest:(WORequest *)_req inContext:(WOContext *)_ctx { 942 WOComponent *comp; 943 NSArray *array; 944 int i, count; 945 946 comp = [_ctx component]; 947 array = [self->list valueInComponent:comp]; 948 count = [array count]; 949 950 /* titles */ 951 [self takeValues:_req mode:WEWeekOverview_TitleMode modeId:@"t" ctx:_ctx]; 952 953 /* headers */ 954 [self takeValuesForHeaderRows:_req ctx:_ctx]; 955 956 /* infos */ 957 [self takeValues:_req mode:WEWeekOverview_InfoMode modeId:WEInfoElementID 958 ctx:_ctx]; 959 960 /* P.M.Infos */ 961 [self takeValues:_req mode:WEWeekOverview_PMInfoMode modeId:@"p" ctx:_ctx]; 962 963 // THREAD: uses temporary ivars 964 [self _calcMatrixInContext:_ctx]; 965 966 [_ctx setObject:@"YES" forKey:WEWeekOverview_ContentMode]; 967 [_ctx appendElementIDComponent:@"c"]; // append content mode 968 [_ctx appendZeroElementIDComponent]; // append section-id 969 for (i = 0; i < 14; i++) { 970 int j, cnt, idx; 971 972 cnt = [self->matrix[i] count]; 973 974 if ((i % 2) == 0 && [self->dayIndex isValueSettable]) 975 [self->dayIndex setIntValue:(int)(i / 2) inComponent:comp]; 976 977 for (j = 0; j < cnt; j++) { 978 NSString *s; 979 980 idx = [[self->matrix[i] objectAtIndex:j] intValue]; 981 982 if (idx >= count) { 983 NSLog(@"Warning! WEWeekRepetition: Index is out of range"); 984 continue; 985 } 986 987 _applyIndex(self, comp, idx); 988 989 if (self->identifier) { 990 s = [self->identifier stringValueInComponent:comp]; 991 [_ctx appendElementIDComponent:s]; 992 } 993 else { 994 s = retStrForInt(idx); 995 [_ctx appendElementIDComponent:s]; 996 [s release]; 997 } 998 999 [self->template takeValuesFromRequest:_req inContext:_ctx]; 1000 1001 [_ctx deleteLastElementIDComponent]; // delete index-id 1002 } 1003 [_ctx incrementLastElementIDComponent]; // increase section-id 1004 } 1005 [_ctx deleteLastElementIDComponent]; // delete section-id 1006 [_ctx deleteLastElementIDComponent]; // delete content mode 1007 [_ctx removeObjectForKey:WEWeekOverview_ContentMode]; 1008 1009 /* footers */ 1010 [self takeValuesForFooterRows:_req ctx:_ctx]; 1011 1012 [self resetMatrix]; 1013} 1014 1015- (id)invokeActionForHeader:(WORequest *)_req inContext:(WOContext *)_ctx 1016 row:(id)_row 1017{ 1018 WOComponent *comp; 1019 NSString *section; // must be 'h' 1020 NSString *colIdx; // must be between 0 and 6 1021 1022 id result; 1023 1024 comp = [_ctx component]; 1025 1026 section = [_ctx currentElementID]; 1027 [_ctx consumeElementID]; 1028 [_ctx appendElementIDComponent:section]; 1029 colIdx = [_ctx currentElementID]; 1030 [_ctx consumeElementID]; 1031 [_ctx appendElementIDComponent:colIdx]; 1032 1033 if ([self->headerRow isValueSettable]) 1034 [self->headerRow setValue:_row inComponent:comp]; 1035 if ([self->dayIndex isValueSettable]) 1036 [self->colIndex setIntValue:[colIdx intValue] inComponent:comp]; 1037 1038 result = [self->template invokeActionForRequest:_req inContext:_ctx]; 1039 1040 [_ctx deleteLastElementIDComponent]; // column idx 1041 [_ctx deleteLastElementIDComponent]; // section ('h') 1042 1043 return result; 1044} 1045- (id)invokeActionForFooter:(WORequest *)_req inContext:(WOContext *)_ctx 1046 row:(id)_row 1047{ 1048 WOComponent *comp; 1049 NSString *section; // must be 'f' 1050 NSString *colIdx; // must be between 0 and 6 1051 1052 id result; 1053 1054 comp = [_ctx component]; 1055 1056 section = [_ctx currentElementID]; 1057 [_ctx consumeElementID]; 1058 [_ctx appendElementIDComponent:section]; 1059 colIdx = [_ctx currentElementID]; 1060 [_ctx consumeElementID]; 1061 [_ctx appendElementIDComponent:colIdx]; 1062 1063 if ([self->footerRow isValueSettable]) 1064 [self->footerRow setValue:_row inComponent:comp]; 1065 if ([self->dayIndex isValueSettable]) 1066 [self->colIndex setIntValue:[colIdx intValue] inComponent:comp]; 1067 1068 result = [self->template invokeActionForRequest:_req inContext:_ctx]; 1069 1070 [_ctx deleteLastElementIDComponent]; // column idx 1071 [_ctx deleteLastElementIDComponent]; // section ('f') 1072 1073 return result; 1074} 1075 1076- (id)invokeActionForRequest:(WORequest *)_req inContext:(WOContext *)_ctx { 1077 WOComponent *comp; 1078 id result = nil; 1079 NSString *cid; 1080 NSString *sectionId; 1081 1082 cid = [_ctx currentElementID]; // get mode ("t" or "i" or "c") 1083 [_ctx consumeElementID]; 1084 [_ctx appendElementIDComponent:cid]; 1085 sectionId = [_ctx currentElementID]; // get section id 1086 [_ctx consumeElementID]; 1087 [_ctx appendElementIDComponent:sectionId]; 1088 1089 comp = [_ctx component]; 1090 1091 if ([cid isEqualToString:@"t"] || 1092 [cid isEqualToString:WEInfoElementID] || [cid isEqualToString:@"p"]) { 1093 if ([self->dayIndex isValueSettable]) 1094 [self->dayIndex setIntValue:[sectionId intValue] inComponent:comp]; 1095 result = [self->template invokeActionForRequest:_req inContext:_ctx]; 1096 } 1097 else if ([cid isEqualToString:@"c"]) { 1098 NSString *idxId; 1099 1100 if ([self->dayIndex isValueSettable]) 1101 [self->dayIndex setIntValue:([sectionId intValue] / 2) inComponent:comp]; 1102 1103 if ((idxId = [_ctx currentElementID])) { 1104 [_ctx consumeElementID]; // consume index-id 1105 [_ctx appendElementIDComponent:idxId]; 1106 1107 if (self->identifier) 1108 _applyIdentifier(self, comp, idxId); 1109 else 1110 _applyIndex(self, comp, [idxId intValue]); 1111 1112 result = [self->template invokeActionForRequest:_req inContext:_ctx]; 1113 1114 [_ctx deleteLastElementIDComponent]; // delete index-id 1115 } 1116 } 1117 else if ([cid isEqualToString:@"hr"]) { 1118 NSArray *headers; 1119 int idx; 1120 1121 headers = [self->headerRows valueInComponent:comp]; 1122 idx = [sectionId intValue]; 1123 if (idx >= (int)[headers count]) { 1124 [self warnWithFormat:@"WEWeekOverview: wrong headerrow index"]; 1125 } 1126 else { 1127 result = [self invokeActionForHeader:_req 1128 inContext:_ctx 1129 row:[headers objectAtIndex:idx]]; 1130 } 1131 } 1132 else if ([cid isEqualToString:@"fr"]) { 1133 NSArray *footers; 1134 int idx; 1135 1136 footers = [self->footerRows valueInComponent:comp]; 1137 idx = [sectionId intValue]; 1138 if (idx >= (int)[footers count]) { 1139 [self warnWithFormat:@"WEWeekOverview: wrong footerrow index"]; 1140 } 1141 else { 1142 result = [self invokeActionForFooter:_req 1143 inContext:_ctx 1144 row:[footers objectAtIndex:idx]]; 1145 } 1146 } 1147 else 1148 NSLog(@"WARNING! WEWeekOverview: wrong section"); 1149 1150 [_ctx deleteLastElementIDComponent]; // delete section id 1151 [_ctx deleteLastElementIDComponent]; // delete mode 1152 1153 return result; 1154} 1155 1156/* generating response */ 1157 1158- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx { 1159 WOComponent *comp; 1160 NSString *bgcolor, *style; 1161 NSString *w; // width 1162 NSString *b; // border 1163 NSString *cp; // cellpadding 1164 NSString *cs; // cellspacing 1165 int i; 1166 BOOL showWeekend; 1167 1168 if ([_ctx isRenderingDisabled]) { 1169 [self->template appendToResponse:_response inContext:_ctx]; 1170 return; 1171 } 1172 1173 [self _calcMatrixInContext:_ctx]; 1174 1175 comp = [_ctx component]; 1176 w = [self->width stringValueInComponent:comp]; 1177 b = [self->border stringValueInComponent:comp]; 1178 cs = [self->cellspacing stringValueInComponent:comp]; 1179 cp = [self->cellpadding stringValueInComponent:comp]; 1180 1181 showWeekend = (self->hideWeekend != nil) 1182 ? [self->hideWeekend boolValueInComponent:comp] ? NO : YES 1183 : YES; 1184 1185 // TODO: use CSS over here 1186 [_response appendContentString: 1187 @"<table border=\""]; 1188 [_response appendContentString:b]; // border 1189 [_response appendContentString:@"\" cellpadding=\""]; 1190 [_response appendContentString:cp]; // cellspacing 1191 [_response appendContentString:@"\" width=\""]; 1192 [_response appendContentString:w]; // width 1193 [_response appendContentString:@"\" cellspacing=\""]; 1194 [_response appendContentString:cs]; // cellspaing 1195 [_response appendContentString:@"\">"]; 1196 1197 /*** append title row (monday - saturday) ***/ 1198 [_response appendContentString:@"<tr>"]; 1199 for (i = 0; i < (showWeekend ? 6 : 5 ); i++) 1200 [self appendDateTitleToResponse:_response inContext:_ctx day:i]; 1201 [_response appendContentString:@"</tr>"]; 1202 1203 /**** header rows ****/ 1204 [self appendHeaderRowsToResponse:_response inContext:_ctx]; 1205 1206 /*** append AM content row + saturday ***/ 1207 [_response appendContentString:@"<tr>"]; 1208 1209 /* AM weekdays content (this is count=10 because we slot 0=AM/1=PM, etc) */ 1210 for (i = 0; i < 10; i = i + 2) { 1211 if ([self->dayIndex isValueSettable]) 1212 [self->dayIndex setIntValue:(i / 2) inComponent:comp]; 1213 1214 [_response appendContentString:@"<td valign=\"top\""]; 1215 if ((bgcolor = [self->contentColor stringValueInComponent:comp])) { 1216 [_response appendContentString:@" bgcolor=\""]; 1217 [_response appendContentString:bgcolor]; 1218 [_response appendContentCharacter:'"']; 1219 } 1220 if ((style = [self->contentStyle stringValueInComponent:comp])) { 1221 [_response appendContentString:@" class=\""]; 1222 [_response appendContentString:style]; 1223 [_response appendContentCharacter:'"']; 1224 } 1225 [_response appendContentCharacter:'>']; 1226 [self appendContentToResponse:_response inContext:_ctx index:i]; 1227 [_response appendContentString:@"</td>"]; 1228 } 1229 /* saturday content */ 1230 if (showWeekend) { 1231 if ([self->dayIndex isValueSettable]) 1232 [self->dayIndex setIntValue:5 inComponent:comp]; 1233 1234 [_response appendContentString:@"<td valign=\"top\""]; 1235 1236 if ((bgcolor = [self->contentColor stringValueInComponent:comp])) { 1237 [_response appendContentString:@" bgcolor=\""]; 1238 [_response appendContentString:bgcolor]; 1239 [_response appendContentCharacter:'"']; 1240 } 1241 if ((style = [self->contentStyle stringValueInComponent:comp])) { 1242 [_response appendContentString:@" class=\""]; 1243 [_response appendContentString:style]; 1244 [_response appendContentCharacter:'"']; 1245 } 1246 [_response appendContentCharacter:'>']; 1247 1248 /* 10 is Saturday AM, 11 is Saturday PM, week overview shows them in one */ 1249 [self appendContentToResponse:_response inContext:_ctx index:10]; 1250 [self appendContentToResponse:_response inContext:_ctx index:11]; 1251 [_response appendContentString:@"</td>"]; 1252 } 1253 1254 [_response appendContentString:@"</tr>"]; /* close AM row */ 1255 1256 /*** append PM content row + sunday ***/ 1257 [_response appendContentString:@"<tr>"]; 1258 1259 /* PM weekdays content */ 1260 for (i = 1; i < 11; i = i + 2) { 1261 if ([self->dayIndex isValueSettable]) 1262 [self->dayIndex setIntValue:(i/2) inComponent:comp]; 1263 1264 [_response appendContentString:@"<td valign=\"top\""]; 1265 1266 if (showWeekend) /* for Sunday we need an additional <tr> */ 1267 [_response appendContentString:@" rowspan=\"2\""]; 1268 1269 if ((bgcolor = [self->contentColor stringValueInComponent:comp])) { 1270 [_response appendContentString:@" bgcolor=\""]; 1271 [_response appendContentString:bgcolor]; 1272 [_response appendContentCharacter:'"']; 1273 } 1274 if ((style = [self->contentStyle stringValueInComponent:comp])) { 1275 [_response appendContentString:@" class=\""]; 1276 [_response appendContentString:style]; 1277 [_response appendContentCharacter:'"']; 1278 } 1279 [_response appendContentCharacter:'>']; 1280 1281 1282 [self appendContentToResponse:_response inContext:_ctx index:i]; 1283 [_response appendContentString:@"</td>"]; 1284 } 1285 1286 if (showWeekend) { 1287 /* sunday title */ 1288 [self appendDateTitleToResponse:_response inContext:_ctx day:6]; 1289 [_response appendContentString:@"</tr>"]; 1290 1291 /* sunday row */ 1292 [_response appendContentString:@"<tr>"]; 1293 1294 if ([self->dayIndex isValueSettable]) 1295 [self->dayIndex setIntValue:6 inComponent:comp]; 1296 1297 [_response appendContentString:@"<td valign=\"top\""]; 1298 if ((bgcolor = [self->contentColor stringValueInComponent:comp])) { 1299 [_response appendContentString:@" bgcolor=\""]; 1300 [_response appendContentString:bgcolor]; 1301 [_response appendContentCharacter:'"']; 1302 } 1303 [_response appendContentCharacter:'>']; 1304 1305 /* 12 is Sunday/AM, 13 is Sunday/PM */ 1306 [self appendContentToResponse:_response inContext:_ctx index:12]; 1307 [self appendContentToResponse:_response inContext:_ctx index:13]; 1308 [_response appendContentString:@"</td>"]; 1309 } 1310 1311 [_response appendContentString:@"</tr>"]; /* close PM row */ 1312 1313 /***** footer rows *****/ 1314 [self appendFooterRowsToResponse:_response inContext:_ctx]; 1315 1316 [_response appendContentString:@"</table>"]; 1317 1318 [self resetMatrix]; 1319} 1320 1321@end /* WeekOverview */ 1322 1323@interface WEWeekOverviewTitleMode : WEContextConditional 1324@end 1325 1326@implementation WEWeekOverviewTitleMode 1327- (NSString *)_contextKey { 1328 return WEWeekOverview_TitleMode; 1329} 1330 1331- (NSString *)_didMatchKey { 1332 return WEWeekOverview_TitleModeDidMatch; 1333} 1334@end /* WEWeekOverviewTitleMode */ 1335 1336// -- 1337 1338@interface WEWeekOverviewInfoMode : WEContextConditional 1339@end 1340 1341@implementation WEWeekOverviewInfoMode 1342- (NSString *)_contextKey { 1343 return WEWeekOverview_InfoMode; 1344} 1345@end /* WEWeekOverviewInfoMode */ 1346 1347// -- 1348 1349@interface WEWeekOverviewContentMode : WEContextConditional 1350@end 1351 1352@implementation WEWeekOverviewContentMode 1353- (NSString *)_contextKey { 1354 return WEWeekOverview_ContentMode; 1355} 1356@end /* WEWeekOverview_ContentMode */ 1357 1358// -- 1359 1360@interface WEWeekOverviewPMInfoMode : WEContextConditional 1361@end 1362 1363@implementation WEWeekOverviewPMInfoMode 1364- (NSString *)_contextKey { 1365 return WEWeekOverview_PMInfoMode; 1366} 1367@end /* WEWeekOverviewPMInfoMode */ 1368 1369@interface WEWeekOverviewHeaderMode : WEContextConditional 1370@end 1371 1372@implementation WEWeekOverviewHeaderMode 1373- (NSString *)_contextKey { 1374 return WEWeekOverview_HeaderRowMode; 1375} 1376@end /* WEWeekOverviewHeaderMode */ 1377 1378@interface WEWeekOverviewFooterMode : WEContextConditional 1379@end 1380 1381@implementation WEWeekOverviewFooterMode 1382- (NSString *)_contextKey { 1383 return WEWeekOverview_FooterRowMode; 1384} 1385@end /* WEWeekOverviewFooterMode */ 1386