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>
+
+
[EMAIL PROTECTED] SKFDFParser : NSObject
++ (NSArray *)notesDictionariesFromFDFString:(NSString *)string;
++ (NSDictionary *)fdfObjectsFromFDFString:(NSString *)string;
[EMAIL PROTECTED]
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"
+
[EMAIL PROTECTED] 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;
[EMAIL PROTECTED]
+
+#pragma mark -
+
[EMAIL PROTECTED] 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;
[EMAIL PROTECTED]
+
+#pragma mark -
+
[EMAIL PROTECTED] 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;
+}
+
[EMAIL PROTECTED]
+
+#pragma mark -
+
[EMAIL PROTECTED] 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;
+}
+
[EMAIL PROTECTED]
+
+#pragma mark -
+
[EMAIL PROTECTED] 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;
+}
+
[EMAIL PROTECTED]
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:@"/[EMAIL PROTECTED]", [[[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.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit