/* ** Utilities.m ** ** Copyright (c) 2004 ** ** Author: Yen-Ju ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program 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 General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "GNUstep.h" #include "Utilities.h" #include #include "Constants.h" #include "AttributesSource.h" #include "Criterion.h" #include "Sources.h" static NSString *my_library_path = nil; #ifdef GNUSTEP static NSString *LibraryLocation = @"~/"; #else static NSString *LibraryLocation = @"~/Documents/"; #endif static NSString *LibraryPath = @"MyLibrary"; NSString *MyLibraryPath(NSString *newPath) { if (newPath) { ASSIGN(my_library_path, [newPath stringByStandardizingPath]); } else { if (my_library_path == nil) { ASSIGN(my_library_path, [[LibraryLocation stringByStandardizingPath] stringByAppendingPathComponent: LibraryPath]); } } return my_library_path; } void addAvailableSubjectsIntoCriterion (Criterion *criterion) { /* Try to get all subject */ [criterion removeAllAvailableSubjects]; [criterion addAvailableSubject: sAnyText forType: CriterionAnyStringType]; [criterion addAvailableSubject: sTitle forType: CriterionStringType]; [criterion addAvailableSubject: sNote forType: CriterionStringType]; [criterion addAvailableSubject: sSource forType: CriterionSelectionType]; [criterion addAvailableSubject: sFilename forType: CriterionStringType]; [criterion addAvailableSubject: sFiletype forType: CriterionStringType]; [criterion addAvailableSubject: sFileContent forType: CriterionContentType]; AttributesSource *attributes = [AttributesSource sharedSource]; NSArray *allKeys; NSString *key, *type; unsigned int i, count; allKeys = [[attributes keysOfAttributes] allObjects]; count = [allKeys count]; for(i = 0; i < count; i++) { key = nameOfAttributeKey([allKeys objectAtIndex: i]); /* Add prefix "- " to indicates it is attribute */ key = [@"- " stringByAppendingString: key]; type = typeOfAttributeKey([allKeys objectAtIndex: i]); if ([type isEqualToString: AttributeStringType]) { [criterion addAvailableSubject: key forType: CriterionStringType]; } else if ([type isEqualToString: AttributeFloatType]) { [criterion addAvailableSubject: key forType: CriterionNumberType]; } else if ([type isEqualToString: AttributeIntegerType]) { [criterion addAvailableSubject: key forType: CriterionNumberType]; } else if ([type isEqualToString: AttributeCalendarDateType]) { [criterion addAvailableSubject: key forType: CriterionDateType]; } else { NSLog(@"internal Error (SmartFolderEditor): invalid attribute type"); } } } NSDictionary *attributesFromFile (NSString *absolutePath) { NSFileManager *fm = [NSFileManager defaultManager]; NSDictionary *attr = [fm fileAttributesAtPath: absolutePath traverseLink: YES]; if (attr == nil) return nil; NSDate *creationDate = [attr objectForKey: NSFileCreationDate]; NSDate *modificationDate = [attr objectForKey: NSFileModificationDate]; NSNumber *size = [attr objectForKey: NSFileSize]; NSString *owner = [NSString stringWithFormat: @"%@/%@", [attr objectForKey: NSFileOwnerAccountName], [attr objectForKey: NSFileGroupOwnerAccountName]]; return [NSDictionary dictionaryWithObjectsAndKeys: creationDate, keyOfAttributes(0, FileInfoCategory, FileInfoCreationDate, AttributeCalendarDateType), modificationDate, keyOfAttributes(1, FileInfoCategory, FileInfoModificationDate, AttributeCalendarDateType), owner, keyOfAttributes(2, FileInfoCategory, FileInfoOwner, AttributeStringType), size, keyOfAttributes(3, FileInfoCategory, FileInfoSize, AttributeIntegerType), nil]; } /* decode /xxx/yyy/type */ int orderOfAttributeKey (NSString *key) { return [[[[[key stringByDeletingLastPathComponent] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent] lastPathComponent] intValue]; } NSString *categoryOfAttributeKey (NSString *key) { return [[[key stringByDeletingLastPathComponent] stringByDeletingLastPathComponent] lastPathComponent];; } NSString *nameOfAttributeKey (NSString *key) { return [[key stringByDeletingLastPathComponent] lastPathComponent]; } NSString *typeOfAttributeKey (NSString *key) { return [key lastPathComponent]; } NSString *keyOfAttributes (int order, NSString *category, NSString *name, NSString *type) { return [[[[@"/" stringByAppendingPathComponent: [NSString stringWithFormat: @"%d", order]] stringByAppendingPathComponent: category] stringByAppendingPathComponent: name] stringByAppendingPathComponent: type]; } #include "RegEx.h" static NSString *RegExDotFloatNumberPattern = @"[-+]?[0-9]*\\.[0-9]+"; static NSString *RegExCommaFloatNumberPattern = @"[-+]?[0-9]*\\,[0-9]+"; //static NSString *RegularExpressionDisplayNumber3 = @"-9.99e-9"; ////static NSString *RegularExpressionNumber3 = @"[-+]?([0-9]*\\.)?[0-9]+([eE][-+]?[0-9]+)?"; static NSString *RegExIntegerPattern = @"[-+]?[0-9]+"; static NSString *RegExMMDDYYYYDatePattern = @"\\((0?[1-9]|1[012])/(0?[1-9]|[12][0-9]|3[01])(/[0-9]+)?\\)"; static NSString *RegExDDMMYYYYDatePattern = @"\\((0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])(/[0-9]+)?\\)"; static NSString *RegExYYYYMMDDDatePattern = @"\\(([0-9]+)/(0?[1-9]|1[012])/(0?[1-9]|[12][0-9]|3[01])\\)"; static NSString *RegExTimePattern = @"\\((0?[0-9]|1[0-9]|2[0-4]):(0?[0-9]|[1-6][0-9])(:(0?[0-9]|[1-6][0-9]))?\\)"; static NSString *RegExMMDDYYYYFullDatePattern = @"\\((0?[1-9]|1[012])/(0?[1-9]|[12][0-9]|3[01])(/[0-9]+)?[ ]+(0?[0-9]|1[0-9]|2[0-4]):(0?[0-9]|[1-6][0-9])(:(0?[0-9]|[1-6][0-9]))?\\)"; static NSString *RegExDDMMYYYYFullDatePattern = @"\\((0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])(/[0-9]+)?[ ]+(0?[0-9]|1[0-9]|2[0-4]):(0?[0-9]|[1-6][0-9])(:(0?[0-9]|[1-6][0-9]))?\\)"; static NSString *RegExYYYYMMDDFullDatePattern = @"\\(([0-9]+)/(0?[1-9]|1[012])/(0?[1-9]|[12][0-9]|3[01])[ ]+(0?[0-9]|1[0-9]|2[0-4]):(0?[0-9]|[1-6][0-9])(:(0?[0-9]|[1-6][0-9]))?\\)"; id objectFromRegExParsedString (NSString *string, RegExFloatNumber number, RegExDate date, RegExType *type) { NSString *floatPattern; NSString *integerPattern; NSString *datePattern; NSString *timePattern; NSString *fullDatePattern; NSRange range; NSString *s, *testString; NSCalendarDate *d, *currentDate = [NSCalendarDate calendarDate]; NSNumber *n; switch (number) { case RegExDotFloatNumber: floatPattern = RegExDotFloatNumberPattern; break; case RegExCommaFloatNumber: floatPattern = RegExCommaFloatNumberPattern; break; } integerPattern = RegExIntegerPattern; switch (date) { case RegExMMDDYYYYDate: datePattern = RegExMMDDYYYYDatePattern; fullDatePattern = RegExMMDDYYYYFullDatePattern; break; case RegExDDMMYYYYDate: datePattern = RegExDDMMYYYYDatePattern; fullDatePattern = RegExDDMMYYYYFullDatePattern; break; case RegExYYYYMMDDDate: datePattern = RegExYYYYMMDDDatePattern; fullDatePattern = RegExYYYYMMDDFullDatePattern; break; } timePattern = RegExTimePattern; if ([string isKindOfClass: [NSString class]] == NO) { NSLog(@"Internal Error (Regex): %@ is not a string", string); } testString = [string stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; /* Try CalendarDateDisplayFormat */ d = [NSCalendarDate dateWithString: testString calendarFormat: CalendarDateDisplayFormat]; if (d) { if ((type)) *type = RegExCalendarDateType; //NSLog(@"date %@", d); return d; } /* Date */ range = [RegExParser rangeOfString: datePattern inString: testString]; if ((range.location == 0) && (range.length) == [testString length]) { s = [testString substringWithRange: NSMakeRange(range.location+1, range.length-2)]; switch(date) { case RegExMMDDYYYYDate: { d = [NSCalendarDate dateWithString: s calendarFormat: @"%m/%d/%Y"]; if (d == nil) d = [NSCalendarDate dateWithString: s calendarFormat: @"%m/%d"]; break; } case RegExDDMMYYYYDate: { d = [NSCalendarDate dateWithString: s calendarFormat: @"%d/%m/%Y"]; if (d == nil) d = [NSCalendarDate dateWithString: s calendarFormat: @"%d/%m"]; break; } case RegExYYYYMMDDDate: { d = [NSCalendarDate dateWithString: s calendarFormat: @"%Y/%m/%d"]; break; } default: NSLog(@"Internal Error: Unknown Date Format"); } /* Put int time information */ if (d) { d = [NSCalendarDate dateWithString: [NSString stringWithFormat: @"%@ %@", [d descriptionWithCalendarFormat: @"%m/%d/%Y"], [currentDate descriptionWithCalendarFormat: @"%H:%M:%S"]] calendarFormat: @"%m/%d/%Y %H:%M:%S"]; [d setCalendarFormat: CalendarDateDisplayFormat]; if ((type)) *type = RegExCalendarDateType; //NSLog(@"date %@", d); return d; } else { NSLog(@"Invalide date: %@", s); } } /* Time */ range = [RegExParser rangeOfString: timePattern inString: testString]; if ((range.location == 0) && (range.length) == [testString length]) { s = [testString substringWithRange: NSMakeRange(range.location+1, range.length-2)]; d = [NSCalendarDate dateWithString: s calendarFormat: @"%H:%M:%S"]; if (d == nil) d = [NSCalendarDate dateWithString: s calendarFormat: @"%H:%M"]; /* Put int time information */ if (d) { d = [NSCalendarDate dateWithString: [NSString stringWithFormat: @"%@ %@", [currentDate descriptionWithCalendarFormat: @"%m/%d/%Y"], [d descriptionWithCalendarFormat: @"%H:%M:%S"]] calendarFormat: @"%m/%d/%Y %H:%M:%S"]; [d setCalendarFormat: CalendarDateDisplayFormat]; if ((type)) *type = RegExCalendarDateType; //NSLog(@"Time %@, type %d", d, *type); return d; } else { NSLog(@"Invalide Time: %@", s); } } /* Full time */ range = [RegExParser rangeOfString: fullDatePattern inString: testString]; if ((range.location == 0) && (range.length) == [testString length]) { NSArray *temp; s = [testString substringWithRange: NSMakeRange(range.location+1, range.length-2)]; temp = [s componentsSeparatedByString: @" "]; s = [NSString stringWithFormat: @"%@ %@", [temp objectAtIndex: 0], [temp lastObject]]; //NSLog(@"full time string %@", s); switch(date) { case RegExMMDDYYYYDate: { d = [NSCalendarDate dateWithString: s calendarFormat: @"%m/%d/%Y %H:%M:%S"]; if (d == nil) d = [NSCalendarDate dateWithString: s calendarFormat: @"%m/%d %H:%M:%S"]; if (d == nil) d = [NSCalendarDate dateWithString: s calendarFormat: @"%m/%d/%Y %H:%M"]; if (d == nil) d = [NSCalendarDate dateWithString: s calendarFormat: @"%m/%d %H:%M"]; break; } case RegExDDMMYYYYDate: { d = [NSCalendarDate dateWithString: s calendarFormat: @"%d/%m/%Y %H:%M:%S"]; if (d == nil) d = [NSCalendarDate dateWithString: s calendarFormat: @"%d/%m %H:%M:%S"]; if (d == nil) d = [NSCalendarDate dateWithString: s calendarFormat: @"%d/%m/%Y %H:%M"]; if (d == nil) d = [NSCalendarDate dateWithString: s calendarFormat: @"%d/%m/%Y %H:%M"]; break; } case RegExYYYYMMDDDate: { d = [NSCalendarDate dateWithString: s calendarFormat: @"%Y/%m/%d %H:%M:%S"]; if (d == nil) d = [NSCalendarDate dateWithString: s calendarFormat: @"%Y/%m/%d %H:%M"]; break; } default: NSLog(@"Internal Error: Unknown Full Time Format"); } /* Put int time information */ if (d) { [d setCalendarFormat: CalendarDateDisplayFormat]; if ((type)) *type = RegExCalendarDateType; //NSLog(@"Full Time %@", d ); return d; } else { NSLog(@"Invalide date: %@", s); } } /* Float */ range = [RegExParser rangeOfString: floatPattern inString: testString]; if ((range.location == 0) && (range.length) == [testString length]) { if (number == RegExCommaFloatNumber) /* -0,99 */ { range = [testString rangeOfString: @","]; s = [NSString stringWithFormat: @"%@.%@", [testString substringToIndex: range.location], [testString substringFromIndex: range.location+1]]; } else s = testString; n = [NSNumber numberWithDouble: [s doubleValue]]; if (n) { if ((type)) *type = RegExFloatNumberType; //NSLog(@"Float %@", n); return n; } else { NSLog(@"Invalide float number: %@", testString); } } /* Integer */ range = [RegExParser rangeOfString: integerPattern inString: testString]; if ((range.location == 0) && (range.length) == [testString length]) { n = [NSNumber numberWithInt: [testString intValue]]; if (n) { if ((type)) *type = RegExIntegerType; //NSLog(@"Integer %@", n); return n; } else { NSLog(@"Invalide integer number: %@", testString); } } if ((type)) *type = RegExStringType; //NSLog(@"String %@", string); return string; }