You can subscribe to this list here.
2007 |
Jan
|
Feb
|
Mar
(23) |
Apr
(254) |
May
(252) |
Jun
(209) |
Jul
(198) |
Aug
(192) |
Sep
(207) |
Oct
(120) |
Nov
(179) |
Dec
(52) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
(48) |
Feb
(69) |
Mar
(129) |
Apr
(250) |
May
(113) |
Jun
(177) |
Jul
(228) |
Aug
(155) |
Sep
(218) |
Oct
(185) |
Nov
(109) |
Dec
(88) |
2009 |
Jan
(83) |
Feb
(39) |
Mar
(70) |
Apr
(47) |
May
(48) |
Jun
(67) |
Jul
(61) |
Aug
(97) |
Sep
(221) |
Oct
(141) |
Nov
(70) |
Dec
(61) |
2010 |
Jan
(45) |
Feb
(76) |
Mar
(178) |
Apr
(106) |
May
(57) |
Jun
(32) |
Jul
(64) |
Aug
(98) |
Sep
(96) |
Oct
(19) |
Nov
(34) |
Dec
(117) |
2011 |
Jan
(55) |
Feb
(48) |
Mar
(64) |
Apr
(21) |
May
(39) |
Jun
(53) |
Jul
(99) |
Aug
(56) |
Sep
(39) |
Oct
(26) |
Nov
(19) |
Dec
(69) |
2012 |
Jan
(17) |
Feb
(40) |
Mar
(17) |
Apr
|
May
(2) |
Jun
(8) |
Jul
(2) |
Aug
(10) |
Sep
(10) |
Oct
(38) |
Nov
(48) |
Dec
(70) |
2013 |
Jan
(43) |
Feb
(47) |
Mar
(39) |
Apr
(37) |
May
(25) |
Jun
(6) |
Jul
(20) |
Aug
(49) |
Sep
(33) |
Oct
(34) |
Nov
(75) |
Dec
(6) |
2014 |
Jan
(32) |
Feb
(10) |
Mar
(17) |
Apr
|
May
|
Jun
(26) |
Jul
(5) |
Aug
|
Sep
(4) |
Oct
(23) |
Nov
(80) |
Dec
(48) |
2015 |
Jan
(80) |
Feb
(50) |
Mar
(58) |
Apr
(20) |
May
(11) |
Jun
(16) |
Jul
(24) |
Aug
(27) |
Sep
(56) |
Oct
(30) |
Nov
(16) |
Dec
(6) |
2016 |
Jan
(31) |
Feb
(14) |
Mar
(23) |
Apr
(17) |
May
(40) |
Jun
(12) |
Jul
(17) |
Aug
(9) |
Sep
(32) |
Oct
(36) |
Nov
(23) |
Dec
(9) |
2017 |
Jan
(37) |
Feb
(23) |
Mar
(65) |
Apr
(22) |
May
(6) |
Jun
(3) |
Jul
|
Aug
|
Sep
(3) |
Oct
(22) |
Nov
(63) |
Dec
(71) |
2018 |
Jan
(83) |
Feb
(21) |
Mar
(35) |
Apr
(44) |
May
(14) |
Jun
(12) |
Jul
(8) |
Aug
(18) |
Sep
(10) |
Oct
(145) |
Nov
(144) |
Dec
(76) |
2019 |
Jan
(18) |
Feb
(28) |
Mar
(5) |
Apr
(208) |
May
(291) |
Jun
(158) |
Jul
(27) |
Aug
(8) |
Sep
(10) |
Oct
(83) |
Nov
(41) |
Dec
(31) |
2020 |
Jan
(16) |
Feb
(46) |
Mar
(100) |
Apr
(78) |
May
(69) |
Jun
(71) |
Jul
(28) |
Aug
(131) |
Sep
(176) |
Oct
(89) |
Nov
(147) |
Dec
(19) |
2021 |
Jan
(19) |
Feb
(25) |
Mar
(91) |
Apr
(98) |
May
(14) |
Jun
(44) |
Jul
(8) |
Aug
(3) |
Sep
(38) |
Oct
(57) |
Nov
(97) |
Dec
(74) |
2022 |
Jan
(89) |
Feb
(47) |
Mar
(15) |
Apr
(50) |
May
(54) |
Jun
(56) |
Jul
(80) |
Aug
(12) |
Sep
(11) |
Oct
(60) |
Nov
(48) |
Dec
(4) |
2023 |
Jan
(75) |
Feb
(49) |
Mar
(84) |
Apr
(24) |
May
(13) |
Jun
(74) |
Jul
(32) |
Aug
(66) |
Sep
(50) |
Oct
(38) |
Nov
(105) |
Dec
(181) |
2024 |
Jan
(21) |
Feb
(49) |
Mar
(77) |
Apr
(84) |
May
(20) |
Jun
(71) |
Jul
(53) |
Aug
(33) |
Sep
(54) |
Oct
(124) |
Nov
(151) |
Dec
(73) |
2025 |
Jan
(61) |
Feb
(17) |
Mar
(136) |
Apr
(72) |
May
(200) |
Jun
(238) |
Jul
(91) |
Aug
(8) |
Sep
|
Oct
|
Nov
|
Dec
|
From: <ho...@us...> - 2007-09-09 13:26:54
|
Revision: 2856 http://skim-app.svn.sourceforge.net/skim-app/?rev=2856&view=rev Author: hofman Date: 2007-09-09 06:26:40 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Fix bugs in FDF parser. Modified Paths: -------------- trunk/SKFDFParser.m Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-09 13:25:28 UTC (rev 2855) +++ trunk/SKFDFParser.m 2007-09-09 13:26:40 UTC (rev 2856) @@ -86,6 +86,13 @@ if ([key isEqualToString:@"Type"]) { if (value = [self value:value ofClass:[NSString class] lookup:lookup]) { + if ([value isEqualToString:@"Annot"] == NO) + success = NO; + } else { + success = NO; + } + } else if ([key isEqualToString:@"Subtype"]) { + if (value = [self value:value ofClass:[NSString class] lookup:lookup]) { if ([value isEqualToString:@"Text"]) value = @"Note"; if ([validTypes containsObject:value]) @@ -114,8 +121,8 @@ } else if ([key isEqualToString:@"Page"]) { if (value = [self value:value ofClass:[NSNumber class] lookup:lookup]) [dictionary setObject:value forKey:@"pageIndex"]; - else - success = NO; + else{ + success = NO;} } else if ([key isEqualToString:@"C"]) { if ((value = [self value:value ofClass:[NSArray class] lookup:lookup]) && [value count] == 3) { float r, g, b; @@ -269,15 +276,19 @@ NSDictionary *trailer; SKIndirectObject *root; NSDictionary *rootDict; + NSDictionary *rootFDFDict; NSArray *annots; if ((fdfDict = [self fdfObjectsFromFDFString:string]) && (trailer = [fdfDict objectForKey:@"trailer"]) && ([trailer isKindOfClass:[NSDictionary class]]) && (root = [trailer objectForKey:@"Root"]) && + ([root isKindOfClass:[SKIndirectObject class]]) && (rootDict = [fdfDict objectForKey:root]) && ([rootDict isKindOfClass:[NSDictionary class]]) && - (annots = [trailer objectForKey:@"Annots"]) && + (rootFDFDict = [rootDict objectForKey:@"FDF"]) && + ([rootFDFDict isKindOfClass:[NSDictionary class]]) && + (annots = [rootFDFDict objectForKey:@"Annots"]) && ([annots isKindOfClass:[NSArray class]])) { NSEnumerator *annotEnum = [annots objectEnumerator]; @@ -317,36 +328,37 @@ [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; // Scan the FDF body - while (success = success && [scanner scanInt:&objNumber] && - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL] && - [scanner scanInt:&genNumber] && - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:NULL] && - [scanner scanString:@"obj" intoString:NULL]) { - + while (success && [scanner scanInt:&objNumber]) { [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; - if (success = [scanner scanFDFObject:&object]) { - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; - - if ([object isKindOfClass:[NSDictionary class]] && [scanner scanString:@"stream" intoString:NULL]) { - object = @""; - [scanner scanString:@"\n" intoString:NULL] || [scanner scanString:@"\r\n" intoString:NULL]; - - if ([scanner scanUpToString:@"endstream" intoString:&object]) { - int end = [object length]; - unichar ch = end ? [object characterAtIndex:end - 1] : 0; - if ([[NSCharacterSet newlineCharacterSet] characterIsMember:ch]) { - end--; - if (end && ch == '\n' && [object characterAtIndex:end - 1] == '\r') - end--; - object = [object substringToIndex:end]; + if (success = [scanner scanInt:&genNumber]) { + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:NULL]; + if ([scanner scanString:@"obj" intoString:NULL]) { + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + if (success = [scanner scanFDFObject:&object]) { + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + + if ([object isKindOfClass:[NSDictionary class]] && [scanner scanString:@"stream" intoString:NULL]) { + object = @""; + [scanner scanString:@"\n" intoString:NULL] || [scanner scanString:@"\r\n" intoString:NULL]; + + if ([scanner scanUpToString:@"endstream" intoString:&object]) { + int end = [object length]; + unichar ch = end ? [object characterAtIndex:end - 1] : 0; + if ([[NSCharacterSet newlineCharacterSet] characterIsMember:ch]) { + end--; + if (end && ch == '\n' && [object characterAtIndex:end - 1] == '\r') + end--; + object = [object substringToIndex:end]; + } + } + [scanner scanString:@"endstream" intoString:NULL]; } + [fdfDict setObject:object forKey:[SKIndirectObject indirectObjectWithNumber:objNumber generation:genNumber]]; + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + success = [scanner scanString:@"endobj" intoString:NULL]; + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; } - [scanner scanString:@"endstream" intoString:NULL]; - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; } - [fdfDict setObject:object forKey:[SKIndirectObject indirectObjectWithNumber:objNumber generation:genNumber]]; - success = [scanner scanString:@"endobj" intoString:NULL]; - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; } } @@ -381,12 +393,12 @@ - (BOOL)scanFDFObject:(id *)object { id tmpObject = nil; BOOL success = [self scanFDFName:&tmpObject] || + [self scanFDFArray:&tmpObject] || + [self scanFDFDictionary:&tmpObject] || [self scanFDFString:&tmpObject] || [self scanFDFHexString:&tmpObject] || + [self scanFDFIndirectObject:&tmpObject] || [self scanFDFNumber:&tmpObject] || - [self scanFDFArray:&tmpObject] || - [self scanFDFDictionary:&tmpObject] || - [self scanFDFIndirectObject:&tmpObject] || [self scanString:@"null" intoString:NULL]; if (success && object) @@ -408,10 +420,13 @@ success = NO; break; } - if (ch == ']') + if (ch == ']') { + [self scanCharacter:NULL]; break; - else if ((success = [self scanFDFObject:&object]) && object) - [tmpArray addObject:object]; + } else if (success = [self scanFDFObject:&object]) { + if (object) + [tmpArray addObject:object]; + } } if (success && array) @@ -422,18 +437,11 @@ - (BOOL)scanFDFDictionary:(NSDictionary **)dictionary { NSMutableDictionary *tmpDict = [NSMutableDictionary dictionary]; - unichar ch; NSString *key; id object; BOOL success = [self scanString:@"<<" intoString:NULL]; while (success) { - [self scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; - - if ([self peekCharacter:&ch] == NO) { - success = NO; - break; - } if ([self scanFDFName:&key]) { [self scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; if ((success = [self scanFDFObject:&object]) && object) @@ -443,6 +451,7 @@ } else { success = NO; } + [self scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; } if (success && dictionary) @@ -589,7 +598,7 @@ if (whitespaceOrDelimiterCharSet == nil) { NSMutableCharacterSet *tmpSet = [[NSCharacterSet whitespaceAndNewlineCharacterSet] mutableCopy]; [tmpSet addCharactersInString:@"()<>[]{}/%"]; - whitespaceOrDelimiterCharSet = [[tmpSet invertedSet] copy]; + whitespaceOrDelimiterCharSet = [tmpSet copy]; [tmpSet release]; } return [self scanString:@"/" intoString:NULL] && [self scanUpToCharactersFromSet:whitespaceOrDelimiterCharSet intoString:string]; @@ -647,6 +656,10 @@ return [self retain]; } +- (NSString *)description { + return [NSString stringWithFormat:@"<%@: %i %i>",[self class], objectNumber, generationNumber]; +} + - (BOOL)isEqual:(id)other { return [self isMemberOfClass:[other class]] && [self objectNumber] == [other objectNumber] && [self generationNumber] == [other generationNumber]; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 13:25:29
|
Revision: 2855 http://skim-app.svn.sourceforge.net/skim-app/?rev=2855&view=rev Author: hofman Date: 2007-09-09 06:25:28 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Fix obj in FDF string value. Modified Paths: -------------- trunk/SKDocument.m Modified: trunk/SKDocument.m =================================================================== --- trunk/SKDocument.m 2007-09-09 10:18:35 UTC (rev 2854) +++ trunk/SKDocument.m 2007-09-09 13:25:28 UTC (rev 2855) @@ -1373,7 +1373,7 @@ [string appendFormat:@"/ID[%@]", fileIDString]; [string appendString:@">>>>\nendobj\n"]; for (i = 0; i < count; i++) - [string appendFormat:@"obj %i 0<<%@>>\nendobj\n", i + 2, [[[self notes] objectAtIndex:i] fdfString]]; + [string appendFormat:@"%i 0 obj<<%@>>\nendobj\n", i + 2, [[[self notes] objectAtIndex:i] fdfString]]; [string appendString:@"trailer\n<</Root 1 0 R>>\n%%EOF\n"]; return string; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 10:18:36
|
Revision: 2854 http://skim-app.svn.sourceforge.net/skim-app/?rev=2854&view=rev Author: hofman Date: 2007-09-09 03:18:35 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Close FDF dictionary. Modified Paths: -------------- trunk/SKDocument.m Modified: trunk/SKDocument.m =================================================================== --- trunk/SKDocument.m 2007-09-08 20:17:43 UTC (rev 2853) +++ trunk/SKDocument.m 2007-09-09 10:18:35 UTC (rev 2854) @@ -1371,7 +1371,7 @@ [string appendFormat:@"]/F(%@)", filename ? [filename stringByEscapingParenthesis] : @""]; if (fileIDString) [string appendFormat:@"/ID[%@]", fileIDString]; - [string appendString:@">>\nendobj\n"]; + [string appendString:@">>>>\nendobj\n"]; for (i = 0; i < count; i++) [string appendFormat:@"obj %i 0<<%@>>\nendobj\n", i + 2, [[[self notes] objectAtIndex:i] fdfString]]; [string appendString:@"trailer\n<</Root 1 0 R>>\n%%EOF\n"]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-08 20:17:45
|
Revision: 2853 http://skim-app.svn.sourceforge.net/skim-app/?rev=2853&view=rev Author: hofman Date: 2007-09-08 13:17:43 -0700 (Sat, 08 Sep 2007) Log Message: ----------- Add hidden defaults for hover window size. Modified Paths: -------------- trunk/InitialUserDefaults.plist trunk/SKPDFHoverWindow.m Modified: trunk/InitialUserDefaults.plist =================================================================== --- trunk/InitialUserDefaults.plist 2007-09-08 18:50:36 UTC (rev 2852) +++ trunk/InitialUserDefaults.plist 2007-09-08 20:17:43 UTC (rev 2853) @@ -232,6 +232,10 @@ <real>400.0</real> <key>SKLargeMagnificationWidth</key> <real>600.0</real> + <key>SKToolTipWidth</key> + <real>400.0</real> + <key>SKToolTipHeight</key> + <real>80.0</real> <key>SKAutoOpenDownloadsWindow</key> <true/> <key>SKAutoRemoveFinishedDownloads</key> Modified: trunk/SKPDFHoverWindow.m =================================================================== --- trunk/SKPDFHoverWindow.m 2007-09-08 18:50:36 UTC (rev 2852) +++ trunk/SKPDFHoverWindow.m 2007-09-08 20:17:43 UTC (rev 2853) @@ -43,8 +43,6 @@ #import "NSParagraphStyle_SKExtensions.h" #import "NSGeometry_SKExtensions.h" -#define WINDOW_WIDTH 400.0 -#define WINDOW_HEIGHT 80.0 #define WINDOW_OFFSET 20.0 #define TEXT_MARGIN_X 2.0 #define TEXT_MARGIN_Y 2.0 @@ -179,8 +177,9 @@ } - (void)showWithTimer:(NSTimer *)aTimer { + NSUserDefaults *sud = [NSUserDefaults standardUserDefaults]; NSPoint thePoint = NSEqualPoints(point, NSZeroPoint) ? [NSEvent mouseLocation] : point; - NSRect contentRect = NSMakeRect(thePoint.x, thePoint.y - WINDOW_OFFSET, WINDOW_WIDTH, WINDOW_HEIGHT); + NSRect contentRect = NSMakeRect(thePoint.x, thePoint.y - WINDOW_OFFSET, [sud floatForKey:@"SKToolTipWidth"], [sud floatForKey:@"SKToolTipHeight"]); NSImage *image = nil; NSAttributedString *text = nil; NSString *string = nil; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-08 18:50:39
|
Revision: 2852 http://skim-app.svn.sourceforge.net/skim-app/?rev=2852&view=rev Author: hofman Date: 2007-09-08 11:50:36 -0700 (Sat, 08 Sep 2007) Log Message: ----------- Implement hash for direct object and use unsigned for ivars. Modified Paths: -------------- trunk/SKFDFParser.m Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-08 16:47:47 UTC (rev 2851) +++ trunk/SKFDFParser.m 2007-09-08 18:50:36 UTC (rev 2852) @@ -55,13 +55,13 @@ #pragma mark - @interface SKIndirectObject : NSObject <NSCopying> { - int objectNumber; - int generationNumber; + unsigned int objectNumber; + unsigned int generationNumber; } -+ (id)indirectObjectWithNumber:(int)objNumber generation:(int)genNumber; -- (id)initWithNumber:(int)objNumber generation:(int)genNumber; -- (int)objectNumber; -- (int)generationNumber; ++ (id)indirectObjectWithNumber:(unsigned int)objNumber generation:(unsigned int)genNumber; +- (id)initWithNumber:(unsigned int)objNumber generation:(unsigned int)genNumber; +- (unsigned int)objectNumber; +- (unsigned int)generationNumber; @end #pragma mark - @@ -631,11 +631,11 @@ @implementation SKIndirectObject : NSObject -+ (id)indirectObjectWithNumber:(int)objNumber generation:(int)genNumber { ++ (id)indirectObjectWithNumber:(unsigned int)objNumber generation:(unsigned int)genNumber { return [[[self alloc] initWithNumber:objNumber generation:genNumber] autorelease]; } -- (id)initWithNumber:(int)objNumber generation:(int)genNumber { +- (id)initWithNumber:(unsigned int)objNumber generation:(unsigned int)genNumber { if (self = [super init]) { objectNumber = objNumber; generationNumber = genNumber; @@ -651,11 +651,15 @@ return [self isMemberOfClass:[other class]] && [self objectNumber] == [other objectNumber] && [self generationNumber] == [other generationNumber]; } -- (int)objectNumber { +- (unsigned int)hash { + return (objectNumber << 16) | generationNumber; +} + +- (unsigned int)objectNumber { return objectNumber; } -- (int)generationNumber { +- (unsigned int)generationNumber { return generationNumber; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-08 16:47:51
|
Revision: 2851 http://skim-app.svn.sourceforge.net/skim-app/?rev=2851&view=rev Author: hofman Date: 2007-09-08 09:47:47 -0700 (Sat, 08 Sep 2007) Log Message: ----------- add a space to separate a number in fdf string. Modified Paths: -------------- trunk/SKPDFAnnotationNote.m Modified: trunk/SKPDFAnnotationNote.m =================================================================== --- trunk/SKPDFAnnotationNote.m 2007-09-08 14:26:08 UTC (rev 2850) +++ trunk/SKPDFAnnotationNote.m 2007-09-08 16:47:47 UTC (rev 2851) @@ -243,7 +243,7 @@ [string appendFormat:@"/C[%f %f %f]", r, g, b]; [string appendFormat:@"/Page %i", [self pageIndex]]; if (border) { - [string appendFormat:@"/BS<</W%f/S", [border lineWidth]]; + [string appendFormat:@"/BS<</W %f/S", [border lineWidth]]; switch ([border style]) { case kPDFBorderStyleSolid: [string appendString:@"/S"]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-08 14:26:10
|
Revision: 2850 http://skim-app.svn.sourceforge.net/skim-app/?rev=2850&view=rev Author: hofman Date: 2007-09-08 07:26:08 -0700 (Sat, 08 Sep 2007) Log Message: ----------- fix typo Modified Paths: -------------- trunk/SKFDFParser.m Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-08 14:25:28 UTC (rev 2849) +++ trunk/SKFDFParser.m 2007-09-08 14:26:08 UTC (rev 2850) @@ -86,7 +86,7 @@ if ([key isEqualToString:@"Type"]) { if (value = [self value:value ofClass:[NSString class] lookup:lookup]) { - if ([value isEqualtoString:@"Text"]) + if ([value isEqualToString:@"Text"]) value = @"Note"; if ([validTypes containsObject:value]) [dictionary setObject:value forKey:@"type"]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-08 14:25:29
|
Revision: 2849 http://skim-app.svn.sourceforge.net/skim-app/?rev=2849&view=rev Author: hofman Date: 2007-09-08 07:25:28 -0700 (Sat, 08 Sep 2007) Log Message: ----------- Discard annotations we don't handle from FDF. Modified Paths: -------------- trunk/SKFDFParser.m Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-08 14:20:39 UTC (rev 2848) +++ trunk/SKFDFParser.m 2007-09-08 14:25:28 UTC (rev 2849) @@ -76,6 +76,7 @@ + (NSDictionary *)noteDictionary:(NSDictionary *)dict lookup:(NSDictionary *)lookup { NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + NSSet *validTypes = [NSSet setWithObjects:@"FreeText", @"Note", @"Circle", @"Square", @"Highlight", @"Underline", @"StrikeOut", @"Line", nil]; NSEnumerator *keyEnum = [dict keyEnumerator]; NSString *key; BOOL success = YES; @@ -84,10 +85,16 @@ id value = [dict valueForKey:key]; if ([key isEqualToString:@"Type"]) { - if (value = [self value:value ofClass:[NSString class] lookup:lookup]) - [dictionary setObject:value forKey:@"type"]; - else + if (value = [self value:value ofClass:[NSString class] lookup:lookup]) { + if ([value isEqualtoString:@"Text"]) + value = @"Note"; + if ([validTypes containsObject:value]) + [dictionary setObject:value forKey:@"type"]; + else + success = NO; + } else { success = NO; + } } else if ([key isEqualToString:@"Contents"]) { if (value = [self value:value ofClass:[NSString class] lookup:lookup]) [dictionary setObject:value forKey:@"contents"]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-08 14:20:45
|
Revision: 2848 http://skim-app.svn.sourceforge.net/skim-app/?rev=2848&view=rev Author: hofman Date: 2007-09-08 07:20:39 -0700 (Sat, 08 Sep 2007) Log Message: ----------- Resolve some more indirect objects when parsing FDF. Declare selectors to satisfy compiler. Remove inline declaration for a recursive functions. Modified Paths: -------------- trunk/NSCell_SKExtensions.h trunk/SKFDFParser.m trunk/SKInfoWindowController.m trunk/SKTypeSelectHelper.m Modified: trunk/NSCell_SKExtensions.h =================================================================== --- trunk/NSCell_SKExtensions.h 2007-09-08 14:07:22 UTC (rev 2847) +++ trunk/NSCell_SKExtensions.h 2007-09-08 14:20:39 UTC (rev 2848) @@ -42,4 +42,5 @@ @interface NSCell (SKExtensions) +- (NSColor *)replacementHighlightColorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView; @end Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-08 14:07:22 UTC (rev 2847) +++ trunk/SKFDFParser.m 2007-09-08 14:20:39 UTC (rev 2848) @@ -268,6 +268,7 @@ (trailer = [fdfDict objectForKey:@"trailer"]) && ([trailer isKindOfClass:[NSDictionary class]]) && (root = [trailer objectForKey:@"Root"]) && + (rootDict = [fdfDict objectForKey:root]) && ([rootDict isKindOfClass:[NSDictionary class]]) && (annots = [trailer objectForKey:@"Annots"]) && ([annots isKindOfClass:[NSArray class]])) { @@ -277,6 +278,8 @@ array = [NSMutableArray array]; while (dict = [annotEnum nextObject]) { + while ([dict isKindOfClass:[SKIndirectObject class]]) + dict = [fdfDict objectForKey:dict]; if ([dict isKindOfClass:[NSDictionary class]] == NO) return nil; if (dict = [self noteDictionary:dict lookup:fdfDict]) Modified: trunk/SKInfoWindowController.m =================================================================== --- trunk/SKInfoWindowController.m 2007-09-08 14:07:22 UTC (rev 2847) +++ trunk/SKInfoWindowController.m 2007-09-08 14:20:39 UTC (rev 2848) @@ -81,8 +81,7 @@ [self setWindowFrameAutosaveName:@"SKInfoWindow"]; } -static inline -NSString *SKFileSizeStringForFileURL(NSURL *fileURL, unsigned long long *physicalSizePtr, unsigned long long *logicalSizePtr) { +static NSString *SKFileSizeStringForFileURL(NSURL *fileURL, unsigned long long *physicalSizePtr, unsigned long long *logicalSizePtr) { if (fileURL == nil) return @""; Modified: trunk/SKTypeSelectHelper.m =================================================================== --- trunk/SKTypeSelectHelper.m 2007-09-08 14:07:22 UTC (rev 2847) +++ trunk/SKTypeSelectHelper.m 2007-09-08 14:20:39 UTC (rev 2848) @@ -49,6 +49,7 @@ @end @interface NSWindow (SKTypeAheadHelperExtensions) +- (BOOL)replacementMakeFirstResponder:(NSResponder *)aResponder; @end #pragma mark - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-08 14:07:24
|
Revision: 2847 http://skim-app.svn.sourceforge.net/skim-app/?rev=2847&view=rev Author: hofman Date: 2007-09-08 07:07:22 -0700 (Sat, 08 Sep 2007) Log Message: ----------- Add file ID to FDF file. Add data category to find a pattern. Add license info. Modified Paths: -------------- trunk/SKDocument.m trunk/SKFDFParser.h trunk/SKFDFParser.m trunk/Skim.xcodeproj/project.pbxproj Added Paths: ----------- trunk/NSData_SKExtensions.h trunk/NSData_SKExtensions.m Added: trunk/NSData_SKExtensions.h =================================================================== --- trunk/NSData_SKExtensions.h (rev 0) +++ trunk/NSData_SKExtensions.h 2007-09-08 14:07:22 UTC (rev 2847) @@ -0,0 +1,46 @@ +// +// NSData_SKExtensions.h +// Skim +// +// Created by Christiaan Hofman on 9/8/07. +/* + This software is Copyright (c) 2007 + Christiaan Hofman. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Neither the name of Christiaan Hofman nor the names of any + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import <Cocoa/Cocoa.h> + + +@interface NSData (SKExtensions) +- (unsigned)indexOfBytes:(const void *)patternBytes length:(unsigned int)patternLength; +- (unsigned)indexOfBytes:(const void *)patternBytes length:(unsigned int)patternLength options:(int)mask; +- (unsigned)indexOfBytes:(const void *)patternBytes length:(unsigned int)patternLength options:(int)mask range:(NSRange)searchRange; +@end Added: trunk/NSData_SKExtensions.m =================================================================== --- trunk/NSData_SKExtensions.m (rev 0) +++ trunk/NSData_SKExtensions.m 2007-09-08 14:07:22 UTC (rev 2847) @@ -0,0 +1,101 @@ +// +// NSData_SKExtensions.m +// Skim +// +// Created by Christiaan Hofman on 9/8/07. +/* + This software is Copyright (c) 2007 + Christiaan Hofman. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Neither the name of Christiaan Hofman nor the names of any + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "NSData_SKExtensions.h" + + +@implementation NSData (SKExtensions) + +- (unsigned)indexOfBytes:(const void *)patternBytes length:(unsigned int)patternLength { + return [self indexOfBytes:patternBytes length:patternLength options:0 range:NSMakeRange(0, [self length])]; +} + +- (unsigned)indexOfBytes:(const void *)patternBytes length:(unsigned int)patternLength options:(int)mask { + return [self indexOfBytes:patternBytes length:patternLength options:mask range:NSMakeRange(0, [self length])]; +} + +- (unsigned)indexOfBytes:(const void *)patternBytes length:(unsigned int)patternLength options:(int)mask range:(NSRange)searchRange { + unsigned const char *selfBufferStart, *selfPtr, *selfPtrEnd, *selfPtrMax; + unsigned const char firstPatternByte = *(const char *)patternBytes; + unsigned int selfLength; + BOOL backward = (mask & NSBackwardsSearch) != 0; + + selfLength = [self length]; + if (searchRange.location > selfLength || NSMaxRange(searchRange) > selfLength) + [NSException raise:NSRangeException format:@"Range {%u,%u} exceeds length %u", searchRange.location, searchRange.length, selfLength]; + + if (patternLength == 0) + return searchRange.location; + if (patternLength > searchRange.length) { + // This test is a nice shortcut, but it's also necessary to avoid crashing: zero-length CFDatas will sometimes(?) return NULL for their bytes pointer, and the resulting pointer arithmetic can underflow. + return NSNotFound; + } + + selfBufferStart = [self bytes]; + selfPtrMax = selfBufferStart + NSMaxRange(searchRange) + 1 - patternLength; + if (backward) { + selfPtr = selfPtrMax - 1; + selfPtrEnd = selfBufferStart + searchRange.location - 1; + } else { + selfPtr = selfBufferStart + searchRange.location; + selfPtrEnd = selfPtrMax; + } + + for (;;) { + if (memcmp(selfPtr, patternBytes, patternLength) == 0) + return (selfPtr - selfBufferStart); + + if (backward) { + do { + selfPtr--; + } while (*selfPtr != firstPatternByte && selfPtr > selfPtrEnd); + if (*selfPtr != firstPatternByte) + break; + } else { + selfPtr++; + if (selfPtr == selfPtrEnd) + break; + selfPtr = memchr(selfPtr, firstPatternByte, (selfPtrMax - selfPtr)); + if (selfPtr == NULL) + break; + } + } + return NSNotFound; +} + +@end Modified: trunk/SKDocument.m =================================================================== --- trunk/SKDocument.m 2007-09-08 12:36:53 UTC (rev 2846) +++ trunk/SKDocument.m 2007-09-08 14:07:22 UTC (rev 2847) @@ -62,6 +62,7 @@ #import "Files_SKExtensions.h" #import "NSTask_SKExtensions.h" #import "SKFDFParser.h" +#import "NSData_SKExtensions.h" #define BUNDLE_DATA_FILENAME @"data" @@ -1055,25 +1056,11 @@ unsigned long long startPos = fileEnd < 1024 ? 0 : fileEnd - 1024; [fh seekToFileOffset:startPos]; NSData *trailerData = [fh readDataToEndOfFile]; - - // done with the filehandle and offsets; now we have the trailer as NSData, so try to find the marker pattern in it const char *pattern = "%%EOF"; unsigned patternLength = strlen(pattern); - unsigned trailerLength = [trailerData length]; - BOOL foundTrailer = NO; + unsigned trailerIndex = [trailerData indexOfBytes:pattern length:patternLength options:NSBackwardsSearch]; - int i, startIndex = trailerLength - patternLength; - const char *buffer = [trailerData bytes]; - - // Adobe says to search from the end, so we get the last %%EOF - for (i = startIndex; i >= 0 && NO == foundTrailer; i -= 1) { - - // don't bother comparing if the first byte doesn't match - if (buffer[i] == pattern[0]) - foundTrailer = (bcmp(&buffer[i], pattern, patternLength) == 0); - } - - if (foundTrailer) { + if (trailerIndex != NSNotFound) { if (autoUpdate && [self isDocumentEdited] == NO) { // tried queuing this with a delayed perform/cancel previous, but revert takes long enough that the cancel was never used [self fileUpdateAlertDidEnd:nil returnCode:NSAlertDefaultReturn contextInfo:NULL]; @@ -1322,8 +1309,54 @@ return data; } +- (NSString *)fileIDString; { + if (pdfData == nil) + return nil; + const char *EOFPattern = "%%EOF"; + const char *trailerPattern = "trailer"; + const char *IDPattern = "/ID"; + const char *startArrayPattern = "["; + const char *endArrayPattern = "]"; + unsigned patternLength = strlen(EOFPattern); + NSRange range = NSMakeRange([pdfData length] - 1024, 1024); + if (range.location < 0) + range = NSMakeRange(0, [pdfData length]); + unsigned EOFIndex = [pdfData indexOfBytes:EOFPattern length:patternLength options:NSBackwardsSearch range:range]; + unsigned trailerIndex, IDIndex, startArrayIndex, endArrayIndex; + NSData *fileIDData; + + if (EOFIndex != NSNotFound) { + range = NSMakeRange(EOFIndex - 2048, 2048); + if (range.location < 0) + range = NSMakeRange(0, EOFIndex); + patternLength = strlen(trailerPattern); + trailerIndex = [pdfData indexOfBytes:trailerPattern length:patternLength options:NSBackwardsSearch range:range]; + if (trailerIndex != NSNotFound) { + range = NSMakeRange(trailerIndex + patternLength, EOFIndex - trailerIndex - patternLength); + patternLength = strlen(IDPattern); + IDIndex = [pdfData indexOfBytes:IDPattern length:patternLength options:0 range:range]; + if (IDIndex != NSNotFound) { + range = NSMakeRange(IDIndex + patternLength, EOFIndex - IDIndex - patternLength); + patternLength = strlen(startArrayPattern); + startArrayIndex = [pdfData indexOfBytes:startArrayPattern length:patternLength options:0 range:range]; + if (startArrayIndex != NSNotFound) { + range = NSMakeRange(startArrayIndex + patternLength, EOFIndex - startArrayIndex - patternLength); + patternLength = strlen(endArrayPattern); + endArrayIndex = [pdfData indexOfBytes:endArrayPattern length:patternLength options:0 range:range]; + if (endArrayIndex != NSNotFound) { + fileIDData = [pdfData subdataWithRange:NSMakeRange(startArrayIndex + 1, endArrayIndex - startArrayIndex - 1)]; + return [[[NSString alloc] initWithData:fileIDData encoding:NSISOLatin1StringEncoding] autorelease]; + } + } + } + } + } + return nil; +} + - (NSString *)notesFDFString { NSString *filename = [[[self fileURL] path] lastPathComponent]; + NSString *fileIDString = [self fileIDString]; int i, count = [[self notes] count]; NSMutableString *string = [NSMutableString stringWithFormat:@"%%FDF-1.2\n%%%C%C%C%C\n1 0 obj<</FDF<<", 0xe2, 0xe3, 0xcf, 0xd3]; [string appendString:@"/Annots["]; @@ -1335,7 +1368,10 @@ if (index != NSNotFound) filename = [filename stringByAppendingPathComponent:[files objectAtIndex:index]]; } - [string appendFormat:@"]/F(%@)>>\nendobj\n", filename ? [filename stringByEscapingParenthesis] : @""]; + [string appendFormat:@"]/F(%@)", filename ? [filename stringByEscapingParenthesis] : @""]; + if (fileIDString) + [string appendFormat:@"/ID[%@]", fileIDString]; + [string appendString:@">>\nendobj\n"]; for (i = 0; i < count; i++) [string appendFormat:@"obj %i 0<<%@>>\nendobj\n", i + 2, [[[self notes] objectAtIndex:i] fdfString]]; [string appendString:@"trailer\n<</Root 1 0 R>>\n%%EOF\n"]; Modified: trunk/SKFDFParser.h =================================================================== --- trunk/SKFDFParser.h 2007-09-08 12:36:53 UTC (rev 2846) +++ trunk/SKFDFParser.h 2007-09-08 14:07:22 UTC (rev 2847) @@ -2,10 +2,40 @@ // SKFDFParser.h // Skim // -// Created by Christiaan Hofman on 6/9/07. -// Copyright 2007 Christiaan Hofman. All rights reserved. -// +// Created by Christiaan Hofman on 9/6/07. +/* + This software is Copyright (c) 2007 + Christiaan Hofman. All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Neither the name of Christiaan Hofman nor the names of any + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + #import <Cocoa/Cocoa.h> Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-08 12:36:53 UTC (rev 2846) +++ trunk/SKFDFParser.m 2007-09-08 14:07:22 UTC (rev 2847) @@ -2,10 +2,40 @@ // SKFDFParser.m // Skim // -// Created by Christiaan Hofman on 6/9/07. -// Copyright 2007 Christiaan Hofman. All rights reserved. -// +// Created by Christiaan Hofman on 9/6/07. +/* + This software is Copyright (c) 2007 + Christiaan Hofman. All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Neither the name of Christiaan Hofman nor the names of any + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + #import "SKFDFParser.h" #import <Quartz/Quartz.h> #import "NSScanner_SKExtensions.h" Modified: trunk/Skim.xcodeproj/project.pbxproj =================================================================== --- trunk/Skim.xcodeproj/project.pbxproj 2007-09-08 12:36:53 UTC (rev 2846) +++ trunk/Skim.xcodeproj/project.pbxproj 2007-09-08 14:07:22 UTC (rev 2847) @@ -149,6 +149,7 @@ CE9A87930C0C9E9A004F1F97 /* ProgressSheet.nib in Resources */ = {isa = PBXBuildFile; fileRef = CE9A878D0C0C9E9A004F1F97 /* ProgressSheet.nib */; }; CE9C423C0B8B5633004AD8CF /* PreferenceWindow.nib in Resources */ = {isa = PBXBuildFile; fileRef = CE9C42360B8B5633004AD8CF /* PreferenceWindow.nib */; }; CE9DC2EA0B9F131900D64F28 /* ToolbarHighlightNote.tiff in Resources */ = {isa = PBXBuildFile; fileRef = CE9DC2E80B9F131800D64F28 /* ToolbarHighlightNote.tiff */; }; + CEA182280C92E3300061A6D4 /* NSData_SKExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = CEA182260C92E3300061A6D4 /* NSData_SKExtensions.m */; }; CEA575CE0B9206E60003D2E7 /* SKNoteOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = CEA575CD0B9206E60003D2E7 /* SKNoteOutlineView.m */; }; CEA575E50B9207B80003D2E7 /* SKThumbnailTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = CEA575E40B9207B80003D2E7 /* SKThumbnailTableView.m */; }; CEA575FD0B9208B60003D2E7 /* SKTocOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = CEA575FC0B9208B60003D2E7 /* SKTocOutlineView.m */; }; @@ -528,6 +529,8 @@ CE9A87970C0C9EA7004F1F97 /* Italian */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = Italian; path = Italian.lproj/ProgressSheet.nib; sourceTree = "<group>"; }; CE9C42370B8B5633004AD8CF /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/PreferenceWindow.nib; sourceTree = "<group>"; }; CE9DC2E80B9F131800D64F28 /* ToolbarHighlightNote.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = ToolbarHighlightNote.tiff; path = Images/ToolbarHighlightNote.tiff; sourceTree = "<group>"; }; + CEA182250C92E3300061A6D4 /* NSData_SKExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSData_SKExtensions.h; sourceTree = "<group>"; }; + CEA182260C92E3300061A6D4 /* NSData_SKExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSData_SKExtensions.m; sourceTree = "<group>"; }; CEA575CC0B9206E60003D2E7 /* SKNoteOutlineView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKNoteOutlineView.h; sourceTree = "<group>"; }; CEA575CD0B9206E60003D2E7 /* SKNoteOutlineView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SKNoteOutlineView.m; sourceTree = "<group>"; }; CEA575E30B9207B80003D2E7 /* SKThumbnailTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKThumbnailTableView.h; sourceTree = "<group>"; }; @@ -806,6 +809,8 @@ CE7C204E0C259A5D0059E08C /* NSColor_SKExtensions.m */, CE2DE4EC0B85DB6300D0DA12 /* NSCursor_SKExtensions.h */, CE2DE4ED0B85DB6300D0DA12 /* NSCursor_SKExtensions.m */, + CEA182250C92E3300061A6D4 /* NSData_SKExtensions.h */, + CEA182260C92E3300061A6D4 /* NSData_SKExtensions.m */, CE5487BA0B35A20A00F8AFB6 /* NSFileManager_ExtendedAttributes.h */, CE5487BB0B35A20A00F8AFB6 /* NSFileManager_ExtendedAttributes.m */, CEF839B00C77742A00A3AD51 /* Files_SKExtensions.h */, @@ -1506,6 +1511,7 @@ CE820A220C8A0E310020E6B0 /* NSTask_SKExtensions.m in Sources */, CE5F71560C8CDF9A008BE480 /* NSCell_SKExtensions.m in Sources */, CE5FA1680C909886008BE480 /* SKFDFParser.m in Sources */, + CEA182280C92E3300061A6D4 /* NSData_SKExtensions.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-08 12:36:57
|
Revision: 2846 http://skim-app.svn.sourceforge.net/skim-app/?rev=2846&view=rev Author: hofman Date: 2007-09-08 05:36:53 -0700 (Sat, 08 Sep 2007) Log Message: ----------- Support import/export of FDF files. Import is not yet tested, and also the output is not yet tested on compatibility with Acrobat. Modified Paths: -------------- trunk/Dutch.lproj/InfoPlist.strings trunk/English.lproj/InfoPlist.strings trunk/French.lproj/InfoPlist.strings trunk/Info.plist trunk/Italian.lproj/InfoPlist.strings trunk/NSScanner_SKExtensions.h trunk/NSScanner_SKExtensions.m trunk/NSString_SKExtensions.h trunk/NSString_SKExtensions.m trunk/SKDocument.h trunk/SKDocument.m trunk/SKDocumentController.h trunk/SKDocumentController.m trunk/SKPDFAnnotationNote.h trunk/SKPDFAnnotationNote.m trunk/Skim.xcodeproj/project.pbxproj Added Paths: ----------- trunk/SKFDFParser.h trunk/SKFDFParser.m Modified: trunk/Dutch.lproj/InfoPlist.strings =================================================================== (Binary files differ) Modified: trunk/English.lproj/InfoPlist.strings =================================================================== (Binary files differ) Modified: trunk/French.lproj/InfoPlist.strings =================================================================== (Binary files differ) Modified: trunk/Info.plist =================================================================== --- trunk/Info.plist 2007-09-08 00:26:07 UTC (rev 2845) +++ trunk/Info.plist 2007-09-08 12:36:53 UTC (rev 2846) @@ -43,6 +43,7 @@ <string>Skim Notes</string> <string>Notes as RTF</string> <string>Notes as Text</string> + <string>Notes as FDF</string> </array> </dict> <dict> @@ -79,6 +80,7 @@ <string>Skim Notes</string> <string>Notes as RTF</string> <string>Notes as Text</string> + <string>Notes as FDF</string> </array> <key>NSPersistentStoreTypeKey</key> <string>Binary</string> @@ -339,6 +341,30 @@ <key>NSPersistentStoreTypeKey</key> <string>Binary</string> </dict> + <dict> + <key>CFBundleTypeExtensions</key> + <array> + <string>fdf</string> + </array> + <key>CFBundleTypeMIMETypes</key> + <array> + <string>application/vnd.fdf</string> + </array> + <key>CFBundleTypeName</key> + <string>Notes as FDF</string> + <key>CFBundleTypeOSTypes</key> + <array> + <string>FDF </string> + </array> + <key>CFBundleTypeRole</key> + <string>None</string> + <key>LSTypeIsPackage</key> + <false/> + <key>NSDocumentClass</key> + <string>SKDocument</string> + <key>NSPersistentStoreTypeKey</key> + <string>Binary</string> + </dict> </array> <key>CFBundleExecutable</key> <string>${EXECUTABLE_NAME}</string> @@ -428,7 +454,7 @@ <key>UTTypeTagSpecification</key> <dict> <key>com.apple.ostype</key> - <string>PDFD</string> + <string>PDFD</string> <key>public.filename-extension</key> <array> <string>pdfd</string> @@ -449,7 +475,7 @@ <key>UTTypeTagSpecification</key> <dict> <key>com.apple.ostype</key> - <string>SKNT</string> + <string>SKNT</string> <key>public.filename-extension</key> <array> <string>skim</string> Modified: trunk/Italian.lproj/InfoPlist.strings =================================================================== (Binary files differ) Modified: trunk/NSScanner_SKExtensions.h =================================================================== --- trunk/NSScanner_SKExtensions.h 2007-09-08 00:26:07 UTC (rev 2845) +++ trunk/NSScanner_SKExtensions.h 2007-09-08 12:36:53 UTC (rev 2846) @@ -41,4 +41,5 @@ @interface NSScanner (SKExtensions) - (BOOL)scanCharacter:(unichar *)ch; +- (BOOL)peekCharacter:(unichar *)ch; @end Modified: trunk/NSScanner_SKExtensions.m =================================================================== --- trunk/NSScanner_SKExtensions.m 2007-09-08 00:26:07 UTC (rev 2845) +++ trunk/NSScanner_SKExtensions.m 2007-09-08 12:36:53 UTC (rev 2846) @@ -51,4 +51,12 @@ return YES; } +- (BOOL)peekCharacter:(unichar *)ch { + if ([self isAtEnd]) + return NO; + if (ch != NULL) + *ch = [[self string] characterAtIndex:[self scanLocation]]; + return YES; +} + @end Modified: trunk/NSString_SKExtensions.h =================================================================== --- trunk/NSString_SKExtensions.h 2007-09-08 00:26:07 UTC (rev 2845) +++ trunk/NSString_SKExtensions.h 2007-09-08 12:36:53 UTC (rev 2846) @@ -53,6 +53,8 @@ - (NSString *)lossyASCIIString; +- (NSString *)stringByEscapingParenthesis; + - (NSRange)rangeOfLeadingEmptyLine; - (NSRange)rangeOfLeadingEmptyLineInRange:(NSRange)range; - (NSRange)rangeOfTrailingEmptyLine; Modified: trunk/NSString_SKExtensions.m =================================================================== --- trunk/NSString_SKExtensions.m 2007-09-08 00:26:07 UTC (rev 2845) +++ trunk/NSString_SKExtensions.m 2007-09-08 12:36:53 UTC (rev 2846) @@ -203,6 +203,27 @@ return [[[NSString alloc] initWithData:[self dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES] encoding:NSASCIIStringEncoding] autorelease]; } +- (NSString *)stringByEscapingParenthesis { + static NSCharacterSet *parenAndBackslashCharSet = nil; + + if (parenAndBackslashCharSet == nil) + parenAndBackslashCharSet = [[NSCharacterSet characterSetWithCharactersInString:@"()\\"] retain]; + + unsigned location = [self rangeOfCharacterFromSet:parenAndBackslashCharSet].location; + if (location == NSNotFound) + return self; + + NSRange range; + NSMutableString *string = [self mutableCopy]; + + while (location != NSNotFound) { + [string insertString:@"\\" atIndex:location]; + range = NSMakeRange(location + 2, [string length] - location - 2); + location = [string rangeOfCharacterFromSet:parenAndBackslashCharSet options:0 range:range].location; + } + return [string autorelease]; +} + #pragma mark Empty lines // whitespace at the beginning of the string up to the end or until (and including) a newline Modified: trunk/SKDocument.h =================================================================== --- trunk/SKDocument.h 2007-09-08 00:26:07 UTC (rev 2845) +++ trunk/SKDocument.h 2007-09-08 12:36:53 UTC (rev 2846) @@ -102,6 +102,7 @@ - (NSString *)notesString; - (NSData *)notesRTFData; +- (NSString *)notesFDFString; - (NSDictionary *)currentDocumentSetup; Modified: trunk/SKDocument.m =================================================================== --- trunk/SKDocument.m 2007-09-08 00:26:07 UTC (rev 2845) +++ trunk/SKDocument.m 2007-09-08 12:36:53 UTC (rev 2846) @@ -61,6 +61,7 @@ #import "SKApplicationController.h" #import "Files_SKExtensions.h" #import "NSTask_SKExtensions.h" +#import "SKFDFParser.h" #define BUNDLE_DATA_FILENAME @"data" @@ -371,6 +372,12 @@ didWrite = [string writeToURL:absoluteURL atomically:YES encoding:NSUTF8StringEncoding error:outError]; else if (outError != NULL) *outError = [NSError errorWithDomain:SKDocumentErrorDomain code:1 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Unable to write notes as text", @"Error description"), NSLocalizedDescriptionKey, nil]]; + } else if ([typeName isEqualToString:SKNotesFDFDocumentType]) { + NSString *string = [self notesFDFString]; + if (string) + didWrite = [string writeToURL:absoluteURL atomically:YES encoding:NSISOLatin1StringEncoding error:outError]; + else if (outError != NULL) + *outError = [NSError errorWithDomain:SKDocumentErrorDomain code:1 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Unable to write notes as FDF", @"Error description"), NSLocalizedDescriptionKey, nil]]; } if (didWrite == NO && outError != NULL && *outError == nil) @@ -668,8 +675,17 @@ - (void)openPanelDidEnd:(NSOpenPanel *)oPanel returnCode:(int)returnCode contextInfo:(void *)contextInfo{ if (returnCode == NSOKButton) { NSURL *notesURL = [[oPanel URLs] objectAtIndex:0]; - NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:[notesURL path]]; + NSString *extension = [[notesURL path] pathExtension]; + NSArray *array = nil; + if ([extension caseInsensitiveCompare:@"skim"] == NSOrderedSame) { + array = [NSKeyedUnarchiver unarchiveObjectWithFile:[notesURL path]]; + } else { + NSString *fdfString = [NSString stringWithContentsOfURL:notesURL encoding:NSISOLatin1StringEncoding error:NULL]; + if (fdfString) + array = [SKFDFParser notesDictionariesFromFDFString:fdfString]; + } + if (array) { if ([[oPanel accessoryView] isEqual:readNotesAccessoryView] && [replaceNotesCheckButton state] == NSOnState) [[self mainWindowController] setAnnotationsFromDictionaries:array]; @@ -678,7 +694,8 @@ // previous undo actions are not reliable anymore [[self undoManager] removeAllActions]; [self updateChangeCount:NSChangeDone]; - } + } else + NSBeep(); } } @@ -699,7 +716,7 @@ [oPanel beginSheetForDirectory:[path stringByDeletingLastPathComponent] file:[[path lastPathComponent] stringByReplacingPathExtension:@"skim"] - types:[NSArray arrayWithObject:@"skim"] + types:[NSArray arrayWithObjects:@"skim", @"fdf", nil] modalForWindow:[self windowForSheet] modalDelegate:self didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) @@ -1305,6 +1322,26 @@ return data; } +- (NSString *)notesFDFString { + NSString *filename = [[[self fileURL] path] lastPathComponent]; + int i, count = [[self notes] count]; + NSMutableString *string = [NSMutableString stringWithFormat:@"%%FDF-1.2\n%%%C%C%C%C\n1 0 obj<</FDF<<", 0xe2, 0xe3, 0xcf, 0xd3]; + [string appendString:@"/Annots["]; + for (i = 0; i < count; i++) + [string appendFormat:@"%i 0 R ", i + 2]; + if (filename && [[self fileType] isEqualToString:SKPDFBundleDocumentType]) { + NSArray *files = [[NSFileManager defaultManager] subpathsAtPath:[[self fileURL] path]]; + unsigned index = [[files valueForKeyPath:@"pathExtension.lowercaseString"] indexOfObject:@"pdf"]; + if (index != NSNotFound) + filename = [filename stringByAppendingPathComponent:[files objectAtIndex:index]]; + } + [string appendFormat:@"]/F(%@)>>\nendobj\n", filename ? [filename stringByEscapingParenthesis] : @""]; + for (i = 0; i < count; i++) + [string appendFormat:@"obj %i 0<<%@>>\nendobj\n", i + 2, [[[self notes] objectAtIndex:i] fdfString]]; + [string appendString:@"trailer\n<</Root 1 0 R>>\n%%EOF\n"]; + return string; +} + - (void)setPrintInfo:(NSPrintInfo *)printInfo { [super setPrintInfo:printInfo]; if (autoRotateButton) Modified: trunk/SKDocumentController.h =================================================================== --- trunk/SKDocumentController.h 2007-09-08 00:26:07 UTC (rev 2845) +++ trunk/SKDocumentController.h 2007-09-08 12:36:53 UTC (rev 2846) @@ -45,6 +45,7 @@ extern NSString *SKNotesDocumentType; extern NSString *SKNotesRTFDocumentType; extern NSString *SKNotesTextDocumentType; +extern NSString *SKNotesFDFDocumentType; extern NSString *SKPostScriptDocumentType; extern NSString *SKDVIDocumentType; Modified: trunk/SKDocumentController.m =================================================================== --- trunk/SKDocumentController.m 2007-09-08 00:26:07 UTC (rev 2845) +++ trunk/SKDocumentController.m 2007-09-08 12:36:53 UTC (rev 2846) @@ -51,6 +51,7 @@ NSString *SKNotesDocumentType = @"Skim Notes"; NSString *SKNotesRTFDocumentType = @"Notes as RTF"; NSString *SKNotesTextDocumentType = @"Notes as Text"; +NSString *SKNotesFDFDocumentType = @"Notes as FDF"; NSString *SKPostScriptDocumentType = @"PostScript document"; NSString *SKDVIDocumentType = @"DVI document"; Added: trunk/SKFDFParser.h =================================================================== --- trunk/SKFDFParser.h (rev 0) +++ trunk/SKFDFParser.h 2007-09-08 12:36:53 UTC (rev 2846) @@ -0,0 +1,15 @@ +// +// SKFDFParser.h +// Skim +// +// Created by Christiaan Hofman on 6/9/07. +// Copyright 2007 Christiaan Hofman. All rights reserved. +// + +#import <Cocoa/Cocoa.h> + + +@interface SKFDFParser : NSObject ++ (NSArray *)notesDictionariesFromFDFString:(NSString *)string; ++ (NSDictionary *)fdfObjectsFromFDFString:(NSString *)string; +@end Added: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m (rev 0) +++ trunk/SKFDFParser.m 2007-09-08 12:36:53 UTC (rev 2846) @@ -0,0 +1,622 @@ +// +// SKFDFParser.m +// Skim +// +// Created by Christiaan Hofman on 6/9/07. +// Copyright 2007 Christiaan Hofman. All rights reserved. +// + +#import "SKFDFParser.h" +#import <Quartz/Quartz.h> +#import "NSScanner_SKExtensions.h" +#import "NSCharacterSet_SKExtensions.h" + +@interface NSScanner (SKFDFParserExtensions) +- (BOOL)scanFDFObject:(id *)object; +- (BOOL)scanFDFArray:(NSArray **)array; +- (BOOL)scanFDFDictionary:(NSDictionary **)dictionary; +- (BOOL)scanFDFString:(NSString **)string; +- (BOOL)scanFDFHexString:(NSString **)string; +- (BOOL)scanFDFName:(NSString **)string; +- (BOOL)scanFDFNumber:(NSNumber **)number; +- (BOOL)scanFDFIndirectObject:(id *)object; +@end + +#pragma mark - + +@interface SKIndirectObject : NSObject <NSCopying> { + int objectNumber; + int generationNumber; +} ++ (id)indirectObjectWithNumber:(int)objNumber generation:(int)genNumber; +- (id)initWithNumber:(int)objNumber generation:(int)genNumber; +- (int)objectNumber; +- (int)generationNumber; +@end + +#pragma mark - + +@implementation SKFDFParser + ++ (id)value:(id)value ofClass:(Class)aClass lookup:(NSDictionary *)lookup { + while ([value isKindOfClass:[SKIndirectObject class]]) + value = [lookup objectForKey:value]; + return ([value isKindOfClass:aClass]) ? value : nil; +} + ++ (NSDictionary *)noteDictionary:(NSDictionary *)dict lookup:(NSDictionary *)lookup { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + NSEnumerator *keyEnum = [dict keyEnumerator]; + NSString *key; + BOOL success = YES; + + while (success && (key = [keyEnum nextObject])) { + id value = [dict valueForKey:key]; + + if ([key isEqualToString:@"Type"]) { + if (value = [self value:value ofClass:[NSString class] lookup:lookup]) + [dictionary setObject:value forKey:@"type"]; + else + success = NO; + } else if ([key isEqualToString:@"Contents"]) { + if (value = [self value:value ofClass:[NSString class] lookup:lookup]) + [dictionary setObject:value forKey:@"contents"]; + else + success = NO; + } else if ([key isEqualToString:@"Rect"]) { + if ((value = [self value:value ofClass:[NSArray class] lookup:lookup]) && [value count] == 4) { + NSRect rect; + rect.origin.x = [[value objectAtIndex:0] floatValue]; + rect.origin.y = [[value objectAtIndex:1] floatValue]; + rect.size.width = [[value objectAtIndex:2] floatValue] - NSMinX(rect); + rect.size.height = [[value objectAtIndex:3] floatValue] - NSMinY(rect); + [dictionary setObject:NSStringFromRect(rect) forKey:@"bounds"]; + } else { + success = NO; + } + } else if ([key isEqualToString:@"Page"]) { + if (value = [self value:value ofClass:[NSNumber class] lookup:lookup]) + [dictionary setObject:value forKey:@"pageIndex"]; + else + success = NO; + } else if ([key isEqualToString:@"C"]) { + if ((value = [self value:value ofClass:[NSArray class] lookup:lookup]) && [value count] == 3) { + float r, g, b; + r = [[value objectAtIndex:0] floatValue]; + g = [[value objectAtIndex:1] floatValue]; + b = [[value objectAtIndex:2] floatValue]; + [dictionary setObject:[NSColor colorWithCalibratedRed:r green:g blue:b alpha:1.0] forKey:@"color"]; + } else { + success = NO; + } + } else if ([key isEqualToString:@"BS"]) { + if (value = [self value:value ofClass:[NSDictionary class] lookup:lookup]) { + NSNumber *width = [value objectForKey:@"W"]; + NSString *s = [value objectForKey:@"S"]; + NSArray *dashPattern = [value objectForKey:@"D"]; + int style = kPDFBorderStyleSolid; + if (s && [s isKindOfClass:[NSString class]]) { + success = NO; + break; + } + if (dashPattern && [dashPattern isKindOfClass:[NSArray class]] == NO) { + success = NO; + break; + } + if (width && [width isKindOfClass:[NSNumber class]] == NO) { + success = NO; + break; + } + if ([s isEqualToString:@"S"]) + style = kPDFBorderStyleSolid; + else if ([s isEqualToString:@"D"]) + style = kPDFBorderStyleDashed; + else if ([s isEqualToString:@"B"]) + style = kPDFBorderStyleBeveled; + else if ([s isEqualToString:@"I"]) + style = kPDFBorderStyleInset; + else if ([s isEqualToString:@"U"]) + style = kPDFBorderStyleUnderline; + if (width && [width floatValue] > 0.0) { + [dictionary setObject:width forKey:@"lineWidth"]; + [dictionary setObject:[NSNumber numberWithInt:style] forKey:@"borderStyle"]; + if (dashPattern) + [dictionary setObject:dashPattern forKey:@"dashPattern"]; + } + } else { + success = NO; + } + } else if ([key isEqualToString:@"Border"]) { + if ([value isKindOfClass:[NSArray class]] == NO) { + success = NO; + break; + } + NSNumber *width = [value count] > 2 ? [value objectAtIndex:2] : nil; + NSArray *dashPattern = [value count] > 3 ? [value objectAtIndex:3] : nil; + if (dashPattern && [dashPattern isKindOfClass:[NSArray class]] == NO) { + success = NO; + break; + } + if (width && [width isKindOfClass:[NSNumber class]] == NO) { + success = NO; + break; + } + if (width && [width floatValue] > 0.0) { + [dictionary setObject:width forKey:@"lineWidth"]; + [dictionary setObject:[NSNumber numberWithInt:dashPattern ? kPDFBorderStyleDashed : kPDFBorderStyleSolid] forKey:@"borderStyle"]; + if (dashPattern) + [dictionary setObject:dashPattern forKey:@"dashPattern"]; + } + } else if ([key isEqualToString:@"Name"]) { + if (value = [self value:value ofClass:[NSString class] lookup:lookup]) { + int icon = kPDFTextAnnotationIconNote; + if ([value isEqualToString:@"Comment"]) + icon = kPDFTextAnnotationIconComment; + else if ([value isEqualToString:@"Key"]) + icon = kPDFTextAnnotationIconKey; + else if ([value isEqualToString:@"Note"]) + icon = kPDFTextAnnotationIconNote; + else if ([value isEqualToString:@"NewParagraph"]) + icon = kPDFTextAnnotationIconNewParagraph; + else if ([value isEqualToString:@"Paragraph"]) + icon = kPDFTextAnnotationIconParagraph; + else if ([value isEqualToString:@"Insert"]) + icon = kPDFTextAnnotationIconInsert; + [dictionary setObject:[NSNumber numberWithInt:icon] forKey:@"iconType"]; + } else { + success = NO; + } + } else if ([key isEqualToString:@"IC"]) { + if ((value = [self value:value ofClass:[NSArray class] lookup:lookup]) && [value count] == 3) { + float r, g, b; + r = [[value objectAtIndex:0] floatValue]; + g = [[value objectAtIndex:1] floatValue]; + b = [[value objectAtIndex:2] floatValue]; + [dictionary setObject:[NSColor colorWithCalibratedRed:r green:g blue:b alpha:1.0] forKey:@"interiorColor"]; + } else { + success = NO; + } + } else if ([key isEqualToString:@"LE"]) { + if ((value = [self value:value ofClass:[NSArray class] lookup:lookup]) && [value count] == 2) { + NSString *start = [value objectAtIndex:0]; + NSString *end = [value objectAtIndex:1]; + int startStyle = kPDFLineStyleNone; + int endStyle = kPDFLineStyleNone; + if (start && [start isKindOfClass:[NSNumber class]] == NO) { + success = NO; + break; + } + if (end && [end isKindOfClass:[NSNumber class]] == NO) { + success = NO; + break; + } + if ([end isEqualToString:@"None"]) + startStyle = kPDFLineStyleNone; + else if ([end isEqualToString:@"Square"]) + startStyle = kPDFLineStyleSquare; + else if ([end isEqualToString:@"Circle"]) + startStyle = kPDFLineStyleCircle; + else if ([end isEqualToString:@"Diamond"]) + startStyle = kPDFLineStyleDiamond; + else if ([end isEqualToString:@"OpenArrow"]) + startStyle = kPDFLineStyleOpenArrow; + else if ([end isEqualToString:@"ClosedArrow"]) + startStyle = kPDFLineStyleClosedArrow; + [dictionary setObject:[NSNumber numberWithInt:startStyle] forKey:@"startLineStyle"]; + [dictionary setObject:[NSNumber numberWithInt:endStyle] forKey:@"endLineStyle"]; + } else { + success = NO; + } + } else if ([key isEqualToString:@"QuadPoints"]) { + if ((value = [self value:value ofClass:[NSArray class] lookup:lookup]) && [value count] % 8 == 0) { + NSMutableArray *quadPoints = [NSMutableArray array]; + int i, count = [value count]; + for (i = 0; i < count; i++) { + NSPoint point; + point.x = [[value objectAtIndex:i] floatValue]; + point.y = [[value objectAtIndex:++i] floatValue]; + [quadPoints addObject:NSStringFromPoint(point)]; + } + [dictionary setObject:quadPoints forKey:@"quadrilateralPoints"]; + } else { + success = NO; + } + } + } + return success ? dictionary : nil; +} + ++ (NSArray *)notesDictionariesFromFDFString:(NSString *)string { + NSMutableArray *array = nil; + NSDictionary *fdfDict; + NSDictionary *trailer; + SKIndirectObject *root; + NSDictionary *rootDict; + NSArray *annots; + + if ((fdfDict = [self fdfObjectsFromFDFString:string]) && + (trailer = [fdfDict objectForKey:@"trailer"]) && + ([trailer isKindOfClass:[NSDictionary class]]) && + (root = [trailer objectForKey:@"Root"]) && + ([rootDict isKindOfClass:[NSDictionary class]]) && + (annots = [trailer objectForKey:@"Annots"]) && + ([annots isKindOfClass:[NSArray class]])) { + + NSEnumerator *annotEnum = [annots objectEnumerator]; + NSDictionary *dict; + + array = [NSMutableArray array]; + while (dict = [annotEnum nextObject]) { + if ([dict isKindOfClass:[NSDictionary class]] == NO) + return nil; + if (dict = [self noteDictionary:dict lookup:fdfDict]) + [array addObject:dict]; + } + } + + return array; +} + ++ (NSDictionary *)fdfObjectsFromFDFString:(NSString *)string { + NSMutableDictionary *fdfDict = [NSMutableDictionary dictionary]; + + NSDictionary *dictionary; + int objNumber, genNumber; + id object; + BOOL success = YES; + + NSScanner *scanner = [NSScanner scannerWithString:string]; + + [scanner setCharactersToBeSkipped:nil]; + + // Scan the FDF header + [scanner scanString:@"%FDF-1.2" intoString:NULL]; + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + if ([scanner scanString:@"%" intoString:NULL]) + [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet] intoString:NULL]; + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + + // Scan the FDF body + while (success = success && [scanner scanInt:&objNumber] && + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL] && + [scanner scanInt:&genNumber] && + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:NULL] && + [scanner scanString:@"obj" intoString:NULL]) { + + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + if (success = [scanner scanFDFObject:&object]) { + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + + if ([object isKindOfClass:[NSDictionary class]] && [scanner scanString:@"stream" intoString:NULL]) { + object = @""; + [scanner scanString:@"\n" intoString:NULL] || [scanner scanString:@"\r\n" intoString:NULL]; + + if ([scanner scanUpToString:@"endstream" intoString:&object]) { + int end = [object length]; + unichar ch = end ? [object characterAtIndex:end - 1] : 0; + if ([[NSCharacterSet newlineCharacterSet] characterIsMember:ch]) { + end--; + if (end && ch == '\n' && [object characterAtIndex:end - 1] == '\r') + end--; + object = [object substringToIndex:end]; + } + } + [scanner scanString:@"endstream" intoString:NULL]; + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + } + [fdfDict setObject:object forKey:[SKIndirectObject indirectObjectWithNumber:objNumber generation:genNumber]]; + success = [scanner scanString:@"endobj" intoString:NULL]; + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + } + } + + // Scan the FDF cross reference table, if present + while (success && [scanner scanString:@"xref" intoString:NULL]) { + [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet] intoString:NULL]; + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + while ([scanner scanInt:NULL]) { + [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet] intoString:NULL]; + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + } + } + + // Scan the FDF trailer + if (success = success && [scanner scanString:@"trailer" intoString:NULL]) { + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + if (success = [scanner scanFDFDictionary:&dictionary] && + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL] && + [scanner scanString:@"%%EOF" intoString:NULL]) + [fdfDict setObject:dictionary forKey:@"trailer"]; + } + + return success ? fdfDict : nil; +} + +@end + +#pragma mark - + +@implementation NSScanner (SKFDFParserExtensions) + +- (BOOL)scanFDFObject:(id *)object { + id tmpObject = nil; + BOOL success = [self scanFDFName:&tmpObject] || + [self scanFDFString:&tmpObject] || + [self scanFDFHexString:&tmpObject] || + [self scanFDFNumber:&tmpObject] || + [self scanFDFArray:&tmpObject] || + [self scanFDFDictionary:&tmpObject] || + [self scanFDFIndirectObject:&tmpObject] || + [self scanString:@"null" intoString:NULL]; + + if (success && object) + *object = tmpObject; + + return success; +} + +- (BOOL)scanFDFArray:(NSArray **)array { + NSMutableArray *tmpArray = [NSMutableArray array]; + unichar ch; + id object; + BOOL success = [self scanString:@"[" intoString:NULL]; + + while (success) { + [self scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + + if ([self peekCharacter:&ch] == NO) { + success = NO; + break; + } + if (ch == ']') + break; + else if ((success = [self scanFDFObject:&object]) && object) + [tmpArray addObject:object]; + } + + if (success && array) + *array = tmpArray; + + return success; +} + +- (BOOL)scanFDFDictionary:(NSDictionary **)dictionary { + NSMutableDictionary *tmpDict = [NSMutableDictionary dictionary]; + unichar ch; + NSString *key; + id object; + BOOL success = [self scanString:@"<<" intoString:NULL]; + + while (success) { + [self scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + + if ([self peekCharacter:&ch] == NO) { + success = NO; + break; + } + if ([self scanFDFName:&key]) { + [self scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + if ((success = [self scanFDFObject:&object]) && object) + [tmpDict setObject:object forKey:key]; + } else if ([self scanString:@">>" intoString:NULL]) { + break; + } else { + success = NO; + } + } + + if (success && dictionary) + *dictionary = tmpDict; + + return success; +} + +- (BOOL)scanFDFString:(NSString **)string { + static NSCharacterSet *specialCharSet = nil; + if (specialCharSet == nil) + specialCharSet = [[NSCharacterSet characterSetWithCharactersInString:@"\\)"] retain]; + + static NSCharacterSet *octalCharSet = nil; + if (octalCharSet == nil) + octalCharSet = [[NSCharacterSet characterSetWithCharactersInString:@"01234567"] retain]; + + NSMutableString *tmpString = [NSMutableString string]; + NSString *s; + unichar ch; + BOOL success = [self scanString:@"(" intoString:NULL]; + + while (success) { + if ([self scanUpToCharactersFromSet:specialCharSet intoString:&s]) + [tmpString appendString:s]; + if ([self scanCharacter:&ch]) { + if (ch == ')') { + break; + } else if (ch == '\\') { + if ([self scanCharacter:&ch]) { + if (ch == 'n') { + [tmpString appendString:@"\n"]; + } else if (ch == 'r') { + [tmpString appendString:@"\r"]; + } else if (ch == 't') { + [tmpString appendString:@"\r"]; + } else if (ch == 'b') { + [tmpString appendString:@"\b"]; + } else if (ch == 'f') { + [tmpString appendString:@"\f"]; + } else if (ch == '(') { + [tmpString appendString:@"("]; + } else if (ch == ')') { + [tmpString appendString:@")"]; + } else if (ch == '\\') { + [tmpString appendString:@"\\"]; + } else if ([octalCharSet characterIsMember:ch]) { + char octal = ch; + if ([self peekCharacter:&ch] && [octalCharSet characterIsMember:ch]) { + [self scanCharacter:NULL]; + octal = 8 * octal + ch; + if ([self peekCharacter:&ch] && [octalCharSet characterIsMember:ch]) { + [self scanCharacter:NULL]; + octal = 8 * octal + ch; + } + } + NSString *s = [[NSString alloc] initWithBytes:&octal length:1 encoding:NSISOLatin1StringEncoding]; + if (success = s != nil) + [tmpString appendString:s]; + [s release]; + } else + success = NO; + } else { + success = NO; + } + } + } else { + success = NO; + } + } + + if (success && string) + *string = tmpString; + + return success; +} + +static inline int hexCharacterNumber(unichar ch) { + if (ch >= '0' && ch <= '9') + return ch - '0'; + if (ch >= 'A' && ch <= 'F') + return ch - 'A' + 10; + if (ch >= 'a' && ch <= 'f') + return ch - 'a' + 10; + return 0; +} + +- (BOOL)scanFDFHexString:(NSString **)string { + static NSCharacterSet *hexCharSet = nil; + if (hexCharSet == nil) + hexCharSet = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789abcdefABCDEF"] retain]; + + int rewindLoc = [self scanLocation]; + NSString *hexString = nil; + unichar ch; + char hexChar; + char *bytes = NULL; + int length = 0; + BOOL isFirst = YES; + BOOL done = NO; + BOOL success = [self scanString:@"<" intoString:NULL]; + + while (done == NO && success && (success = [self scanCharacter:&ch])) { + hexChar = 0; + if ([hexCharSet characterIsMember:ch]) { + hexChar += hexCharacterNumber(ch); + } else if ([[NSCharacterSet whitespaceAndNewlineCharacterSet] characterIsMember:ch]) { + // ignore + } else if (ch == '>') { + done = YES; + } else { + success = NO; + } + if (isFirst) { + hexChar *= 16; + } else { + length++; + bytes = NSZoneRealloc([self zone], bytes, length * sizeof(char)); + bytes[length - 1] = hexChar; + hexChar = 0; + } + isFirst = !isFirst; + } + + if (success) { + hexString = length == 0 ? @"" : [[[NSString alloc] initWithBytes:bytes length:length encoding:NSISOLatin1StringEncoding] autorelease]; + success = hexString != nil; + } + + if (bytes) + NSZoneFree([self zone], bytes); + + if (success == NO) + [self setScanLocation:rewindLoc]; + + if (success && string) + *string = hexString; + + return success; +} + +- (BOOL)scanFDFName:(NSString **)string { + static NSCharacterSet *whitespaceOrDelimiterCharSet = nil; + if (whitespaceOrDelimiterCharSet == nil) { + NSMutableCharacterSet *tmpSet = [[NSCharacterSet whitespaceAndNewlineCharacterSet] mutableCopy]; + [tmpSet addCharactersInString:@"()<>[]{}/%"]; + whitespaceOrDelimiterCharSet = [[tmpSet invertedSet] copy]; + [tmpSet release]; + } + return [self scanString:@"/" intoString:NULL] && [self scanUpToCharactersFromSet:whitespaceOrDelimiterCharSet intoString:string]; +} + +- (BOOL)scanFDFNumber:(NSNumber **)number { + float f; + BOOL success = [self scanFloat:&f]; + + if (success && number) + *number = [NSNumber numberWithFloat:f]; + + return success; +} + +- (BOOL)scanFDFIndirectObject:(id *)object { + int rewindLoc = [self scanLocation]; + id tmpObject; + int objNumber, genNumber; + BOOL success; + + if (success = [self scanInt:&objNumber] && [self scanCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:NULL] && + [self scanInt:&genNumber] && [self scanCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:NULL] && + [self scanString:@"R" intoString:NULL]) + tmpObject = [SKIndirectObject indirectObjectWithNumber:objNumber generation:genNumber]; + + if (success == NO) + [self setScanLocation:rewindLoc]; + + if (success && object) + *object = tmpObject; + + return success; +} + +@end + +#pragma mark - + +@implementation SKIndirectObject : NSObject + ++ (id)indirectObjectWithNumber:(int)objNumber generation:(int)genNumber { + return [[[self alloc] initWithNumber:objNumber generation:genNumber] autorelease]; +} + +- (id)initWithNumber:(int)objNumber generation:(int)genNumber { + if (self = [super init]) { + objectNumber = objNumber; + generationNumber = genNumber; + } + return self; +} + +- (id)copyWithZone:(NSZone *)aZone { + return [self retain]; +} + +- (BOOL)isEqual:(id)other { + return [self isMemberOfClass:[other class]] && [self objectNumber] == [other objectNumber] && [self generationNumber] == [other generationNumber]; +} + +- (int)objectNumber { + return objectNumber; +} + +- (int)generationNumber { + return generationNumber; +} + +@end Modified: trunk/SKPDFAnnotationNote.h =================================================================== --- trunk/SKPDFAnnotationNote.h 2007-09-08 00:26:07 UTC (rev 2845) +++ trunk/SKPDFAnnotationNote.h 2007-09-08 12:36:53 UTC (rev 2846) @@ -50,6 +50,8 @@ - (NSDictionary *)dictionaryValue; +- (NSString *)fdfString; + - (PDFDestination *)destination; - (unsigned int)pageIndex; - (int)noteType; Modified: trunk/SKPDFAnnotationNote.m =================================================================== --- trunk/SKPDFAnnotationNote.m 2007-09-08 00:26:07 UTC (rev 2845) +++ trunk/SKPDFAnnotationNote.m 2007-09-08 12:36:53 UTC (rev 2846) @@ -44,6 +44,7 @@ #import "OBUtilities.h" #import "NSUserDefaultsController_SKExtensions.h" #import "NSGeometry_SKExtensions.h" +#import "NSString_SKExtensions.h" enum { SKASTextNote = 'NTxt', @@ -222,6 +223,50 @@ return dict; } +- (NSString *)fdfString { + NSMutableString *string = [NSMutableString string]; + NSRect bounds = [self bounds]; + float r, g, b, a = 0.0; + PDFBorder *border = [self border]; + [[self color] getRed:&r green:&g blue:&b alpha:&a]; + [string appendString:@"/Type/Annot/Subtype/"]; + [string appendString:[[self type] isEqualToString:@"Note"] ? @"Text" : [self type]]; + [string appendString:@"/Contents("]; + [string appendString:[[self contents] stringByEscapingParenthesis]]; + if ([self text]) { + [string appendString:@"\n"]; + [string appendString:[[[self text] string] stringByEscapingParenthesis]]; + } + [string appendString:@")"]; + [string appendFormat:@"/Rect[%f %f %f %f]", NSMinX(bounds), NSMinY(bounds), NSMaxX(bounds), NSMaxY(bounds)]; + if (a > 0.0) + [string appendFormat:@"/C[%f %f %f]", r, g, b]; + [string appendFormat:@"/Page %i", [self pageIndex]]; + if (border) { + [string appendFormat:@"/BS<</W%f/S", [border lineWidth]]; + switch ([border style]) { + case kPDFBorderStyleSolid: + [string appendString:@"/S"]; + break; + case kPDFBorderStyleDashed: + [string appendString:@"/D"]; + break; + case kPDFBorderStyleBeveled: + [string appendString:@"/B"]; + break; + case kPDFBorderStyleInset: + [string appendString:@"/I"]; + break; + case kPDFBorderStyleUnderline: + [string appendString:@"/U"]; + break; + } + [string appendFormat:@"/D[%@]", [[[border dashPattern] valueForKey:@"stringValue"] componentsJoinedByString:@" "]]; + [string appendString:@">>"]; + } + return string; +} + - (PDFDestination *)destination{ NSRect bounds = [self bounds]; NSPoint point = SKTopLeftPoint(bounds); @@ -599,6 +644,15 @@ return dict; } +- (NSString *)fdfString { + NSMutableString *string = [[[super fdfString] mutableCopy] autorelease]; + float r, g, b, a = 0.0; + [[self interiorColor] getRed:&r green:&g blue:&b alpha:&a]; + if (a > 0.0) + [string appendFormat:@"/IC[%f %f %f]", r, g, b]; + return string; +} + - (BOOL)isNoteAnnotation { return YES; } - (BOOL)isResizable { return YES; } @@ -673,6 +727,15 @@ return dict; } +- (NSString *)fdfString { + NSMutableString *string = [[[super fdfString] mutableCopy] autorelease]; + float r, g, b, a = 0.0; + [[self interiorColor] getRed:&r green:&g blue:&b alpha:&a]; + if (a > 0.0) + [string appendFormat:@"/IC[%f %f %f]", r, g, b]; + return string; +} + - (BOOL)isNoteAnnotation { return YES; } - (BOOL)isResizable { return YES; } @@ -910,6 +973,20 @@ return dict; } +- (NSString *)fdfString { + NSMutableString *string = [[[super fdfString] mutableCopy] autorelease]; + NSEnumerator *pointEnum = [[self quadrilateralPoints] objectEnumerator]; + NSValue *value; + NSPoint point; + [string appendString:@"/QuadPoints["]; + while (value = [pointEnum nextObject]) { + point = [value pointValue]; + [string appendFormat:@"%f %f ", point.x, point.y]; + } + [string appendString:@"]"]; + return string; +} + - (void)regenerateLineRects { NSArray *quadPoints = [self quadrilateralPoints]; @@ -1063,6 +1140,12 @@ return dict; } +- (NSString *)fdfString { + NSMutableString *string = [[[super fdfString] mutableCopy] autorelease]; + [string appendFormat:@"/DA(/%@ %f Tf)", [[self font] fontName], [[self font] pointSize]]; + return string; +} + - (BOOL)isNoteAnnotation { return YES; } - (BOOL)isResizable { return YES; } @@ -1179,6 +1262,32 @@ return dict; } +- (NSString *)fdfString { + NSMutableString *string = [[[super fdfString] mutableCopy] autorelease]; + [string appendString:@"/Name"]; + switch ([self iconType]) { + case kPDFTextAnnotationIconComment: + [string appendString:@"/Comment"]; + break; + case kPDFTextAnnotationIconKey: + [string appendString:@"/Key"]; + break; + case kPDFTextAnnotationIconNote: + [string appendString:@"/Note"]; + break; + case kPDFTextAnnotationIconNewParagraph: + [string appendString:@"/NewParagraph"]; + break; + case kPDFTextAnnotationIconParagraph: + [string appendString:@"/Paragraph"]; + break; + case kPDFTextAnnotationIconInsert: + [string appendString:@"/Insert"]; + break; + } + return string; +} + - (BOOL)isNoteAnnotation { return YES; } - (BOOL)isMovable { return YES; } @@ -1374,6 +1483,59 @@ return dict; } +- (NSString *)fdfString { + NSMutableString *string = [[[super fdfString] mutableCopy] autorelease]; + [string appendString:@"/LE["]; + switch ([self startLineStyle]) { + case kPDFLineStyleNone: + [string appendString:@"/None"]; + break; + case kPDFLineStyleSquare: + [string appendString:@"/Square"]; + break; + case kPDFLineStyleCircle: + [string appendString:@"/Circle"]; + break; + case kPDFLineStyleDiamond: + [string appendString:@"/Diamond"]; + break; + case kPDFLineStyleOpenArrow: + [string appendString:@"/OpenArrow"]; + break; + case kPDFLineStyleClosedArrow: + [string appendString:@"/ClosedArrow"]; + break; + default: + [string appendString:@"/None"]; + break; + } + switch ([self endLineStyle]) { + case kPDFLineStyleNone: + [string appendString:@"/None"]; + break; + case kPDFLineStyleSquare: + [string appendString:@"/Square"]; + break; + case kPDFLineStyleCircle: + [string appendString:@"/Circle"]; + break; + case kPDFLineStyleDiamond: + [string appendString:@"/Diamond"]; + break; + case kPDFLineStyleOpenArrow: + [string appendString:@"/OpenArrow"]; + break; + case kPDFLineStyleClosedArrow: + [string appendString:@"/ClosedArrow"]; + break; + default: + [string appendString:@"/None"]; + break; + } + [string appendString:@"]"]; + return string; +} + - (BOOL)isNoteAnnotation { return YES; } - (BOOL)isResizable { return YES; } Modified: trunk/Skim.xcodeproj/project.pbxproj =================================================================== --- trunk/Skim.xcodeproj/project.pbxproj 2007-09-08 00:26:07 UTC (rev 2845) +++ trunk/Skim.xcodeproj/project.pbxproj 2007-09-08 12:36:53 UTC (rev 2846) @@ -133,6 +133,7 @@ CE5F42AF0BF89FE00069D89C /* AppleRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = CE5F42AD0BF89FE00069D89C /* AppleRemote.m */; }; CE5F43730BF8A3410069D89C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE5F42D30BF8A3400069D89C /* IOKit.framework */; }; CE5F71560C8CDF9A008BE480 /* NSCell_SKExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE5F71540C8CDF9A008BE480 /* NSCell_SKExtensions.m */; }; + CE5FA1680C909886008BE480 /* SKFDFParser.m in Sources */ = {isa = PBXBuildFile; fileRef = CE5FA1660C909886008BE480 /* SKFDFParser.m */; }; CE67BB260BC44AC9007B6929 /* ZoomValues.strings in Resources */ = {isa = PBXBuildFile; fileRef = CE67BB240BC44AC9007B6929 /* ZoomValues.strings */; }; CE6C03F10BEDF759007BF0B5 /* NSParagraphStyle_SKExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE6C03EF0BEDF759007BF0B5 /* NSParagraphStyle_SKExtensions.m */; }; CE74686F0B7F3B1C00CBF969 /* ToolbarInfo.tiff in Resources */ = {isa = PBXBuildFile; fileRef = CE7467330B7F2ED700CBF969 /* ToolbarInfo.tiff */; }; @@ -500,6 +501,8 @@ CE5F42D30BF8A3400069D89C /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; }; CE5F71530C8CDF9A008BE480 /* NSCell_SKExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSCell_SKExtensions.h; sourceTree = "<group>"; }; CE5F71540C8CDF9A008BE480 /* NSCell_SKExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSCell_SKExtensions.m; sourceTree = "<group>"; }; + CE5FA1650C909886008BE480 /* SKFDFParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKFDFParser.h; sourceTree = "<group>"; }; + CE5FA1660C909886008BE480 /* SKFDFParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SKFDFParser.m; sourceTree = "<group>"; }; CE67BB250BC44AC9007B6929 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/ZoomValues.strings; sourceTree = "<group>"; }; CE67BB290BC44AD5007B6929 /* Dutch */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = Dutch; path = Dutch.lproj/ZoomValues.strings; sourceTree = "<group>"; }; CE6C03EE0BEDF759007BF0B5 /* NSParagraphStyle_SKExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSParagraphStyle_SKExtensions.h; sourceTree = "<group>"; }; @@ -1004,6 +1007,8 @@ CE48BAD60C089EA300A166C6 /* SKTemplateParser.m */, CE5BD6710C7ADF1500EBDCF7 /* SKTypeSelectHelper.h */, CE5BD6720C7ADF1500EBDCF7 /* SKTypeSelectHelper.m */, + CE5FA1650C909886008BE480 /* SKFDFParser.h */, + CE5FA1660C909886008BE480 /* SKFDFParser.m */, ); name = Miscellaneous; sourceTree = "<group>"; @@ -1500,6 +1505,7 @@ CE5BF8430C7CC24A00EBDCF7 /* SKOutlineView.m in Sources */, CE820A220C8A0E310020E6B0 /* NSTask_SKExtensions.m in Sources */, CE5F71560C8CDF9A008BE480 /* NSCell_SKExtensions.m in Sources */, + CE5FA1680C909886008BE480 /* SKFDFParser.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-08 00:26:23
|
Revision: 2845 http://skim-app.svn.sourceforge.net/skim-app/?rev=2845&view=rev Author: hofman Date: 2007-09-07 17:26:07 -0700 (Fri, 07 Sep 2007) Log Message: ----------- Subtract outline triangle width from column width for auto-resizing note rows. Modified Paths: -------------- trunk/SKMainWindowController.m Modified: trunk/SKMainWindowController.m =================================================================== --- trunk/SKMainWindowController.m 2007-09-07 19:57:23 UTC (rev 2844) +++ trunk/SKMainWindowController.m 2007-09-08 00:26:07 UTC (rev 2845) @@ -3416,7 +3416,7 @@ - (void)autoSizeNoteRows:(id)sender { NSTableColumn *tableColumn = [noteOutlineView tableColumnWithIdentifier:@"note"]; id cell = [tableColumn dataCell]; - float width = NSWidth([cell drawingRectForBounds:NSMakeRect(0.0, 0.0, [tableColumn width], 17.0)]); + float width = NSWidth([cell drawingRectForBounds:NSMakeRect(0.0, 0.0, [tableColumn width] - 17.0, 17.0)]); NSSize size = NSMakeSize(width, FLT_MAX); NSMutableArray *items = [NSMutableArray array]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-07 19:57:25
|
Revision: 2844 http://skim-app.svn.sourceforge.net/skim-app/?rev=2844&view=rev Author: hofman Date: 2007-09-07 12:57:23 -0700 (Fri, 07 Sep 2007) Log Message: ----------- Download external URLs to default download location. Don't remove file after finishing. Add a contextual menu to the download window. Don't remove finished downloads by default. Modified Paths: -------------- trunk/Files_SKExtensions.h trunk/Files_SKExtensions.m trunk/InitialUserDefaults.plist trunk/SKDownload.m trunk/SKDownloadController.m Modified: trunk/Files_SKExtensions.h =================================================================== --- trunk/Files_SKExtensions.h 2007-09-07 18:18:54 UTC (rev 2843) +++ trunk/Files_SKExtensions.h 2007-09-07 19:57:23 UTC (rev 2844) @@ -38,6 +38,10 @@ #import <Cocoa/Cocoa.h> +// This function is not thread safe + +extern NSURL *SKDownloadFolderURL(); + // These functions are thread safe extern BOOL SKFileIsInTrash(NSURL *fileURL); Modified: trunk/Files_SKExtensions.m =================================================================== --- trunk/Files_SKExtensions.m 2007-09-07 18:18:54 UTC (rev 2843) +++ trunk/Files_SKExtensions.m 2007-09-07 19:57:23 UTC (rev 2844) @@ -39,6 +39,36 @@ #import "Files_SKExtensions.h" #import <Carbon/Carbon.h> +NSURL *SKDownloadFolderURL() { + OSStatus err; + ICInstance inst; + ICAttr junk = 0; + ICFileSpec spec; + + static CFURLRef pathURL = NULL; + + if (NULL == pathURL) { + long size = sizeof(ICFileSpec); + FSRef pathRef; + + err = ICStart(&inst, 'SKim'); + if (noErr == err) + err = ICBegin(inst, icReadOnlyPerm); + + if (err == noErr) { + err = ICGetPref(inst, kICDownloadFolder, &junk, &spec, &size); + if (noErr == err) { + ICEnd(inst); + ICStop(inst); + } + + err = FSpMakeFSRef(&(spec.fss), &pathRef); + if(err == noErr) + pathURL = CFURLCreateFromFSRef(CFAllocatorGetDefault(), &pathRef); + } + } + return (NSURL *)pathURL; +} BOOL SKFileIsInTrash(NSURL *fileURL) { NSCParameterAssert([fileURL isFileURL]); Modified: trunk/InitialUserDefaults.plist =================================================================== --- trunk/InitialUserDefaults.plist 2007-09-07 18:18:54 UTC (rev 2843) +++ trunk/InitialUserDefaults.plist 2007-09-07 19:57:23 UTC (rev 2844) @@ -235,7 +235,7 @@ <key>SKAutoOpenDownloadsWindow</key> <true/> <key>SKAutoRemoveFinishedDownloads</key> - <true/> + <false/> <key>SKAutoCloseDownloadsWindow</key> <false/> <key>SUScheduledCheckInterval</key> Modified: trunk/SKDownload.m =================================================================== --- trunk/SKDownload.m 2007-09-07 18:18:54 UTC (rev 2843) +++ trunk/SKDownload.m 2007-09-07 19:57:23 UTC (rev 2844) @@ -38,8 +38,8 @@ #import "SKDownload.h" #import <ApplicationServices/ApplicationServices.h> +#import "Files_SKExtensions.h" - @interface SKDownload (Private) - (void)setStatus:(int)newStatus; - (void)setFilePath:(NSString *)newFilePath; @@ -78,7 +78,7 @@ - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [self cleanupDownload]; + [self cancelDownload]; [URL release]; [URLDownload release]; [filePath release]; @@ -88,7 +88,7 @@ } - (void)handleApplicationWillTerminateNotification:(NSNotification *)notification { - [self cleanupDownload]; + [self cancelDownload]; } #pragma mark Accessors @@ -306,9 +306,7 @@ } - (void)download:(NSURLDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename { - NSString *tmpDir = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]; - [[NSFileManager defaultManager] createDirectoryAtPath:tmpDir attributes:nil]; - [URLDownload setDestination:[tmpDir stringByAppendingPathComponent:filename] allowOverwrite:YES]; + [URLDownload setDestination:[[SKDownloadFolderURL() path] stringByAppendingPathComponent:filename] allowOverwrite:NO]; } - (void)download:(NSURLDownload *)download didCreateDestination:(NSString *)path { Modified: trunk/SKDownloadController.m =================================================================== --- trunk/SKDownloadController.m 2007-09-07 18:18:54 UTC (rev 2843) +++ trunk/SKDownloadController.m 2007-09-07 19:57:23 UTC (rev 2844) @@ -43,6 +43,7 @@ #import "SKStringConstants.h" #import "SKTableView.h" #import "SKTypeSelectHelper.h" +#import "NSString_SKExtensions.h" @implementation SKDownloadController @@ -127,36 +128,45 @@ } - (IBAction)cancelDownload:(id)sender { - int row = [tableView clickedRow]; + SKDownload *download = [sender respondsToSelector:@selector(representedObject)] ? [sender representedObject] : nil; - if (row != -1) { - SKDownload *download = [downloads objectAtIndex:row]; - if ([download status] == SKDownloadStatusDownloading) { - [download cancelDownload]; - } + if (download == nil) { + int row = [tableView clickedRow]; + if (row != -1) + download = [downloads objectAtIndex:row]; } + if (download && [download status] == SKDownloadStatusDownloading) { + [download cancelDownload]; + } } - (IBAction)resumeDownload:(id)sender { - int row = [tableView clickedRow]; + SKDownload *download = [sender respondsToSelector:@selector(representedObject)] ? [sender representedObject] : nil; - if (row != -1) { - SKDownload *download = [downloads objectAtIndex:row]; - if ([download status] == SKDownloadStatusCanceled) { - [download resumeDownload]; - [self reloadTableView]; - [self updateButtons]; - } + if (download == nil) { + int row = [tableView clickedRow]; + if (row != -1) + download = [downloads objectAtIndex:row]; } + if (download && [download status] == SKDownloadStatusCanceled) { + [download resumeDownload]; + [self reloadTableView]; + [self updateButtons]; + } } - (IBAction)removeDownload:(id)sender { - int row = [tableView clickedRow]; + SKDownload *download = [sender respondsToSelector:@selector(representedObject)] ? [sender representedObject] : nil; - if (row != -1) { - SKDownload *download = [downloads objectAtIndex:row]; - [download cleanupDownload]; - [downloads removeObjectAtIndex:row]; + if (download == nil) { + int row = [tableView clickedRow]; + if (row != -1) + download = [downloads objectAtIndex:row]; + } + + if (download) { + [download cancelDownload]; + [downloads removeObject:download]; [self reloadTableView]; [self updateButtons]; } @@ -181,6 +191,47 @@ [preferencesSheet orderOut:self]; } +- (void)openDownloadedFile:(id)sender { + SKDownload *download = [sender representedObject]; + + if (download && [download status] != SKDownloadStatusFinished) { + NSBeep(); + return; + } + + NSURL *fileURL = [NSURL fileURLWithPath:[download filePath]]; + NSError *error; + if (nil == [[NSDocumentController sharedDocumentController] openDocumentWithContentsOfURL:fileURL display:YES error:&error]) + [NSApp presentError:error]; +} + +- (void)revealDownloadedFile:(id)sender { + SKDownload *download = [sender representedObject]; + + if (download && [download status] != SKDownloadStatusFinished) { + NSBeep(); + return; + } + + [[NSWorkspace sharedWorkspace] selectFile:[download filePath] inFileViewerRootedAtPath:nil]; +} + +- (void)trashDownloadedFile:(id)sender { + SKDownload *download = [sender representedObject]; + + if (download && [download status] != SKDownloadStatusFinished) { + NSBeep(); + return; + } + + NSString *filePath = [download filePath]; + NSString *folderPath = [filePath stringByDeletingLastPathComponent]; + NSString *fileName = [filePath lastPathComponent]; + int tag = 0; + + [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:folderPath destination:nil files:[NSArray arrayWithObjects:fileName, nil] tag:&tag]; +} + #pragma mark SKDownloadDelegate - (void)downloadDidStart:(SKDownload *)download { @@ -202,7 +253,7 @@ [NSApp presentError:error]; if ([[NSUserDefaults standardUserDefaults] boolForKey:SKAutoRemoveFinishedDownloadsKey]) { - [download cleanupDownload]; + [download cancelDownload]; [downloads removeObject:download]; // for the document to note that the file has been deleted [document setFileURL:[NSURL fileURLWithPath:[download filePath]]]; @@ -313,7 +364,7 @@ if ([download canCancel]) { [download cancelDownload]; } else { - [download cleanupDownload]; + [download cancelDownload]; [downloads removeObjectAtIndex:row]; [self reloadTableView]; [self updateButtons]; @@ -324,6 +375,44 @@ return YES; } +- (NSMenu *)tableView:(NSTableView *)aTableView menuForTableColumn:(NSTableColumn *)tableColumn row:(int)row { + NSMenu *menu = [[[NSMenu allocWithZone:[NSMenu menuZone]] init] autorelease]; + NSMenuItem *menuItem; + SKDownload *download = [downloads objectAtIndex:row]; + + [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO]; + + if ([download canCancel]) { + menuItem = [menu addItemWithTitle:NSLocalizedString(@"Cancel", @"Menu item title") action:@selector(cancelDownload:) keyEquivalent:@""]; + [menuItem setTarget:self]; + [menuItem setRepresentedObject:download]; + } else { + menuItem = [menu addItemWithTitle:NSLocalizedString(@"Remove", @"Menu item title") action:@selector(removeDownload:) keyEquivalent:@""]; + [menuItem setTarget:self]; + [menuItem setRepresentedObject:download]; + } + if ([download canResume]) { + menuItem = [menu addItemWithTitle:NSLocalizedString(@"Resume", @"Menu item title") action:@selector(resumeDownload:) keyEquivalent:@""]; + [menuItem setTarget:self]; + [menuItem setRepresentedObject:download]; + } + if ([download status] == SKDownloadStatusFinished) { + menuItem = [menu addItemWithTitle:[NSLocalizedString(@"Open", @"Menu item title") stringByAppendingEllipsis] action:@selector(openDownloadedFile:) keyEquivalent:@""]; + [menuItem setTarget:self]; + [menuItem setRepresentedObject:download]; + + menuItem = [menu addItemWithTitle:[NSLocalizedString(@"Reveal", @"Menu item title") stringByAppendingEllipsis] action:@selector(revealDownloadedFile:) keyEquivalent:@""]; + [menuItem setTarget:self]; + [menuItem setRepresentedObject:download]; + + menuItem = [menu addItemWithTitle:NSLocalizedString(@"Move to Trash", @"Menu item title") action:@selector(trashDownloadedFile:) keyEquivalent:@""]; + [menuItem setTarget:self]; + [menuItem setRepresentedObject:download]; + } + + return menu; +} + #pragma mark SKTypeSelectHelper datasource protocol - (NSArray *)typeSelectHelperSelectionItems:(SKTypeSelectHelper *)typeSelectHelper { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-07 18:20:13
|
Revision: 2843 http://skim-app.svn.sourceforge.net/skim-app/?rev=2843&view=rev Author: hofman Date: 2007-09-07 11:18:54 -0700 (Fri, 07 Sep 2007) Log Message: ----------- Add contextual menu items to auto-size rows in the note table. Modified Paths: -------------- trunk/SKMainWindowController.m Modified: trunk/SKMainWindowController.m =================================================================== --- trunk/SKMainWindowController.m 2007-09-06 14:05:11 UTC (rev 2842) +++ trunk/SKMainWindowController.m 2007-09-07 18:18:54 UTC (rev 2843) @@ -3413,6 +3413,39 @@ [pdfView setActiveAnnotation:nil]; } +- (void)autoSizeNoteRows:(id)sender { + NSTableColumn *tableColumn = [noteOutlineView tableColumnWithIdentifier:@"note"]; + id cell = [tableColumn dataCell]; + float width = NSWidth([cell drawingRectForBounds:NSMakeRect(0.0, 0.0, [tableColumn width], 17.0)]); + NSSize size = NSMakeSize(width, FLT_MAX); + + NSMutableArray *items = [NSMutableArray array]; + id item = [sender representedObject]; + + if (item) { + [items addObject:item]; + } else { + [items addObjectsFromArray:[self notes]]; + [items addObjectsFromArray:[[self notes] valueForKeyPath:@"@unionOfArrays.texts"]]; + } + + int i, count = [items count]; + NSMutableIndexSet *rowIndexes = [NSMutableIndexSet indexSet]; + int row; + + for (i = 0; i < count; i++) { + item = [items objectAtIndex:i]; + [cell setObjectValue:[item contents]]; + NSAttributedString *attrString = [cell attributedStringValue]; + NSRect rect = [attrString boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin]; + [item setRowHeight:fmaxf(NSHeight(rect) + 3.0, 19.0)]; + row = [noteOutlineView rowForItem:item]; + if (row != -1) + [rowIndexes addIndex:row]; + } + [noteOutlineView noteHeightOfRowsWithIndexesChanged:rowIndexes]; +} + - (NSMenu *)outlineView:(NSOutlineView *)ov menuForTableColumn:(NSTableColumn *)tableColumn item:(id)item { NSMenu *menu = nil; NSMenuItem *menuItem; @@ -3445,6 +3478,13 @@ [menuItem setTarget:self]; [menuItem setRepresentedObject:annotation]; } + if ([menu numberOfItems] > 0) + [menu addItem:[NSMenuItem separatorItem]]; + menuItem = [menu addItemWithTitle:NSLocalizedString(@"Auto Size Row", @"Menu item title") action:@selector(autoSizeNoteRows:) keyEquivalent:@""]; + [menuItem setTarget:self]; + [menuItem setRepresentedObject:item]; + menuItem = [menu addItemWithTitle:NSLocalizedString(@"Auto Size All", @"Menu item title") action:@selector(autoSizeNoteRows:) keyEquivalent:@""]; + [menuItem setTarget:self]; } return menu; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-06 14:05:15
|
Revision: 2842 http://skim-app.svn.sourceforge.net/skim-app/?rev=2842&view=rev Author: hofman Date: 2007-09-06 07:05:11 -0700 (Thu, 06 Sep 2007) Log Message: ----------- Stop type-select when the key window closes. Modified Paths: -------------- trunk/SKTypeSelectHelper.m Modified: trunk/SKTypeSelectHelper.m =================================================================== --- trunk/SKTypeSelectHelper.m 2007-09-06 12:15:54 UTC (rev 2841) +++ trunk/SKTypeSelectHelper.m 2007-09-06 14:05:11 UTC (rev 2842) @@ -170,6 +170,7 @@ [[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(typeSelectCleanTimeout:) name:SKWindowDidChangeFirstResponderNotification object:keyWindow]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(typeSelectCleanTimeout:) name:NSWindowDidResignKeyNotification object:keyWindow]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(typeSelectCleanTimeout:) name:NSWindowWillCloseNotification object:keyWindow]; [fieldEditor setDelegate:self]; [fieldEditor setString:@""]; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-06 12:15:55
|
Revision: 2841 http://skim-app.svn.sourceforge.net/skim-app/?rev=2841&view=rev Author: hofman Date: 2007-09-06 05:15:54 -0700 (Thu, 06 Sep 2007) Log Message: ----------- initialize ivars. Modified Paths: -------------- trunk/SKTypeSelectHelper.m Modified: trunk/SKTypeSelectHelper.m =================================================================== --- trunk/SKTypeSelectHelper.m 2007-09-05 23:32:15 UTC (rev 2840) +++ trunk/SKTypeSelectHelper.m 2007-09-06 12:15:54 UTC (rev 2841) @@ -70,7 +70,8 @@ - (id)init { if (self = [super init]){ - searchString = [[NSMutableString alloc] init]; + searchCache = nil; + searchString = nil; cycleResults = YES; matchesImmediately = YES; matchOption = SKPrefixMatch; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-05 23:32:18
|
Revision: 2840 http://skim-app.svn.sourceforge.net/skim-app/?rev=2840&view=rev Author: hofman Date: 2007-09-05 16:32:15 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Allow shift-lock modifier for type-select. Pass a dummy key event when clearing the search to clear any uncompleted dead keys, unless someone else took the field editor. Modified Paths: -------------- trunk/SKTypeSelectHelper.m Modified: trunk/SKTypeSelectHelper.m =================================================================== --- trunk/SKTypeSelectHelper.m 2007-09-05 20:09:35 UTC (rev 2839) +++ trunk/SKTypeSelectHelper.m 2007-09-05 23:32:15 UTC (rev 2840) @@ -169,6 +169,7 @@ [[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(typeSelectCleanTimeout:) name:SKWindowDidChangeFirstResponderNotification object:keyWindow]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(typeSelectCleanTimeout:) name:NSWindowDidResignKeyNotification object:keyWindow]; + [fieldEditor setDelegate:self]; [fieldEditor setString:@""]; } @@ -211,7 +212,7 @@ - (BOOL)isSearchEvent:(NSEvent *)keyEvent { if ([keyEvent type] != NSKeyDown) return NO; - if ([keyEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask & ~NSShiftKeyMask & ~NSAlternateKeyMask) + if ([keyEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask & ~NSShiftKeyMask & ~NSAlternateKeyMask & ~NSAlphaShiftKeyMask) return NO; static NSCharacterSet *nonAlphanumericCharacterSet = nil; @@ -292,6 +293,24 @@ [[NSNotificationCenter defaultCenter] removeObserver:self]; [self stopTimer]; processing = NO; + + NSWindow *keyWindow = [NSApp keyWindow]; + NSText *fieldEditor = [keyWindow fieldEditor:YES forObject:self]; + if ([fieldEditor delegate] == self) { + // we pass a dummy key event to the field editor to clear any hanging dead keys (marked text) + NSEvent *keyEvent = [NSEvent keyEventWithType:NSKeyDown + location:NSZeroPoint + modifierFlags:0 + timestamp:0 + windowNumber:0 + context:nil + characters:@"" + charactersIgnoringModifiers:@"" + isARepeat:NO + keyCode:0]; + [fieldEditor interpretKeyEvents:[NSArray arrayWithObject:keyEvent]]; + [fieldEditor setDelegate:nil]; + } } - (void)searchWithStickyMatch:(BOOL)sticky { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-05 20:09:51
|
Revision: 2839 http://skim-app.svn.sourceforge.net/skim-app/?rev=2839&view=rev Author: hofman Date: 2007-09-05 13:09:35 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Redisplay the find table header when we change the header text. Modified Paths: -------------- trunk/SKMainWindowController.m Modified: trunk/SKMainWindowController.m =================================================================== --- trunk/SKMainWindowController.m 2007-09-05 18:51:35 UTC (rev 2838) +++ trunk/SKMainWindowController.m 2007-09-05 20:09:35 UTC (rev 2839) @@ -2365,6 +2365,7 @@ if (findPanelFind == NO) { [findArrayController removeObjects:searchResults]; [[[[findTableView tableColumns] objectAtIndex:1] headerCell] setStringValue:[NSLocalizedString(@"Searching", @"Message in search table header") stringByAppendingEllipsis]]; + [[findTableView headerView] setNeedsDisplay:YES]; [statusBar setProgressIndicatorStyle:SKProgressIndicatorBarStyle]; [[statusBar progressIndicator] setMaxValue:[[note object] pageCount]]; [[statusBar progressIndicator] setDoubleValue:0.0]; @@ -2377,6 +2378,7 @@ [self willChangeValueForKey:@"searchResults"]; [self didChangeValueForKey:@"searchResults"]; [[[[findTableView tableColumns] objectAtIndex:1] headerCell] setStringValue:[NSString stringWithFormat:NSLocalizedString(@"%i Results", @"Message in search table header"), [searchResults count]]]; + [[findTableView headerView] setNeedsDisplay:YES]; [statusBar stopAnimation:self]; [statusBar setProgressIndicatorStyle:SKProgressIndicatorNone]; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-05 18:51:37
|
Revision: 2838 http://skim-app.svn.sourceforge.net/skim-app/?rev=2838&view=rev Author: hofman Date: 2007-09-05 11:51:35 -0700 (Wed, 05 Sep 2007) Log Message: ----------- More type-select improvements. Wrap more determination of event type in TypeSelectHelper. Correct check for characters to extend type-select. Modified Paths: -------------- trunk/SKOutlineView.m trunk/SKPDFView.m trunk/SKTableView.m trunk/SKTypeSelectHelper.h trunk/SKTypeSelectHelper.m Modified: trunk/SKOutlineView.m =================================================================== --- trunk/SKOutlineView.m 2007-09-05 17:33:18 UTC (rev 2837) +++ trunk/SKOutlineView.m 2007-09-05 18:51:35 UTC (rev 2838) @@ -91,16 +91,14 @@ unichar eventChar = [characters length] > 0 ? [characters characterAtIndex:0] : 0; unsigned modifierFlags = [theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask; - if ([typeSelectHelper isTypeSelectEvent:theEvent]) - [typeSelectHelper processKeyDownEvent:theEvent]; - else if ([typeSelectHelper isRepeatEvent:theEvent]) - [typeSelectHelper repeatSearch]; - else if (eventChar == NSHomeFunctionKey && (modifierFlags & ~NSFunctionKeyMask) == 0) + if ([typeSelectHelper processKeyDownEvent:theEvent]) { + } else if (eventChar == NSHomeFunctionKey && (modifierFlags & ~NSFunctionKeyMask) == 0) { [self scrollToBeginningOfDocument:nil]; - else if (eventChar == NSEndFunctionKey && (modifierFlags & ~NSFunctionKeyMask) == 0) + } else if (eventChar == NSEndFunctionKey && (modifierFlags & ~NSFunctionKeyMask) == 0) { [self scrollToEndOfDocument:nil]; - else + } else { [super keyDown:theEvent]; + } } - (void)scrollToBeginningOfDocument:(id)sender { Modified: trunk/SKPDFView.m =================================================================== --- trunk/SKPDFView.m 2007-09-05 17:33:18 UTC (rev 2837) +++ trunk/SKPDFView.m 2007-09-05 18:51:35 UTC (rev 2838) @@ -952,10 +952,7 @@ [self setAnnotationMode:SKStrikeOutNote]; } else if ([self toolMode] == SKNoteToolMode && modifiers == 0 && eventChar == 'l') { [self setAnnotationMode:SKLineNote]; - } else if ([typeSelectHelper isTypeSelectEvent:theEvent]) { - [typeSelectHelper processKeyDownEvent:theEvent]; - } else if ([typeSelectHelper isRepeatEvent:theEvent]) { - [typeSelectHelper repeatSearch]; + } else if ([typeSelectHelper processKeyDownEvent:theEvent]) { } else { [super keyDown:theEvent]; } Modified: trunk/SKTableView.m =================================================================== --- trunk/SKTableView.m 2007-09-05 17:33:18 UTC (rev 2837) +++ trunk/SKTableView.m 2007-09-05 18:51:35 UTC (rev 2838) @@ -69,18 +69,18 @@ unichar eventChar = [characters length] > 0 ? [characters characterAtIndex:0] : 0; unsigned modifierFlags = [theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask; - if ([typeSelectHelper isTypeSelectEvent:theEvent]) - [typeSelectHelper processKeyDownEvent:theEvent]; - else if ([typeSelectHelper isRepeatEvent:theEvent]) + if ([typeSelectHelper processKeyDownEvent:theEvent]) { + } else if ([typeSelectHelper isRepeatEvent:theEvent]) { [typeSelectHelper repeatSearch]; - else if ((eventChar == NSDeleteCharacter || eventChar == NSDeleteFunctionKey) && modifierFlags == 0 && [self canDelete]) + } else if ((eventChar == NSDeleteCharacter || eventChar == NSDeleteFunctionKey) && modifierFlags == 0 && [self canDelete]) { [self delete:self]; - else if (eventChar == NSHomeFunctionKey && (modifierFlags & ~NSFunctionKeyMask) == 0) + } else if (eventChar == NSHomeFunctionKey && (modifierFlags & ~NSFunctionKeyMask) == 0) { [self scrollToBeginningOfDocument:nil]; - else if (eventChar == NSEndFunctionKey && (modifierFlags & ~NSFunctionKeyMask) == 0) + } else if (eventChar == NSEndFunctionKey && (modifierFlags & ~NSFunctionKeyMask) == 0) { [self scrollToEndOfDocument:nil]; - else + } else { [super keyDown:theEvent]; + } } - (void)scrollToBeginningOfDocument:(id)sender { Modified: trunk/SKTypeSelectHelper.h =================================================================== --- trunk/SKTypeSelectHelper.h 2007-09-05 17:33:18 UTC (rev 2837) +++ trunk/SKTypeSelectHelper.h 2007-09-05 18:51:35 UTC (rev 2838) @@ -76,12 +76,15 @@ - (void)rebuildTypeSelectSearchCache; -- (void)processKeyDownEvent:(NSEvent *)keyEvent; +- (BOOL)processKeyDownEvent:(NSEvent *)keyEvent; +- (void)searchWithEvent:(NSEvent *)keyEvent; - (void)repeatSearch; -- (void)stopSearch; +- (void)cancelSearch; - (BOOL)isTypeSelectEvent:(NSEvent *)keyEvent; +- (BOOL)isSearchEvent:(NSEvent *)keyEvent; - (BOOL)isRepeatEvent:(NSEvent *)keyEvent; +- (BOOL)isCancelEvent:(NSEvent *)keyEvent; @end Modified: trunk/SKTypeSelectHelper.m =================================================================== --- trunk/SKTypeSelectHelper.m 2007-09-05 17:33:18 UTC (rev 2837) +++ trunk/SKTypeSelectHelper.m 2007-09-05 18:51:35 UTC (rev 2838) @@ -41,7 +41,8 @@ static NSString *SKWindowDidChangeFirstResponderNotification = @"SKWindowDidChangeFirstResponderNotification"; -#define REPEAT_CHARACTER '/' +#define REPEAT_CHARACTER 0x2F +#define CANCEL_CHARACTER 0x1B @interface NSString (SKTypeAheadHelperExtensions) - (BOOL)containsStringStartingAtWord:(NSString *)string options:(int)mask range:(NSRange)range; @@ -146,12 +147,28 @@ searchCache = [[dataSource typeSelectHelperSelectionItems:self] retain]; } -- (void)processKeyDownEvent:(NSEvent *)keyEvent { - NSText *fieldEditor = [[NSApp keyWindow] fieldEditor:YES forObject:self]; +- (BOOL)processKeyDownEvent:(NSEvent *)keyEvent { + if ([self isSearchEvent:keyEvent]) { + [self searchWithEvent:keyEvent]; + return YES; + } else if ([self isRepeatEvent:keyEvent]) { + [self repeatSearch]; + return YES; + } else if ([self isCancelEvent:keyEvent]) { + [self cancelSearch]; + return YES; + } + return NO; +} + +- (void)searchWithEvent:(NSEvent *)keyEvent { + NSWindow *keyWindow = [NSApp keyWindow]; + NSText *fieldEditor = [keyWindow fieldEditor:YES forObject:self]; if (processing == NO) { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(typeSelectCleanTimeout:) name:SKWindowDidChangeFirstResponderNotification object:[NSApp keyWindow]]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(typeSelectCleanTimeout:) name:NSWindowDidResignKeyNotification object:[NSApp keyWindow]]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(typeSelectCleanTimeout:) name:SKWindowDidChangeFirstResponderNotification object:keyWindow]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(typeSelectCleanTimeout:) name:NSWindowDidResignKeyNotification object:keyWindow]; [fieldEditor setString:@""]; } @@ -182,33 +199,28 @@ processing = NO; } -- (void)stopSearch { +- (void)cancelSearch { if (timer) [self typeSelectCleanTimeout:timer]; } - (BOOL)isTypeSelectEvent:(NSEvent *)keyEvent { + return [self isSearchEvent:keyEvent] || [self isRepeatEvent:keyEvent] || [self isCancelEvent:keyEvent]; +} + +- (BOOL)isSearchEvent:(NSEvent *)keyEvent { if ([keyEvent type] != NSKeyDown) return NO; if ([keyEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask & ~NSShiftKeyMask & ~NSAlternateKeyMask) return NO; - NSString *characters = [keyEvent charactersIgnoringModifiers]; - int i, count = [characters length]; - unichar character; + static NSCharacterSet *nonAlphanumericCharacterSet = nil; + if (nonAlphanumericCharacterSet == nil) + nonAlphanumericCharacterSet = [[[NSCharacterSet alphanumericCharacterSet] invertedSet] copy]; - if (count == 0) - return NO; + NSCharacterSet *invalidCharacters = [self isProcessing] ? [NSCharacterSet controlCharacterSet] : nonAlphanumericCharacterSet; - for (i = 0; i < count; i++) { - character = [characters characterAtIndex:i]; - if ([[NSCharacterSet alphanumericCharacterSet] characterIsMember:character]) - continue; - if ([self isProcessing] && [[NSCharacterSet controlCharacterSet] characterIsMember:character]) - continue; - return NO; - } - return YES; + return [[keyEvent characters] rangeOfCharacterFromSet:invalidCharacters].location == NSNotFound; } - (BOOL)isRepeatEvent:(NSEvent *)keyEvent { @@ -222,6 +234,19 @@ return modifierFlags == 0 && character == REPEAT_CHARACTER; } +- (BOOL)isCancelEvent:(NSEvent *)keyEvent { + if ([keyEvent type] != NSKeyDown) + return NO; + if ([self isProcessing] == NO) + return NO; + + NSString *characters = [keyEvent charactersIgnoringModifiers]; + unichar character = [characters length] > 0 ? [characters characterAtIndex:0] : 0; + unsigned modifierFlags = [keyEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask; + + return modifierFlags == 0 && character == CANCEL_CHARACTER; +} + @end #pragma mark - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-05 17:33:23
|
Revision: 2837 http://skim-app.svn.sourceforge.net/skim-app/?rev=2837&view=rev Author: hofman Date: 2007-09-05 10:33:18 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Use a notification to stop type-select when the first responder or the key window changes. Modified Paths: -------------- trunk/SKOutlineView.m trunk/SKPDFView.m trunk/SKTableView.m trunk/SKTypeSelectHelper.m Modified: trunk/SKOutlineView.m =================================================================== --- trunk/SKOutlineView.m 2007-09-05 16:50:17 UTC (rev 2836) +++ trunk/SKOutlineView.m 2007-09-05 17:33:18 UTC (rev 2837) @@ -103,13 +103,6 @@ [super keyDown:theEvent]; } -- (BOOL)resignFirstResponder { - BOOL shouldResign = [super resignFirstResponder]; - if (shouldResign) - [typeSelectHelper stopSearch]; - return shouldResign; -} - - (void)scrollToBeginningOfDocument:(id)sender { if ([self numberOfRows]) [self scrollRowToVisible:0]; Modified: trunk/SKPDFView.m =================================================================== --- trunk/SKPDFView.m 2007-09-05 16:50:17 UTC (rev 2836) +++ trunk/SKPDFView.m 2007-09-05 17:33:18 UTC (rev 2837) @@ -1441,13 +1441,6 @@ [[NSSpellChecker sharedSpellChecker] ignoreWord:[[sender selectedCell] stringValue] inSpellDocumentWithTag:spellingTag]; } -- (BOOL)resignFirstResponder { - BOOL shouldResign = [super resignFirstResponder]; - if (shouldResign) - [typeSelectHelper stopSearch]; - return shouldResign; -} - #pragma mark Tracking mousemoved fix - (void)setFrame:(NSRect)frame { Modified: trunk/SKTableView.m =================================================================== --- trunk/SKTableView.m 2007-09-05 16:50:17 UTC (rev 2836) +++ trunk/SKTableView.m 2007-09-05 17:33:18 UTC (rev 2837) @@ -83,13 +83,6 @@ [super keyDown:theEvent]; } -- (BOOL)resignFirstResponder { - BOOL shouldResign = [super resignFirstResponder]; - if (shouldResign) - [typeSelectHelper stopSearch]; - return shouldResign; -} - - (void)scrollToBeginningOfDocument:(id)sender { if ([self numberOfRows]) [self scrollRowToVisible:0]; Modified: trunk/SKTypeSelectHelper.m =================================================================== --- trunk/SKTypeSelectHelper.m 2007-09-05 16:50:17 UTC (rev 2836) +++ trunk/SKTypeSelectHelper.m 2007-09-05 17:33:18 UTC (rev 2837) @@ -37,13 +37,19 @@ */ #import "SKTypeSelectHelper.h" +#import "OBUtilities.h" +static NSString *SKWindowDidChangeFirstResponderNotification = @"SKWindowDidChangeFirstResponderNotification"; + #define REPEAT_CHARACTER '/' -@interface NSString (BDSKTypeAheadHelperExtensions) +@interface NSString (SKTypeAheadHelperExtensions) - (BOOL)containsStringStartingAtWord:(NSString *)string options:(int)mask range:(NSRange)range; @end +@interface NSWindow (SKTypeAheadHelperExtensions) +@end + #pragma mark - @interface SKTypeSelectHelper (SKPrivate) @@ -52,8 +58,8 @@ - (void)searchWithStickyMatch:(BOOL)allowUpdate; - (void)stopTimer; - (void)startTimerForSelector:(SEL)selector; -- (void)typeSelectSearchTimeout:(NSTimer *)aTimer; -- (void)typeSelectCleanTimeout:(NSTimer *)aTimer; +- (void)typeSelectSearchTimeout:(id)sender; +- (void)typeSelectCleanTimeout:(id)sender; - (unsigned int)indexOfMatchedItemAfterIndex:(unsigned int)selectedIndex; @end @@ -72,6 +78,7 @@ } - (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; [self stopTimer]; [searchString release]; [searchCache release]; @@ -142,8 +149,11 @@ - (void)processKeyDownEvent:(NSEvent *)keyEvent { NSText *fieldEditor = [[NSApp keyWindow] fieldEditor:YES forObject:self]; - if (processing == NO) + if (processing == NO) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(typeSelectCleanTimeout:) name:SKWindowDidChangeFirstResponderNotification object:[NSApp keyWindow]]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(typeSelectCleanTimeout:) name:NSWindowDidResignKeyNotification object:[NSApp keyWindow]]; [fieldEditor setString:@""]; + } // Append the new character to the search string [fieldEditor interpretKeyEvents:[NSArray arrayWithObject:keyEvent]]; @@ -196,6 +206,7 @@ continue; if ([self isProcessing] && [[NSCharacterSet controlCharacterSet] characterIsMember:character]) continue; + return NO; } return YES; } @@ -244,15 +255,16 @@ [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; } -- (void)typeSelectSearchTimeout:(NSTimer *)aTimer { +- (void)typeSelectSearchTimeout:(id)sender { if (matchesImmediately == NO) [self searchWithStickyMatch:NO]; - [self typeSelectCleanTimeout:aTimer]; + [self typeSelectCleanTimeout:sender]; } -- (void)typeSelectCleanTimeout:(NSTimer *)aTimer { +- (void)typeSelectCleanTimeout:(id)sender { if ([dataSource respondsToSelector:@selector(typeSelectHelper:updateSearchString:)]) [dataSource typeSelectHelper:self updateSearchString:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; [self stopTimer]; processing = NO; } @@ -328,7 +340,7 @@ #pragma mark - -@implementation NSString (BDSKTypeAheadHelperExtensions) +@implementation NSString (SKTypeAheadHelperExtensions) - (BOOL)containsStringStartingAtWord:(NSString *)string options:(int)mask range:(NSRange)range { unsigned int stringLength = [string length]; @@ -354,3 +366,23 @@ } @end + +#pragma mark - + +@implementation NSWindow (SKTypeAheadHelperExtensions) + +static BOOL (*originalMakeFirstResponder)(id, SEL, id) = NULL; + ++ (void)load { + originalMakeFirstResponder = (typeof(originalMakeFirstResponder))OBReplaceMethodImplementationWithSelector(self, @selector(makeFirstResponder:), @selector(replacementMakeFirstResponder:)); +} + +- (BOOL)replacementMakeFirstResponder:(NSResponder *)aResponder { + id oldFirstResponder = [self firstResponder]; + BOOL success = originalMakeFirstResponder(self, _cmd, aResponder); + if (oldFirstResponder != [self firstResponder]) + [[NSNotificationCenter defaultCenter] postNotificationName:SKWindowDidChangeFirstResponderNotification object:self]; + return success; +} + +@end This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-05 16:50:18
|
Revision: 2836 http://skim-app.svn.sourceforge.net/skim-app/?rev=2836&view=rev Author: hofman Date: 2007-09-05 09:50:17 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Revert last commit, as it disables type-select in the PDFView. Modified Paths: -------------- trunk/SKOutlineView.m trunk/SKPDFView.m trunk/SKTableView.m trunk/SKTypeSelectHelper.h trunk/SKTypeSelectHelper.m Modified: trunk/SKOutlineView.m =================================================================== --- trunk/SKOutlineView.m 2007-09-05 16:11:40 UTC (rev 2835) +++ trunk/SKOutlineView.m 2007-09-05 16:50:17 UTC (rev 2836) @@ -91,9 +91,9 @@ unichar eventChar = [characters length] > 0 ? [characters characterAtIndex:0] : 0; unsigned modifierFlags = [theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask; - if ([typeSelectHelper isTypeSelectEvent:theEvent forView:self]) - [typeSelectHelper processKeyDownEvent:theEvent forView:self]; - else if ([typeSelectHelper isRepeatEvent:theEvent forView:self]) + if ([typeSelectHelper isTypeSelectEvent:theEvent]) + [typeSelectHelper processKeyDownEvent:theEvent]; + else if ([typeSelectHelper isRepeatEvent:theEvent]) [typeSelectHelper repeatSearch]; else if (eventChar == NSHomeFunctionKey && (modifierFlags & ~NSFunctionKeyMask) == 0) [self scrollToBeginningOfDocument:nil]; Modified: trunk/SKPDFView.m =================================================================== --- trunk/SKPDFView.m 2007-09-05 16:11:40 UTC (rev 2835) +++ trunk/SKPDFView.m 2007-09-05 16:50:17 UTC (rev 2836) @@ -952,9 +952,9 @@ [self setAnnotationMode:SKStrikeOutNote]; } else if ([self toolMode] == SKNoteToolMode && modifiers == 0 && eventChar == 'l') { [self setAnnotationMode:SKLineNote]; - } else if ([typeSelectHelper isTypeSelectEvent:theEvent forView:self]) { - [typeSelectHelper processKeyDownEvent:theEvent forView:self]; - } else if ([typeSelectHelper isRepeatEvent:theEvent forView:self]) { + } else if ([typeSelectHelper isTypeSelectEvent:theEvent]) { + [typeSelectHelper processKeyDownEvent:theEvent]; + } else if ([typeSelectHelper isRepeatEvent:theEvent]) { [typeSelectHelper repeatSearch]; } else { [super keyDown:theEvent]; Modified: trunk/SKTableView.m =================================================================== --- trunk/SKTableView.m 2007-09-05 16:11:40 UTC (rev 2835) +++ trunk/SKTableView.m 2007-09-05 16:50:17 UTC (rev 2836) @@ -69,9 +69,9 @@ unichar eventChar = [characters length] > 0 ? [characters characterAtIndex:0] : 0; unsigned modifierFlags = [theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask; - if ([typeSelectHelper isTypeSelectEvent:theEvent forView:self]) - [typeSelectHelper processKeyDownEvent:theEvent forView:self]; - else if ([typeSelectHelper isRepeatEvent:theEvent forView:self]) + if ([typeSelectHelper isTypeSelectEvent:theEvent]) + [typeSelectHelper processKeyDownEvent:theEvent]; + else if ([typeSelectHelper isRepeatEvent:theEvent]) [typeSelectHelper repeatSearch]; else if ((eventChar == NSDeleteCharacter || eventChar == NSDeleteFunctionKey) && modifierFlags == 0 && [self canDelete]) [self delete:self]; Modified: trunk/SKTypeSelectHelper.h =================================================================== --- trunk/SKTypeSelectHelper.h 2007-09-05 16:11:40 UTC (rev 2835) +++ trunk/SKTypeSelectHelper.h 2007-09-05 16:50:17 UTC (rev 2836) @@ -76,12 +76,12 @@ - (void)rebuildTypeSelectSearchCache; -- (void)processKeyDownEvent:(NSEvent *)keyEvent forView:(NSView *)view; +- (void)processKeyDownEvent:(NSEvent *)keyEvent; - (void)repeatSearch; - (void)stopSearch; -- (BOOL)isTypeSelectEvent:(NSEvent *)keyEvent forView:(NSView *)view; -- (BOOL)isRepeatEvent:(NSEvent *)keyEvent forView:(NSView *)view; +- (BOOL)isTypeSelectEvent:(NSEvent *)keyEvent; +- (BOOL)isRepeatEvent:(NSEvent *)keyEvent; @end Modified: trunk/SKTypeSelectHelper.m =================================================================== --- trunk/SKTypeSelectHelper.m 2007-09-05 16:11:40 UTC (rev 2835) +++ trunk/SKTypeSelectHelper.m 2007-09-05 16:50:17 UTC (rev 2836) @@ -139,28 +139,26 @@ searchCache = [[dataSource typeSelectHelperSelectionItems:self] retain]; } -- (void)processKeyDownEvent:(NSEvent *)keyEvent forView:(NSView *)view { - if ([self isTypeSelectEvent:keyEvent forView:view]) { - NSText *fieldEditor = [[view window] fieldEditor:YES forObject:self]; - - if (processing == NO) - [fieldEditor setString:@""]; - - // Append the new character to the search string - [fieldEditor interpretKeyEvents:[NSArray arrayWithObject:keyEvent]]; - [self setSearchString:[fieldEditor string]]; - - if ([dataSource respondsToSelector:@selector(typeSelectHelper:updateSearchString:)]) - [dataSource typeSelectHelper:self updateSearchString:searchString]; - - // Reset the timer if it hasn't expired yet - [self startTimerForSelector:@selector(typeSelectSearchTimeout:)]; - - if (matchesImmediately) - [self searchWithStickyMatch:processing]; - - processing = YES; - } +- (void)processKeyDownEvent:(NSEvent *)keyEvent { + NSText *fieldEditor = [[NSApp keyWindow] fieldEditor:YES forObject:self]; + + if (processing == NO) + [fieldEditor setString:@""]; + + // Append the new character to the search string + [fieldEditor interpretKeyEvents:[NSArray arrayWithObject:keyEvent]]; + [self setSearchString:[fieldEditor string]]; + + if ([dataSource respondsToSelector:@selector(typeSelectHelper:updateSearchString:)]) + [dataSource typeSelectHelper:self updateSearchString:searchString]; + + // Reset the timer if it hasn't expired yet + [self startTimerForSelector:@selector(typeSelectSearchTimeout:)]; + + if (matchesImmediately) + [self searchWithStickyMatch:processing]; + + processing = YES; } - (void)repeatSearch { @@ -179,13 +177,11 @@ [self typeSelectCleanTimeout:timer]; } -- (BOOL)isTypeSelectEvent:(NSEvent *)keyEvent forView:(NSView *)view { +- (BOOL)isTypeSelectEvent:(NSEvent *)keyEvent { if ([keyEvent type] != NSKeyDown) return NO; if ([keyEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask & ~NSShiftKeyMask & ~NSAlternateKeyMask) return NO; - if ([[view window] firstResponder] != view) - return NO; NSString *characters = [keyEvent charactersIgnoringModifiers]; int i, count = [characters length]; @@ -204,11 +200,9 @@ return YES; } -- (BOOL)isRepeatEvent:(NSEvent *)keyEvent forView:(NSView *)view { +- (BOOL)isRepeatEvent:(NSEvent *)keyEvent { if ([keyEvent type] != NSKeyDown) return NO; - if ([[view window] firstResponder] != view) - return NO; NSString *characters = [keyEvent charactersIgnoringModifiers]; unichar character = [characters length] > 0 ? [characters characterAtIndex:0] : 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-05 16:11:45
|
Revision: 2835 http://skim-app.svn.sourceforge.net/skim-app/?rev=2835&view=rev Author: hofman Date: 2007-09-05 09:11:40 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Check the view for type-select for first responder status and for the field editor. Modified Paths: -------------- trunk/SKOutlineView.m trunk/SKPDFView.m trunk/SKTableView.m trunk/SKTypeSelectHelper.h trunk/SKTypeSelectHelper.m Modified: trunk/SKOutlineView.m =================================================================== --- trunk/SKOutlineView.m 2007-09-05 13:52:22 UTC (rev 2834) +++ trunk/SKOutlineView.m 2007-09-05 16:11:40 UTC (rev 2835) @@ -91,9 +91,9 @@ unichar eventChar = [characters length] > 0 ? [characters characterAtIndex:0] : 0; unsigned modifierFlags = [theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask; - if ([typeSelectHelper isTypeSelectEvent:theEvent]) - [typeSelectHelper processKeyDownEvent:theEvent]; - else if ([typeSelectHelper isRepeatEvent:theEvent]) + if ([typeSelectHelper isTypeSelectEvent:theEvent forView:self]) + [typeSelectHelper processKeyDownEvent:theEvent forView:self]; + else if ([typeSelectHelper isRepeatEvent:theEvent forView:self]) [typeSelectHelper repeatSearch]; else if (eventChar == NSHomeFunctionKey && (modifierFlags & ~NSFunctionKeyMask) == 0) [self scrollToBeginningOfDocument:nil]; Modified: trunk/SKPDFView.m =================================================================== --- trunk/SKPDFView.m 2007-09-05 13:52:22 UTC (rev 2834) +++ trunk/SKPDFView.m 2007-09-05 16:11:40 UTC (rev 2835) @@ -952,9 +952,9 @@ [self setAnnotationMode:SKStrikeOutNote]; } else if ([self toolMode] == SKNoteToolMode && modifiers == 0 && eventChar == 'l') { [self setAnnotationMode:SKLineNote]; - } else if ([typeSelectHelper isTypeSelectEvent:theEvent]) { - [typeSelectHelper processKeyDownEvent:theEvent]; - } else if ([typeSelectHelper isRepeatEvent:theEvent]) { + } else if ([typeSelectHelper isTypeSelectEvent:theEvent forView:self]) { + [typeSelectHelper processKeyDownEvent:theEvent forView:self]; + } else if ([typeSelectHelper isRepeatEvent:theEvent forView:self]) { [typeSelectHelper repeatSearch]; } else { [super keyDown:theEvent]; Modified: trunk/SKTableView.m =================================================================== --- trunk/SKTableView.m 2007-09-05 13:52:22 UTC (rev 2834) +++ trunk/SKTableView.m 2007-09-05 16:11:40 UTC (rev 2835) @@ -69,9 +69,9 @@ unichar eventChar = [characters length] > 0 ? [characters characterAtIndex:0] : 0; unsigned modifierFlags = [theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask; - if ([typeSelectHelper isTypeSelectEvent:theEvent]) - [typeSelectHelper processKeyDownEvent:theEvent]; - else if ([typeSelectHelper isRepeatEvent:theEvent]) + if ([typeSelectHelper isTypeSelectEvent:theEvent forView:self]) + [typeSelectHelper processKeyDownEvent:theEvent forView:self]; + else if ([typeSelectHelper isRepeatEvent:theEvent forView:self]) [typeSelectHelper repeatSearch]; else if ((eventChar == NSDeleteCharacter || eventChar == NSDeleteFunctionKey) && modifierFlags == 0 && [self canDelete]) [self delete:self]; Modified: trunk/SKTypeSelectHelper.h =================================================================== --- trunk/SKTypeSelectHelper.h 2007-09-05 13:52:22 UTC (rev 2834) +++ trunk/SKTypeSelectHelper.h 2007-09-05 16:11:40 UTC (rev 2835) @@ -76,12 +76,12 @@ - (void)rebuildTypeSelectSearchCache; -- (void)processKeyDownEvent:(NSEvent *)keyEvent; +- (void)processKeyDownEvent:(NSEvent *)keyEvent forView:(NSView *)view; - (void)repeatSearch; - (void)stopSearch; -- (BOOL)isTypeSelectEvent:(NSEvent *)keyEvent; -- (BOOL)isRepeatEvent:(NSEvent *)keyEvent; +- (BOOL)isTypeSelectEvent:(NSEvent *)keyEvent forView:(NSView *)view; +- (BOOL)isRepeatEvent:(NSEvent *)keyEvent forView:(NSView *)view; @end Modified: trunk/SKTypeSelectHelper.m =================================================================== --- trunk/SKTypeSelectHelper.m 2007-09-05 13:52:22 UTC (rev 2834) +++ trunk/SKTypeSelectHelper.m 2007-09-05 16:11:40 UTC (rev 2835) @@ -139,26 +139,28 @@ searchCache = [[dataSource typeSelectHelperSelectionItems:self] retain]; } -- (void)processKeyDownEvent:(NSEvent *)keyEvent { - NSText *fieldEditor = [[NSApp keyWindow] fieldEditor:YES forObject:self]; - - if (processing == NO) - [fieldEditor setString:@""]; - - // Append the new character to the search string - [fieldEditor interpretKeyEvents:[NSArray arrayWithObject:keyEvent]]; - [self setSearchString:[fieldEditor string]]; - - if ([dataSource respondsToSelector:@selector(typeSelectHelper:updateSearchString:)]) - [dataSource typeSelectHelper:self updateSearchString:searchString]; - - // Reset the timer if it hasn't expired yet - [self startTimerForSelector:@selector(typeSelectSearchTimeout:)]; - - if (matchesImmediately) - [self searchWithStickyMatch:processing]; - - processing = YES; +- (void)processKeyDownEvent:(NSEvent *)keyEvent forView:(NSView *)view { + if ([self isTypeSelectEvent:keyEvent forView:view]) { + NSText *fieldEditor = [[view window] fieldEditor:YES forObject:self]; + + if (processing == NO) + [fieldEditor setString:@""]; + + // Append the new character to the search string + [fieldEditor interpretKeyEvents:[NSArray arrayWithObject:keyEvent]]; + [self setSearchString:[fieldEditor string]]; + + if ([dataSource respondsToSelector:@selector(typeSelectHelper:updateSearchString:)]) + [dataSource typeSelectHelper:self updateSearchString:searchString]; + + // Reset the timer if it hasn't expired yet + [self startTimerForSelector:@selector(typeSelectSearchTimeout:)]; + + if (matchesImmediately) + [self searchWithStickyMatch:processing]; + + processing = YES; + } } - (void)repeatSearch { @@ -177,11 +179,13 @@ [self typeSelectCleanTimeout:timer]; } -- (BOOL)isTypeSelectEvent:(NSEvent *)keyEvent { +- (BOOL)isTypeSelectEvent:(NSEvent *)keyEvent forView:(NSView *)view { if ([keyEvent type] != NSKeyDown) return NO; if ([keyEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask & ~NSShiftKeyMask & ~NSAlternateKeyMask) return NO; + if ([[view window] firstResponder] != view) + return NO; NSString *characters = [keyEvent charactersIgnoringModifiers]; int i, count = [characters length]; @@ -200,9 +204,11 @@ return YES; } -- (BOOL)isRepeatEvent:(NSEvent *)keyEvent { +- (BOOL)isRepeatEvent:(NSEvent *)keyEvent forView:(NSView *)view { if ([keyEvent type] != NSKeyDown) return NO; + if ([[view window] firstResponder] != view) + return NO; NSString *characters = [keyEvent charactersIgnoringModifiers]; unichar character = [characters length] > 0 ? [characters characterAtIndex:0] : 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-05 13:52:24
|
Revision: 2834 http://skim-app.svn.sourceforge.net/skim-app/?rev=2834&view=rev Author: hofman Date: 2007-09-05 06:52:22 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Allow non-ascii characters for type-select. Use the current keyWindow's field editor to compose text. Modified Paths: -------------- trunk/SKBookmarkController.m trunk/SKMainWindowController.m trunk/SKNotesDocument.m trunk/SKOutlineView.m trunk/SKPDFView.m trunk/SKTableView.m trunk/SKTypeSelectHelper.h trunk/SKTypeSelectHelper.m Modified: trunk/SKBookmarkController.m =================================================================== --- trunk/SKBookmarkController.m 2007-09-05 12:51:37 UTC (rev 2833) +++ trunk/SKBookmarkController.m 2007-09-05 13:52:22 UTC (rev 2834) @@ -360,7 +360,7 @@ #pragma mark SKTypeSelectHelper datasource protocol - (NSArray *)typeSelectHelperSelectionItems:(SKTypeSelectHelper *)typeSelectHelper { - return [bookmarks valueForKeyPath:@"label.lossyASCIIString"]; + return [bookmarks valueForKey:@"label"]; } - (unsigned int)typeSelectHelperCurrentlySelectedIndex:(SKTypeSelectHelper *)typeSelectHelper { Modified: trunk/SKMainWindowController.m =================================================================== --- trunk/SKMainWindowController.m 2007-09-05 12:51:37 UTC (rev 2833) +++ trunk/SKMainWindowController.m 2007-09-05 13:52:22 UTC (rev 2834) @@ -3648,7 +3648,7 @@ if ([typeSelectHelper isEqual:[thumbnailTableView typeSelectHelper]] || [typeSelectHelper isEqual:[pdfView typeSelectHelper]]) { return pageLabels; } else if ([typeSelectHelper isEqual:[noteOutlineView typeSelectHelper]]) { - return [[noteArrayController arrangedObjects] valueForKeyPath:@"contents.lossyASCIIString"]; + return [[noteArrayController arrangedObjects] valueForKey:@"contents"]; } else if ([typeSelectHelper isEqual:[outlineView typeSelectHelper]]) { int i, count = [outlineView numberOfRows]; NSMutableArray *array = [NSMutableArray arrayWithCapacity:count]; Modified: trunk/SKNotesDocument.m =================================================================== --- trunk/SKNotesDocument.m 2007-09-05 12:51:37 UTC (rev 2833) +++ trunk/SKNotesDocument.m 2007-09-05 13:52:22 UTC (rev 2834) @@ -332,7 +332,7 @@ #pragma mark SKTypeSelectHelper datasource protocol - (NSArray *)typeSelectHelperSelectionItems:(SKTypeSelectHelper *)typeSelectHelper { - return [[arrayController arrangedObjects] valueForKeyPath:@"contents.lossyASCIIString"]; + return [[arrayController arrangedObjects] valueForKey:@"contents"]; } - (unsigned int)typeSelectHelperCurrentlySelectedIndex:(SKTypeSelectHelper *)typeSelectHelper { Modified: trunk/SKOutlineView.m =================================================================== --- trunk/SKOutlineView.m 2007-09-05 12:51:37 UTC (rev 2833) +++ trunk/SKOutlineView.m 2007-09-05 13:52:22 UTC (rev 2834) @@ -91,9 +91,9 @@ unichar eventChar = [characters length] > 0 ? [characters characterAtIndex:0] : 0; unsigned modifierFlags = [theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask; - if ([typeSelectHelper isTypeSelectCharacter:eventChar] && typeSelectHelper && modifierFlags == 0) - [typeSelectHelper processKeyDownCharacter:eventChar]; - else if ([typeSelectHelper isRepeatCharacter:eventChar] && modifierFlags == 0) + if ([typeSelectHelper isTypeSelectEvent:theEvent]) + [typeSelectHelper processKeyDownEvent:theEvent]; + else if ([typeSelectHelper isRepeatEvent:theEvent]) [typeSelectHelper repeatSearch]; else if (eventChar == NSHomeFunctionKey && (modifierFlags & ~NSFunctionKeyMask) == 0) [self scrollToBeginningOfDocument:nil]; @@ -103,6 +103,13 @@ [super keyDown:theEvent]; } +- (BOOL)resignFirstResponder { + BOOL shouldResign = [super resignFirstResponder]; + if (shouldResign) + [typeSelectHelper stopSearch]; + return shouldResign; +} + - (void)scrollToBeginningOfDocument:(id)sender { if ([self numberOfRows]) [self scrollRowToVisible:0]; Modified: trunk/SKPDFView.m =================================================================== --- trunk/SKPDFView.m 2007-09-05 12:51:37 UTC (rev 2833) +++ trunk/SKPDFView.m 2007-09-05 13:52:22 UTC (rev 2834) @@ -952,9 +952,9 @@ [self setAnnotationMode:SKStrikeOutNote]; } else if ([self toolMode] == SKNoteToolMode && modifiers == 0 && eventChar == 'l') { [self setAnnotationMode:SKLineNote]; - } else if ([typeSelectHelper isTypeSelectCharacter:eventChar] && modifiers == 0) { - [typeSelectHelper processKeyDownCharacter:eventChar]; - } else if ([typeSelectHelper isRepeatCharacter:eventChar] && modifiers == 0) { + } else if ([typeSelectHelper isTypeSelectEvent:theEvent]) { + [typeSelectHelper processKeyDownEvent:theEvent]; + } else if ([typeSelectHelper isRepeatEvent:theEvent]) { [typeSelectHelper repeatSearch]; } else { [super keyDown:theEvent]; @@ -1441,6 +1441,13 @@ [[NSSpellChecker sharedSpellChecker] ignoreWord:[[sender selectedCell] stringValue] inSpellDocumentWithTag:spellingTag]; } +- (BOOL)resignFirstResponder { + BOOL shouldResign = [super resignFirstResponder]; + if (shouldResign) + [typeSelectHelper stopSearch]; + return shouldResign; +} + #pragma mark Tracking mousemoved fix - (void)setFrame:(NSRect)frame { Modified: trunk/SKTableView.m =================================================================== --- trunk/SKTableView.m 2007-09-05 12:51:37 UTC (rev 2833) +++ trunk/SKTableView.m 2007-09-05 13:52:22 UTC (rev 2834) @@ -69,9 +69,9 @@ unichar eventChar = [characters length] > 0 ? [characters characterAtIndex:0] : 0; unsigned modifierFlags = [theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask; - if ([typeSelectHelper isTypeSelectCharacter:eventChar] && typeSelectHelper && modifierFlags == 0) - [typeSelectHelper processKeyDownCharacter:eventChar]; - else if ([typeSelectHelper isRepeatCharacter:eventChar] && modifierFlags == 0) + if ([typeSelectHelper isTypeSelectEvent:theEvent]) + [typeSelectHelper processKeyDownEvent:theEvent]; + else if ([typeSelectHelper isRepeatEvent:theEvent]) [typeSelectHelper repeatSearch]; else if ((eventChar == NSDeleteCharacter || eventChar == NSDeleteFunctionKey) && modifierFlags == 0 && [self canDelete]) [self delete:self]; @@ -83,6 +83,13 @@ [super keyDown:theEvent]; } +- (BOOL)resignFirstResponder { + BOOL shouldResign = [super resignFirstResponder]; + if (shouldResign) + [typeSelectHelper stopSearch]; + return shouldResign; +} + - (void)scrollToBeginningOfDocument:(id)sender { if ([self numberOfRows]) [self scrollRowToVisible:0]; Modified: trunk/SKTypeSelectHelper.h =================================================================== --- trunk/SKTypeSelectHelper.h 2007-09-05 12:51:37 UTC (rev 2833) +++ trunk/SKTypeSelectHelper.h 2007-09-05 13:52:22 UTC (rev 2834) @@ -52,7 +52,7 @@ BOOL matchesImmediately; NSArray *searchCache; - NSMutableString *searchString; + NSString *searchString; NSTimer *timer; BOOL processing; } @@ -68,16 +68,20 @@ - (int)matchOption; - (void)setMatchOption:(int)newValue; + +- (NSString *)searchString; +- (void)setSearchString:(NSString *)newSearchString; -- (void)rebuildTypeSelectSearchCache; - - (BOOL)isProcessing; -- (void)processKeyDownCharacter:(unichar)character; +- (void)rebuildTypeSelectSearchCache; + +- (void)processKeyDownEvent:(NSEvent *)keyEvent; - (void)repeatSearch; +- (void)stopSearch; -- (BOOL)isTypeSelectCharacter:(unichar)character; -- (BOOL)isRepeatCharacter:(unichar)character; +- (BOOL)isTypeSelectEvent:(NSEvent *)keyEvent; +- (BOOL)isRepeatEvent:(NSEvent *)keyEvent; @end Modified: trunk/SKTypeSelectHelper.m =================================================================== --- trunk/SKTypeSelectHelper.m 2007-09-05 12:51:37 UTC (rev 2833) +++ trunk/SKTypeSelectHelper.m 2007-09-05 13:52:22 UTC (rev 2834) @@ -115,6 +115,17 @@ matchOption = newValue; } +- (NSString *)searchString { + return searchString; +} + +- (void)setSearchString:(NSString *)newSearchString { + if (searchString != newSearchString) { + [searchString release]; + searchString = [newSearchString retain]; + } +} + - (BOOL)isProcessing { return processing; } @@ -128,12 +139,15 @@ searchCache = [[dataSource typeSelectHelperSelectionItems:self] retain]; } -- (void)processKeyDownCharacter:(unichar)character { +- (void)processKeyDownEvent:(NSEvent *)keyEvent { + NSText *fieldEditor = [[NSApp keyWindow] fieldEditor:YES forObject:self]; + if (processing == NO) - [searchString setString:@""]; + [fieldEditor setString:@""]; // Append the new character to the search string - [searchString appendFormat:@"%C", character]; + [fieldEditor interpretKeyEvents:[NSArray arrayWithObject:keyEvent]]; + [self setSearchString:[fieldEditor string]]; if ([dataSource respondsToSelector:@selector(typeSelectHelper:updateSearchString:)]) [dataSource typeSelectHelper:self updateSearchString:searchString]; @@ -158,18 +172,45 @@ processing = NO; } -- (BOOL)isTypeSelectCharacter:(unichar)character { - if ([[NSCharacterSet alphanumericCharacterSet] characterIsMember:character]) - return YES; - if ([self isProcessing] && [[NSCharacterSet controlCharacterSet] characterIsMember:character] == NO) - return YES; - return NO; +- (void)stopSearch { + if (timer) + [self typeSelectCleanTimeout:timer]; } -- (BOOL)isRepeatCharacter:(unichar)character { - return [self cyclesSimilarResults] && character == REPEAT_CHARACTER; +- (BOOL)isTypeSelectEvent:(NSEvent *)keyEvent { + if ([keyEvent type] != NSKeyDown) + return NO; + if ([keyEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask & ~NSShiftKeyMask & ~NSAlternateKeyMask) + return NO; + + NSString *characters = [keyEvent charactersIgnoringModifiers]; + int i, count = [characters length]; + unichar character; + + if (count == 0) + return NO; + + for (i = 0; i < count; i++) { + character = [characters characterAtIndex:i]; + if ([[NSCharacterSet alphanumericCharacterSet] characterIsMember:character]) + continue; + if ([self isProcessing] && [[NSCharacterSet controlCharacterSet] characterIsMember:character]) + continue; + } + return YES; } +- (BOOL)isRepeatEvent:(NSEvent *)keyEvent { + if ([keyEvent type] != NSKeyDown) + return NO; + + NSString *characters = [keyEvent charactersIgnoringModifiers]; + unichar character = [characters length] > 0 ? [characters characterAtIndex:0] : 0; + unsigned modifierFlags = [keyEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask; + + return modifierFlags == 0 && character == REPEAT_CHARACTER; +} + @end #pragma mark - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-05 12:51:40
|
Revision: 2833 http://skim-app.svn.sourceforge.net/skim-app/?rev=2833&view=rev Author: hofman Date: 2007-09-05 05:51:37 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Show a different message when type-select fails. Modified Paths: -------------- trunk/SKBookmarkController.m trunk/SKMainWindowController.m trunk/SKTypeSelectHelper.h trunk/SKTypeSelectHelper.m Modified: trunk/SKBookmarkController.m =================================================================== --- trunk/SKBookmarkController.m 2007-09-05 08:57:31 UTC (rev 2832) +++ trunk/SKBookmarkController.m 2007-09-05 12:51:37 UTC (rev 2833) @@ -372,6 +372,10 @@ [tableView scrollRowToVisible:itemIndex]; } +- (void)typeSelectHelper:(SKTypeSelectHelper *)typeSelectHelper didFailToFindMatchForSearchString:(NSString *)searchString { + [statusBar setLeftStringValue:[NSString stringWithFormat:NSLocalizedString(@"No match: \"%@\"", @"Status message"), searchString]]; +} + - (void)typeSelectHelper:(SKTypeSelectHelper *)typeSelectHelper updateSearchString:(NSString *)searchString { NSString *message = @""; if (searchString) Modified: trunk/SKMainWindowController.m =================================================================== --- trunk/SKMainWindowController.m 2007-09-05 08:57:31 UTC (rev 2832) +++ trunk/SKMainWindowController.m 2007-09-05 12:51:37 UTC (rev 2833) @@ -3684,6 +3684,16 @@ } } +- (void)typeSelectHelper:(SKTypeSelectHelper *)typeSelectHelper didFailToFindMatchForSearchString:(NSString *)searchString { + if ([typeSelectHelper isEqual:[thumbnailTableView typeSelectHelper]] || [typeSelectHelper isEqual:[pdfView typeSelectHelper]]) { + [statusBar setLeftStringValue:[NSString stringWithFormat:NSLocalizedString(@"No match: %@", @"Status message"), searchString]]; + } else if ([typeSelectHelper isEqual:[noteOutlineView typeSelectHelper]]) { + [statusBar setRightStringValue:[NSString stringWithFormat:NSLocalizedString(@"No match: \"%@\"", @"Status message"), searchString]]; + } else if ([typeSelectHelper isEqual:[outlineView typeSelectHelper]]) { + [statusBar setLeftStringValue:[NSString stringWithFormat:NSLocalizedString(@"No match: \"%@\"", @"Status message"), searchString]]; + } +} + - (void)typeSelectHelper:(SKTypeSelectHelper *)typeSelectHelper updateSearchString:(NSString *)searchString { if ([typeSelectHelper isEqual:[thumbnailTableView typeSelectHelper]] || [typeSelectHelper isEqual:[pdfView typeSelectHelper]]) { if (searchString) Modified: trunk/SKTypeSelectHelper.h =================================================================== --- trunk/SKTypeSelectHelper.h 2007-09-05 08:57:31 UTC (rev 2832) +++ trunk/SKTypeSelectHelper.h 2007-09-05 12:51:37 UTC (rev 2833) @@ -88,6 +88,7 @@ - (unsigned int)typeSelectHelperCurrentlySelectedIndex:(SKTypeSelectHelper *)typeSelectHelper; // required - (void)typeSelectHelper:(SKTypeSelectHelper *)typeSelectHelper selectItemAtIndex:(unsigned int)itemIndex; // required +- (void)typeSelectHelper:(SKTypeSelectHelper *)typeSelectHelper didFailToFindMatchForSearchString:(NSString *)searchString; // optional - (void)typeSelectHelper:(SKTypeSelectHelper *)typeSelectHelper updateSearchString:(NSString *)searchString; // optional @end Modified: trunk/SKTypeSelectHelper.m =================================================================== --- trunk/SKTypeSelectHelper.m 2007-09-05 08:57:31 UTC (rev 2832) +++ trunk/SKTypeSelectHelper.m 2007-09-05 12:51:37 UTC (rev 2833) @@ -234,9 +234,13 @@ foundIndex = [self indexOfMatchedItemAfterIndex:startIndex]; - // Avoid flashing a selection all over the place while you're still typing the thing you have selected - if (foundIndex != NSNotFound && foundIndex != selectedIndex) + if (foundIndex == NSNotFound) { + if ([dataSource respondsToSelector:@selector(typeSelectHelper:didFailToFindMatchForSearchString:)]) + [dataSource typeSelectHelper:self didFailToFindMatchForSearchString:searchString]; + } else if (foundIndex != selectedIndex) { + // Avoid flashing a selection all over the place while you're still typing the thing you have selected [dataSource typeSelectHelper:self selectItemAtIndex:foundIndex]; + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-05 08:57:38
|
Revision: 2832 http://skim-app.svn.sourceforge.net/skim-app/?rev=2832&view=rev Author: hofman Date: 2007-09-05 01:57:31 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Remove unzipped disk image before unzipping. This ensures that the disk image is up to date. Modified Paths: -------------- trunk/Skim.xcodeproj/project.pbxproj Modified: trunk/Skim.xcodeproj/project.pbxproj =================================================================== --- trunk/Skim.xcodeproj/project.pbxproj 2007-09-04 20:50:18 UTC (rev 2831) +++ trunk/Skim.xcodeproj/project.pbxproj 2007-09-05 08:57:31 UTC (rev 2832) @@ -1329,7 +1329,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/rm -f /tmp/Skim.dmg\n/usr/bin/unzip ${SOURCE_ROOT}/Skim.dmg.zip\n/bin/cp ${SOURCE_ROOT}/Skim.dmg /tmp\n/usr/bin/hdiutil attach /tmp/Skim.dmg\n${SYSTEM_DEVELOPER_TOOLS}/CpMac -r ${BUILT_PRODUCTS_DIR}/Skim.app /Volumes/Skim\n/usr/bin/osascript -e \"tell application \\\"Finder\\\" to set the position of application file \\\"Skim.app\\\" of disk named \\\"Skim\\\" to {90, 206}\" && \\\nsleep 7; \\\n/usr/sbin/diskutil eject /Volumes/Skim\n/usr/bin/hdiutil resize -size `/usr/bin/hdiutil resize /tmp/Skim.dmg | cut -f -1 -d \" \" -`b /tmp/Skim.dmg\n/usr/bin/hdiutil convert /tmp/Skim.dmg -format UDZO -imagekey zlib-level=9 -o $HOME/Desktop/Skim.dmg\n/usr/bin/hdiutil internet-enable -YES $HOME/Desktop/Skim.dmg\nexit 0"; + shellScript = "/bin/rm -f /tmp/Skim.dmg\n/bin/rm -f ${SOURCE_ROOT}/Skim.dmg.zip\n/usr/bin/unzip ${SOURCE_ROOT}/Skim.dmg.zip\n/bin/cp ${SOURCE_ROOT}/Skim.dmg /tmp\n/usr/bin/hdiutil attach /tmp/Skim.dmg\n${SYSTEM_DEVELOPER_TOOLS}/CpMac -r ${BUILT_PRODUCTS_DIR}/Skim.app /Volumes/Skim\n/usr/bin/osascript -e \"tell application \\\"Finder\\\" to set the position of application file \\\"Skim.app\\\" of disk named \\\"Skim\\\" to {90, 206}\" && \\\nsleep 7; \\\n/usr/sbin/diskutil eject /Volumes/Skim\n/usr/bin/hdiutil resize -size `/usr/bin/hdiutil resize /tmp/Skim.dmg | cut -f -1 -d \" \" -`b /tmp/Skim.dmg\n/usr/bin/hdiutil convert /tmp/Skim.dmg -format UDZO -imagekey zlib-level=9 -o $HOME/Desktop/Skim.dmg\n/usr/bin/hdiutil internet-enable -YES $HOME/Desktop/Skim.dmg\nexit 0"; }; CEE1383C0BCEA63F00BF2D3E /* ShellScript */ = { isa = PBXShellScriptBuildPhase; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |