From a469e8d790d81e9ee064f327b5c317ff7b57d069 Mon Sep 17 00:00:00 2001 From: helge Date: Thu, 18 Aug 2005 23:39:31 +0000 Subject: [PATCH] added new calendar calculation methods git-svn-id: http://svn.opengroupware.org/SOPE/trunk@1051 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- sope-core/NGExtensions/ChangeLog | 7 + .../NGExtensions/FdExt.subproj/GNUmakefile | 1 + .../FdExt.subproj/NSCalendarDate+matrix.m | 127 ++++++++++++++++ .../FdExt.subproj/NSCalendarDate+misc.m | 56 ++++++- .../NGExtensions/NSCalendarDate+misc.h | 21 ++- sope-core/NGExtensions/Version | 2 +- sope-core/samples/ChangeLog | 4 + sope-core/samples/ngcal.m | 139 +++++++++++++++++- 8 files changed, 343 insertions(+), 14 deletions(-) create mode 100644 sope-core/NGExtensions/FdExt.subproj/NSCalendarDate+matrix.m diff --git a/sope-core/NGExtensions/ChangeLog b/sope-core/NGExtensions/ChangeLog index 80c997d1..2314cb1f 100644 --- a/sope-core/NGExtensions/ChangeLog +++ b/sope-core/NGExtensions/ChangeLog @@ -1,3 +1,10 @@ +2005-08-19 Helge Hess + + * added method to calculate a calendar matrix for a date representing + a month (-calendarMatrixWithStartDayOfWeek:onlyCurrentMonth:), + added a method to turn an English/German string into a day-of-a-week + number (0=Sun-6=Sat) (v4.5.171) + 2005-08-07 Helge Hess * NGExtensions.xcodeproj: moved NGRuleParser.h from source to header diff --git a/sope-core/NGExtensions/FdExt.subproj/GNUmakefile b/sope-core/NGExtensions/FdExt.subproj/GNUmakefile index 82e1db2b..15ded15e 100644 --- a/sope-core/NGExtensions/FdExt.subproj/GNUmakefile +++ b/sope-core/NGExtensions/FdExt.subproj/GNUmakefile @@ -10,6 +10,7 @@ FdExt_OBJC_FILES = \ NSAutoreleasePool+misc.m \ NSBundle+misc.m \ NSCalendarDate+misc.m \ + NSCalendarDate+matrix.m \ NSData+gzip.m \ NSData+misc.m \ NSDictionary+misc.m \ diff --git a/sope-core/NGExtensions/FdExt.subproj/NSCalendarDate+matrix.m b/sope-core/NGExtensions/FdExt.subproj/NSCalendarDate+matrix.m new file mode 100644 index 00000000..bb5a359b --- /dev/null +++ b/sope-core/NGExtensions/FdExt.subproj/NSCalendarDate+matrix.m @@ -0,0 +1,127 @@ +/* + Copyright (C) 2005 SKYRIX Software AG + + This file is part of SOPE. + + SOPE is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + SOPE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with SOPE; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + +#include "NSCalendarDate+misc.h" +#include "common.h" + +@implementation NSCalendarDate(CalMatrix) + +static BOOL debugCalMatrix = NO; + +- (NSArray *)calendarMatrixWithStartDayOfWeek:(short)_caldow + onlyCurrentMonth:(BOOL)_onlyThisMonth +{ + // Note: we keep clock time! + NSAutoreleasePool *pool; + NSCalendarDate *firstInMonth; + NSArray *matrix; + NSArray *weeks[8] = { nil, nil, nil, nil, nil, nil, nil, nil }; + NSCalendarDate *week[8] = { nil, nil, nil, nil, nil, nil, nil, nil }; + unsigned firstDoW, numDaysInLastMonth, i, j, curday, curweek, curmonth; + + /* all the date operations use autorelease, so we wrap it in a pool */ + pool = [[NSAutoreleasePool alloc] init]; + + if (debugCalMatrix) + NSLog(@"calmatrix for: %@", self); + + firstInMonth = [[self firstDayOfMonth] beginOfDay]; + firstDoW = [firstInMonth dayOfWeek]; + curmonth = [firstInMonth monthOfYear]; + + numDaysInLastMonth = (firstDoW < _caldow) + ? (firstDoW + 7 - _caldow) + : (firstDoW - _caldow); + + if (debugCalMatrix) { + NSLog(@" LAST: %d FIRST-DOW: %d START-DOW: %d", + numDaysInLastMonth, firstDoW, _caldow); + } + + + /* first week */ + + if (_onlyThisMonth) { + j = 0; /* this is the position where first week days are added */ + } + else { + /* add dates from last month */ + for (i = numDaysInLastMonth; i > 0; i--) { + week[numDaysInLastMonth - i] = + [firstInMonth dateByAddingYears:0 months:0 days:-i]; + } + j = numDaysInLastMonth; + } + week[j] = firstInMonth; j++; + + for (i = numDaysInLastMonth + 1; i < 7; i++, j++) { + week[j] = [firstInMonth dateByAddingYears:0 months:0 + days:(i - numDaysInLastMonth)]; + } + curday = 7 - numDaysInLastMonth; + curweek = 1; + if (debugCalMatrix) + NSLog(@" current day after 1st week: %d, week: %d", curday, curweek); + + /* finish first week */ + weeks[0] = [[NSArray alloc] initWithObjects:week count:j]; + + + /* follow up weeks */ + + while (curweek < 7) { + BOOL foundNewMonth = NO; + + for (i = 0; i < 7; i++, curday++) { + week[i] = [firstInMonth dateByAddingYears:0 months:0 days:curday]; + + if (!foundNewMonth && curday > 27) { + foundNewMonth = ([week[i] monthOfYear] != curmonth) ? YES : NO; + if (foundNewMonth && _onlyThisMonth) + break; + } + } + + if (i > 0) { + weeks[curweek] = [[NSArray alloc] initWithObjects:week count:i]; + curweek++; + } + if (foundNewMonth) + break; + } + + + /* build final matrix */ + + matrix = [[NSArray alloc] initWithObjects:weeks count:curweek]; + for (i = 0; i < 8; i++) { + [weeks[i] release]; + weeks[i] = nil; + } + + if (debugCalMatrix) + NSLog(@"matrix for %@: %@", self, matrix); + + [pool release]; + return [matrix autorelease]; +} + +@end /* NSCalendarDate(CalMatrix) */ diff --git a/sope-core/NGExtensions/FdExt.subproj/NSCalendarDate+misc.m b/sope-core/NGExtensions/FdExt.subproj/NSCalendarDate+misc.m index edfb1822..b09b2523 100644 --- a/sope-core/NGExtensions/FdExt.subproj/NSCalendarDate+misc.m +++ b/sope-core/NGExtensions/FdExt.subproj/NSCalendarDate+misc.m @@ -562,17 +562,61 @@ year--; if (year <= 0) year--; - return [NSCalendarDate dateWithYear:year - month:month - day:day - hour:12 - minute:0 - second:0 + return [NSCalendarDate dateWithYear:year month:month day:day + hour:12 minute:0 second:0 timeZone:nil]; } @end /* NSCalendarDate(misc) */ + +@implementation NSString(FuzzyDayOfWeek) + +- (int)dayOfWeekInEnglishOrGerman { + NSString *s; + unichar c1; + unsigned len; + + if ((len = [self length]) == 0) + return -1; + + if (isdigit([self characterAtIndex:0])) + return [self intValue]; + + if (len < 2) /* need at least two chars */ + return -1; + + s = [self lowercaseString]; + c1 = [s characterAtIndex:1]; + switch ([s characterAtIndex:0]) { + case 'm': // Monday, Montag, Mittwoch + return (c1 == 'i') ? 3 /* Wednesday */ : 1 /* Monday */; + + case 't': // Tuesday, Thursday + return (c1 == 'u') ? 2 /* Tuesday */ : 4 /* Thursday */; + + case 'f': // Friday, Freitag + return 5 /* Friday */; + + case 's': // Saturday, Sunday, Samstag, Sonntag, Sonnabend + if (c1 == 'a') + return 6; /* Saturday */ + + if (c1 == 'o' && [s hasPrefix:@"sonna"]) + return 6; /* Sonnabend */ + + return 0 /* Sunday */; + + case 'w': // Wed + return 3 /* Wednesday */; + } + + return -1; +} + +@end /* NSString(FuzzyDayOfWeek) */ + + /* static linking */ void __link_NSCalendarDate_misc(void) { diff --git a/sope-core/NGExtensions/NGExtensions/NSCalendarDate+misc.h b/sope-core/NGExtensions/NGExtensions/NSCalendarDate+misc.h index 28d10fd3..14e6b763 100644 --- a/sope-core/NGExtensions/NGExtensions/NSCalendarDate+misc.h +++ b/sope-core/NGExtensions/NGExtensions/NSCalendarDate+misc.h @@ -23,11 +23,14 @@ #define __NGExtensions_NSCalendarDate_misc_H__ #import +#import #if NeXT_Foundation_LIBRARY || GNUSTEP_BASE_LIBRARY # import #endif +@class NSArray, NSTimeZone; + @interface NSCalendarDate(misc) - (int)weekOfMonth; @@ -74,7 +77,7 @@ elif year >= 0 && year < 70 year = 2000 + year */ - + - (NSCalendarDate *)y2kDate; /* @@ -103,4 +106,20 @@ @end + +@interface NSCalendarDate(CalMatrix) + +- (NSArray *)calendarMatrixWithStartDayOfWeek:(short)_caldow + onlyCurrentMonth:(BOOL)_onlyThisMonth; + +@end + + +@interface NSString(FuzzyDayOfWeek) + +- (int)dayOfWeekInEnglishOrGerman; + +@end + + #endif /* __NGExtensions_NSCalendarDate_misc_H__ */ diff --git a/sope-core/NGExtensions/Version b/sope-core/NGExtensions/Version index 336b5832..ea40701b 100644 --- a/sope-core/NGExtensions/Version +++ b/sope-core/NGExtensions/Version @@ -1,6 +1,6 @@ # version -SUBMINOR_VERSION:=170 +SUBMINOR_VERSION:=171 # v4.3.115 requires libFoundation v1.0.59 # v4.2.72 requires libEOControl v4.2.39 diff --git a/sope-core/samples/ChangeLog b/sope-core/samples/ChangeLog index 7bfb072c..9d8e009c 100644 --- a/sope-core/samples/ChangeLog +++ b/sope-core/samples/ChangeLog @@ -1,3 +1,7 @@ +2005-08-19 Helge Hess + + * ngcal.m: finished cal tool (requires libNGExtensions v4.5.171) + 2005-08-18 Helge Hess * prepared new ngcal tool for testing calendar calculations diff --git a/sope-core/samples/ngcal.m b/sope-core/samples/ngcal.m index e08781f1..9e96b9b5 100644 --- a/sope-core/samples/ngcal.m +++ b/sope-core/samples/ngcal.m @@ -21,6 +21,51 @@ #include "common.h" +#if 0 +@interface NSCalendarDate(CalMatrix) + +- (NSArray *)calendarMatrixWithStartDayOfWeek:(unsigned)_caldow + onlyCurrentMonth:(BOOL)_onlyThisMonth; + +@end + + + +@interface NSString(DayOfWeek) +- (int)dayOfWeek; +@end + +@implementation NSString(DayOfWeek) + +- (int)dayOfWeek { + NSString *s; + + if ([self length] == 0) + return -1; + + if (isdigit([self characterAtIndex:0])) + return [self intValue]; + + s = [self lowercaseString]; + switch ([s characterAtIndex:0]) { + case 'm': // Monday, Montag, Mittwoch + return ([s characterAtIndex:1] == 'i') ? 3 : 1; + case 't': // Tue, Thu + return ([s characterAtIndex:1] == 'u') ? 2 : 4; + case 'f': // Fri, Frei + return 5; + case 's': // Sat, Sun, Sam, Sonn + return ([s characterAtIndex:1] == 'a') ? 6 : 0; + case 'w': // Wed + return 3; + } + + return -1; +} + +@end /* NSString(DayOfWeek) */ +#endif + static void usage(NSArray *args) { printf("Usage: %s [[[month] year] startday]\n\n" "Arguments:\n" @@ -30,19 +75,88 @@ static void usage(NSArray *args) { , [[args objectAtIndex:0] cString]); } -static int doCalArgs(NSArray *args) { - NSCalendarDate *now; - unsigned startDayOfWeek, month, year; - if ([args containsObject:@"--help"] || [args containsObject:@"-h"]) { - usage(args); - return 0; +static void printMatrix(NSArray *weeks, int dow) { + unsigned week, weekCount; + + if (weeks == nil) { + NSLog(@"ERROR: got no week matrix!"); + return; } + for (week = 0; week < 7; week++) { + int dd = dow + week; + char c; + if (dd > 7 ) dd -= 7; + switch (dd) { + case 0: c = 'S'; break; + case 1: c = 'M'; break; + case 2: c = 'T'; break; + case 3: c = 'W'; break; + case 4: c = 'T'; break; + case 5: c = 'F'; break; + case 6: c = 'S'; break; + } + printf(" %2c", c); + } + puts(""); + + for (week = 0, weekCount = [weeks count]; week < weekCount; week++) { + NSArray *days; + unsigned day, dayCount; + + days = [weeks objectAtIndex:week]; + dayCount = [days count]; + + /* pad first week (could also print old dates) */ + if (week == 0) { + for (day = 7; day > dayCount; day--) + printf(" "); + } + + for (day = 0; day < dayCount; day++) { + NSCalendarDate *dayDate; + + dayDate = [days objectAtIndex:day]; + printf(" %2i", [dayDate dayOfMonth]); + } + puts(""); + } +} + + +static int doCalArgs(NSArray *args) { + NSCalendarDate *now, *start; + unsigned startDayOfWeek, month, year; + + /* defaults */ + now = [NSCalendarDate date]; startDayOfWeek = 1 /* Monday */; month = [now monthOfYear]; year = [now yearOfCommonEra]; + + /* arguments */ + + if ([args count] > 1) + month = [[args objectAtIndex:1] intValue]; + if ([args count] > 2) { + year = [[args objectAtIndex:2] intValue]; + if (year < 100) + year += 2000; + } + if ([args count] > 3) + startDayOfWeek = [[args objectAtIndex:3] dayOfWeekInEnglishOrGerman]; + + /* focus date */ + + start = [NSCalendarDate dateWithYear:year month:month day:1 + hour:0 minute:0 second:0 + timeZone:[now timeZone]]; + + printMatrix([start calendarMatrixWithStartDayOfWeek:startDayOfWeek + onlyCurrentMonth:NO], + startDayOfWeek); return 0; } @@ -55,6 +169,19 @@ int main(int argc, char **argv, char **env) { #if LIB_FOUNDATION_LIBRARY [NSProcessInfo initializeWithArguments:argv count:argc environment:env]; #endif + + /* + Note: we cannot check for those in the tool function because the - args + are stripped out + */ + if ([[[NSProcessInfo processInfo] arguments] containsObject:@"--help"]) { + usage([[NSProcessInfo processInfo] arguments]); + exit(0); + } + if ([[[NSProcessInfo processInfo] arguments] containsObject:@"-h"]) { + usage([[NSProcessInfo processInfo] arguments]); + exit(0); + } res = doCalArgs([[NSProcessInfo processInfo] argumentsWithoutDefaults]); -- 2.39.5