Revision: 3910
          http://skim-app.svn.sourceforge.net/skim-app/?rev=3910&view=rev
Author:   hofman
Date:     2008-05-23 08:25:11 -0700 (Fri, 23 May 2008)

Log Message:
-----------
Allow adding custom export types using templates. Any file added to a Templates 
folder in app support is interpreted as a custom export type, with name and 
export type derived from the file name.

Modified Paths:
--------------
    trunk/SKApplicationController.h
    trunk/SKApplicationController.m
    trunk/SKDocumentController.h
    trunk/SKDocumentController.m
    trunk/SKNotesDocument.h
    trunk/SKNotesDocument.m
    trunk/SKPDFDocument.h
    trunk/SKPDFDocument.m

Modified: trunk/SKApplicationController.h
===================================================================
--- trunk/SKApplicationController.h     2008-05-22 18:41:30 UTC (rev 3909)
+++ trunk/SKApplicationController.h     2008-05-23 15:25:11 UTC (rev 3910)
@@ -71,6 +71,7 @@
 
 - (NSString *)applicationSupportPathForDomain:(int)domain create:(BOOL)create;
 - (NSString *)pathForApplicationSupportFile:(NSString *)file ofType:(NSString 
*)extension;
+- (NSString *)pathForApplicationSupportFile:(NSString *)file ofType:(NSString 
*)extension inDirectory:(NSString *)subpath;
 
 - (NSDictionary *)defaultPdfViewSettings;
 - (void)setDefaultPdfViewSettings:(NSDictionary *)settings;

Modified: trunk/SKApplicationController.m
===================================================================
--- trunk/SKApplicationController.m     2008-05-22 18:41:30 UTC (rev 3909)
+++ trunk/SKApplicationController.m     2008-05-23 15:25:11 UTC (rev 3910)
@@ -500,6 +500,10 @@
 }
 
 - (NSString *)pathForApplicationSupportFile:(NSString *)file ofType:(NSString 
*)extension {
+    return [self pathForApplicationSupportFile:file ofType:extension 
inDirectory:nil];
+}
+
+- (NSString *)pathForApplicationSupportFile:(NSString *)file ofType:(NSString 
*)extension inDirectory:(NSString *)subpath {
     NSFileManager *fm = [NSFileManager defaultManager];
     NSString *filename = [file stringByAppendingPathExtension:extension];
     NSString *fullPath = nil;
@@ -509,13 +513,18 @@
     
     for (i = 0; fullPath == nil && i < 3; i++) {
         if (appSupportPath = [self applicationSupportPathForDomain:domains[i] 
create:NO]) {
+            if (subpath)
+                fullPath = [fullPath stringByAppendingPathComponent:subpath];
             fullPath = [appSupportPath 
stringByAppendingPathComponent:filename];
             if ([fm fileExistsAtPath:fullPath] == NO)
                 fullPath = nil;
         }
     }
     if (fullPath == nil) {
-        fullPath = [[[NSBundle mainBundle] sharedSupportPath] 
stringByAppendingPathComponent:filename];
+        fullPath = [[NSBundle mainBundle] sharedSupportPath];
+        if (subpath)
+            fullPath = [fullPath stringByAppendingPathComponent:subpath];
+        fullPath = [fullPath stringByAppendingPathComponent:filename];
         if ([fm fileExistsAtPath:fullPath] == NO)
             fullPath = nil;
     }

Modified: trunk/SKDocumentController.h
===================================================================
--- trunk/SKDocumentController.h        2008-05-22 18:41:30 UTC (rev 3909)
+++ trunk/SKDocumentController.h        2008-05-23 15:25:11 UTC (rev 3910)
@@ -66,9 +66,16 @@
 extern NSString *SKPostScriptDocumentType;
 extern NSString *SKDVIDocumentType;
 
[EMAIL PROTECTED] SKDocumentController : NSDocumentController
[EMAIL PROTECTED] SKDocumentController : NSDocumentController {
+    NSArray *customExportTemplateFiles;
+}
+
 - (void)newDocumentFromClipboard:(id)sender;
 - (id)openDocumentWithContentsOfPasteboard:(NSPasteboard *)pboard 
error:(NSError **)outError;
 - (id)openDocumentWithImageFromPasteboard:(NSPasteboard *)pboard 
error:(NSError **)outError;
 - (id)openDocumentWithURLFromPasteboard:(NSPasteboard *)pboard error:(NSError 
**)outError;
+
+- (void)resetCustomExportTemplateFiles;
+- (NSArray *)customExportTemplateFiles;
+
 @end

Modified: trunk/SKDocumentController.m
===================================================================
--- trunk/SKDocumentController.m        2008-05-22 18:41:30 UTC (rev 3909)
+++ trunk/SKDocumentController.m        2008-05-23 15:25:11 UTC (rev 3910)
@@ -43,6 +43,7 @@
 #import "NSURL_SKExtensions.h"
 #import "SKStringConstants.h"
 #import "SKUtilities.h"
+#import "SKApplicationController.h"
 
 // See CFBundleTypeName in Info.plist
 static NSString *SKPDFDocumentTypeName = nil; /* set to NSPDFPboardType, not 
@"NSPDFPboardType" */
@@ -182,6 +183,11 @@
     }
 }
 
+- (void)dealloc {
+    [customExportTemplateFiles release];
+    [super dealloc];
+}
+
 - (NSString *)typeFromFileExtension:(NSString *)fileExtensionOrHFSFileType {
        NSString *type = [super 
typeFromFileExtension:fileExtensionOrHFSFileType];
     if (SKIsEmbeddedPDFDocumentType(type) || SKIsBarePDFDocumentType(type)) {
@@ -356,4 +362,55 @@
         return YES;
 }
 
+- (NSArray *)customExportTemplateFiles {
+    if (customExportTemplateFiles == nil) {
+        NSFileManager *fm = [NSFileManager defaultManager];
+        NSMutableSet *templateNames = [NSMutableSet 
setWithObjects:@"notesTemplate.txt", @"notesTemplate.rtf", 
@"notesTemplate.rtfd", nil];
+        NSMutableArray *templateFiles = [NSMutableArray array];
+        int domains[3] = {kUserDomain, kLocalDomain, kNetworkDomain};
+        int i;
+        for (i = 0; i < 3; i++) {
+            NSString *templatesPath = [[[NSApp delegate] 
applicationSupportPathForDomain:domains[i] create:NO] 
stringByAppendingPathComponent:@"Templates"];
+            BOOL isDir;
+            if ([fm fileExistsAtPath:templatesPath isDirectory:&isDir] && 
isDir) {
+                NSEnumerator *fileEnum = [[fm subpathsAtPath:templatesPath] 
objectEnumerator];
+                NSString *file;
+                while (file = [fileEnum nextObject]) {
+                    if ([file hasPrefix:@"."] == NO && [templateNames 
containsObject:file] == NO) {
+                        [templateFiles addObject:[templatesPath 
stringByAppendingPathComponent:file]];
+                        [templateFiles addObject:file];
+                    }
+                }
+            }
+        }
+        customExportTemplateFiles = [templateFiles copy];
+    }
+    return customExportTemplateFiles;
+}
+
+- (void)resetCustomExportTemplateFiles {
+    [customExportTemplateFiles release];
+    customExportTemplateFiles = nil;
+}
+
+- (NSArray *)fileExtensionsFromType:(NSString *)documentTypeName {
+    NSArray *fileExtensions = [super fileExtensionsFromType:documentTypeName];
+    if ([fileExtensions count] == 0) {
+        NSArray *customTemplates = [[self customExportTemplateFiles] 
valueForKey:@"lastPathComponent"];
+        if ([customTemplates containsObject:documentTypeName])
+            fileExtensions = [NSArray arrayWithObjects:[documentTypeName 
pathExtension], nil];
+       }
+       return fileExtensions;
+}
+
+- (NSString *)displayNameForType:(NSString *)documentTypeName{
+    NSString *displayName = nil;
+    NSArray *customTemplates = [[self customExportTemplateFiles] 
valueForKey:@"lastPathComponent"];
+    if ([customTemplates containsObject:documentTypeName])
+        displayName = [[documentTypeName stringByDeletingPathExtension] 
stringByAppendingFormat:@" (%@)", [[documentTypeName pathExtension] 
uppercaseString]];
+    else
+        displayName = [super displayNameForType:documentTypeName];
+    return displayName;
+}
+
 @end

Modified: trunk/SKNotesDocument.h
===================================================================
--- trunk/SKNotesDocument.h     2008-05-22 18:41:30 UTC (rev 3909)
+++ trunk/SKNotesDocument.h     2008-05-23 15:25:11 UTC (rev 3910)
@@ -58,5 +58,6 @@
 
 - (NSString *)notesString;
 - (NSData *)notesRTFData;
+- (NSData *)notesDataUsingTemplateFile:(NSString *)templatePath;
 
 @end

Modified: trunk/SKNotesDocument.m
===================================================================
--- trunk/SKNotesDocument.m     2008-05-22 18:41:30 UTC (rev 3909)
+++ trunk/SKNotesDocument.m     2008-05-23 15:25:11 UTC (rev 3910)
@@ -98,6 +98,32 @@
     [outlineView setTypeSelectHelper:typeSelectHelper];
 }
 
+- (NSArray *)writableTypesForSaveOperation:(NSSaveOperationType)saveOperation {
+    NSMutableArray *writableTypes = [[[super 
writableTypesForSaveOperation:saveOperation] mutableCopy] autorelease];
+    if (saveOperation == NSSaveToOperation) {
+        [[NSDocumentController sharedDocumentController] 
resetCustomExportTemplateFiles];
+        NSEnumerator *fileEnum = [[[NSDocumentController 
sharedDocumentController] customExportTemplateFiles] objectEnumerator];
+        NSString *file;
+        while (file = [fileEnum nextObject]) {
+            if ([[file pathExtension] caseInsensitiveCompare:@"rtfd"] != 
NSOrderedSame)
+                [writableTypes addObject:[file lastPathComponent]];
+        }
+    }
+    return writableTypes;
+}
+
+- (NSString *)fileNameExtensionForType:(NSString *)typeName 
saveOperation:(NSSaveOperationType)saveOperation {
+    // this will never be called on 10.4, so we can safely call super
+    NSString *fileExtension = [super fileNameExtensionForType:typeName 
saveOperation:saveOperation];
+    if (fileExtension == nil) {
+        [[NSDocumentController sharedDocumentController] 
resetCustomExportTemplateFiles];
+        NSArray *customTemplates = [[[NSDocumentController 
sharedDocumentController] customExportTemplateFiles] 
valueForKey:@"lastPathComponent"];
+        if ([customTemplates containsObject:typeName])
+            fileExtension = [typeName pathExtension];
+       }
+    return fileExtension;
+}
+
 - (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
     NSData *data = nil;
     
@@ -117,6 +143,11 @@
         data = [self notesRTFData];
     } else if (SKIsNotesTextDocumentType(typeName)) {
         data = [[self notesString] dataUsingEncoding:NSUTF8StringEncoding];
+    } else {
+        NSArray *customTemplates = [[NSDocumentController 
sharedDocumentController] customExportTemplateFiles];
+        unsigned int idx = [[customTemplates valueForKey:@"lastPathComponent"] 
indexOfObject:typeName];
+        if (idx != NSNotFound)
+            data = [self notesDataUsingTemplateFile:[customTemplates 
objectAtIndex:idx]];
     }
     
     if (data == nil && outError != NULL)
@@ -190,14 +221,14 @@
 }
 
 - (NSString *)notesString {
-    NSString *templatePath = [[NSApp delegate] 
pathForApplicationSupportFile:@"notesTemplate" ofType:@"txt"];
+    NSString *templatePath = [[NSApp delegate] 
pathForApplicationSupportFile:@"notesTemplate" ofType:@"txt" 
inDirectory:@"Templates"];
     NSString *templateString = [[NSString alloc] 
initWithContentsOfFile:templatePath encoding:NSUTF8StringEncoding error:NULL];
     NSString *string = [SKTemplateParser 
stringByParsingTemplate:templateString usingObject:self];
     return string;
 }
 
 - (NSData *)notesRTFData {
-    NSString *templatePath = [[NSApp delegate] 
pathForApplicationSupportFile:@"notesTemplate" ofType:@"rtf"];
+    NSString *templatePath = [[NSApp delegate] 
pathForApplicationSupportFile:@"notesTemplate" ofType:@"rtf" 
inDirectory:@"Templates"];
     NSDictionary *docAttributes = nil;
     NSAttributedString *templateAttrString = [[NSAttributedString alloc] 
initWithPath:templatePath documentAttributes:&docAttributes];
     NSAttributedString *attrString = [SKTemplateParser 
attributedStringByParsingTemplate:templateAttrString usingObject:self];
@@ -206,6 +237,32 @@
     return data;
 }
 
+- (NSData *)notesDataUsingTemplateFile:(NSString *)templatePath {
+    static NSSet *richTextTypes = nil;
+    if (richTextTypes == nil) {
+        if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_4)
+            richTextTypes = [[NSSet alloc] initWithObjects:@"rtf", @"doc", 
@"odt", nil];
+        else
+            richTextTypes = [[NSSet alloc] initWithObjects:@"rtf", @"doc", 
nil];
+    }
+    NSString *fileType = [[templatePath pathExtension] lowercaseString];
+    NSData *data = nil;
+    if ([richTextTypes containsObject:fileType]) {
+        NSDictionary *docAttributes = nil;
+        NSError *error = nil;
+        NSAttributedString *templateAttrString = [[NSAttributedString alloc] 
initWithPath:templatePath documentAttributes:&docAttributes];
+        NSAttributedString *attrString = [SKTemplateParser 
attributedStringByParsingTemplate:templateAttrString usingObject:self];
+        data = [attrString dataFromRange:NSMakeRange(0, [attrString length]) 
documentAttributes:docAttributes error:&error];
+        [templateAttrString release];
+    } else if ([fileType caseInsensitiveCompare:@"rtfd"] != NSOrderedSame) {
+        NSError *error = nil;
+        NSString *templateString = [[NSString alloc] 
initWithContentsOfFile:templatePath encoding:NSUTF8StringEncoding error:&error];
+        NSString *string = [SKTemplateParser 
stringByParsingTemplate:templateString usingObject:self];
+        data = [string dataUsingEncoding:NSUTF8StringEncoding 
allowLossyConversion:NO];
+    }
+    return data;
+}
+
 // these are necessary for the app controller, we may change it there
 - (NSDictionary *)currentDocumentSetup {
     NSMutableDictionary *setup = [NSMutableDictionary dictionary];

Modified: trunk/SKPDFDocument.h
===================================================================
--- trunk/SKPDFDocument.h       2008-05-22 18:41:30 UTC (rev 3909)
+++ trunk/SKPDFDocument.h       2008-05-23 15:25:11 UTC (rev 3910)
@@ -114,6 +114,9 @@
 - (NSString *)notesFDFString;
 - (NSString *)notesFDFStringForFile:(NSString *)filename;
 
+- (NSData *)notesDataUsingTemplateFile:(NSString *)templatePath;
+- (NSFileWrapper *)notesFileWrapperUsingTemplateFile:(NSString *)templatePath;
+
 - (NSArray *)fileIDStrings;
 
 - (void)savePasswordInKeychain:(NSString *)password;

Modified: trunk/SKPDFDocument.m
===================================================================
--- trunk/SKPDFDocument.m       2008-05-22 18:41:30 UTC (rev 3909)
+++ trunk/SKPDFDocument.m       2008-05-23 15:25:11 UTC (rev 3910)
@@ -218,6 +218,27 @@
 
 #pragma mark Document read/write
 
+- (NSArray *)writableTypesForSaveOperation:(NSSaveOperationType)saveOperation {
+    NSMutableArray *writableTypes = [[[super 
writableTypesForSaveOperation:saveOperation] mutableCopy] autorelease];
+    if (saveOperation == NSSaveToOperation) {
+        [[NSDocumentController sharedDocumentController] 
resetCustomExportTemplateFiles];
+        NSArray *customTemplates = [[NSDocumentController 
sharedDocumentController] customExportTemplateFiles];
+        [writableTypes addObjectsFromArray:[customTemplates 
valueForKey:@"lastPathComponent"]];
+    }
+    return writableTypes;
+}
+
+- (NSString *)fileNameExtensionForType:(NSString *)typeName 
saveOperation:(NSSaveOperationType)saveOperation {
+    // this will never be called on 10.4, so we can safely call super
+    NSString *fileExtension = [super fileNameExtensionForType:typeName 
saveOperation:saveOperation];
+    if (fileExtension == nil) {
+        NSArray *customTemplates = [[[NSDocumentController 
sharedDocumentController] customExportTemplateFiles] 
valueForKey:@"lastPathComponent"];
+        if ([customTemplates containsObject:typeName])
+            fileExtension = [typeName pathExtension];
+       }
+    return fileExtension;
+}
+
 - (BOOL)prepareSavePanel:(NSSavePanel *)savePanel {
     if (exportUsingPanel) {
         NSPopUpButton *formatPopup = [[savePanel accessoryView] 
subviewOfClass:[NSPopUpButton class]];
@@ -459,6 +480,24 @@
             didWrite = [string writeToURL:absoluteURL atomically:YES 
encoding:NSISOLatin1StringEncoding error:&error];
         else 
             error = [NSError errorWithDomain:SKDocumentErrorDomain code:1 
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Unable 
to write notes as FDF", @"Error description"), NSLocalizedDescriptionKey, nil]];
+    } else {
+        NSArray *customTemplates = [[NSDocumentController 
sharedDocumentController] customExportTemplateFiles];
+        unsigned int idx = [[customTemplates valueForKey:@"lastPathComponent"] 
indexOfObject:typeName];
+        if (idx != NSNotFound) {
+            if ([[typeName pathExtension] caseInsensitiveCompare:@"rtfd"]) {
+                NSFileWrapper *fileWrapper = [self 
notesFileWrapperUsingTemplateFile:[customTemplates objectAtIndex:idx]];
+                if (fileWrapper)
+                    didWrite = [fileWrapper writeToFile:[absoluteURL path] 
atomically:NO updateFilenames:NO];
+                else
+                    error = [NSError errorWithDomain:SKDocumentErrorDomain 
code:1 userInfo:[NSDictionary 
dictionaryWithObjectsAndKeys:NSLocalizedString(@"Unable to write notes using 
template", @"Error description"), NSLocalizedDescriptionKey, nil]];
+            } else {
+                NSData *data = [self 
notesDataUsingTemplateFile:[customTemplates objectAtIndex:idx]];
+                if (data)
+                    didWrite = [data writeToURL:absoluteURL options:0 
error:&error];
+                else
+                    error = [NSError errorWithDomain:SKDocumentErrorDomain 
code:1 userInfo:[NSDictionary 
dictionaryWithObjectsAndKeys:NSLocalizedString(@"Unable to write notes using 
template", @"Error description"), NSLocalizedDescriptionKey, nil]];
+            }
+        }
     }
     
     if (didWrite == NO && outError != NULL)
@@ -1483,7 +1522,7 @@
 }
 
 - (NSString *)notesString {
-    NSString *templatePath = [[NSApp delegate] 
pathForApplicationSupportFile:@"notesTemplate" ofType:@"txt"];
+    NSString *templatePath = [[NSApp delegate] 
pathForApplicationSupportFile:@"notesTemplate" ofType:@"txt" 
inDirectory:@"Templates"];
     NSStringEncoding encoding = NSUTF8StringEncoding;
     NSError *error = nil;
     NSString *templateString = [[NSString alloc] 
initWithContentsOfFile:templatePath encoding:encoding error:&error];
@@ -1493,7 +1532,7 @@
 }
 
 - (NSData *)notesRTFData {
-    NSString *templatePath = [[NSApp delegate] 
pathForApplicationSupportFile:@"notesTemplate" ofType:@"rtf"];
+    NSString *templatePath = [[NSApp delegate] 
pathForApplicationSupportFile:@"notesTemplate" ofType:@"rtf" 
inDirectory:@"Templates"];
     NSDictionary *docAttributes = nil;
     NSAttributedString *templateAttrString = [[NSAttributedString alloc] 
initWithPath:templatePath documentAttributes:&docAttributes];
     NSAttributedString *attrString = [SKTemplateParser 
attributedStringByParsingTemplate:templateAttrString usingObject:self];
@@ -1503,7 +1542,7 @@
 }
 
 - (NSFileWrapper *)notesRTFDFileWrapper {
-    NSString *templatePath = [[NSApp delegate] 
pathForApplicationSupportFile:@"notesTemplate" ofType:@"rtfd"];
+    NSString *templatePath = [[NSApp delegate] 
pathForApplicationSupportFile:@"notesTemplate" ofType:@"rtfd" 
inDirectory:@"Templates"];
     NSDictionary *docAttributes = nil;
     NSAttributedString *templateAttrString = [[NSAttributedString alloc] 
initWithPath:templatePath documentAttributes:&docAttributes];
     NSAttributedString *attrString = [SKTemplateParser 
attributedStringByParsingTemplate:templateAttrString usingObject:self];
@@ -1512,6 +1551,41 @@
     return fileWrapper;
 }
 
+- (NSData *)notesDataUsingTemplateFile:(NSString *)templatePath {
+    static NSSet *richTextTypes = nil;
+    if (richTextTypes == nil) {
+        if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_4)
+            richTextTypes = [[NSSet alloc] initWithObjects:@"rtf", @"doc", 
@"odt", nil];
+        else
+            richTextTypes = [[NSSet alloc] initWithObjects:@"rtf", @"doc", 
nil];
+    }
+    NSString *fileType = [[templatePath pathExtension] lowercaseString];
+    NSData *data = nil;
+    if ([richTextTypes containsObject:fileType]) {
+        NSDictionary *docAttributes = nil;
+        NSError *error = nil;
+        NSAttributedString *templateAttrString = [[NSAttributedString alloc] 
initWithPath:templatePath documentAttributes:&docAttributes];
+        NSAttributedString *attrString = [SKTemplateParser 
attributedStringByParsingTemplate:templateAttrString usingObject:self];
+        data = [attrString dataFromRange:NSMakeRange(0, [attrString length]) 
documentAttributes:docAttributes error:&error];
+        [templateAttrString release];
+    } else if ([fileType caseInsensitiveCompare:@"rtfd"] != NSOrderedSame) {
+        NSError *error = nil;
+        NSString *templateString = [[NSString alloc] 
initWithContentsOfFile:templatePath encoding:NSUTF8StringEncoding error:&error];
+        NSString *string = [SKTemplateParser 
stringByParsingTemplate:templateString usingObject:self];
+        data = [string dataUsingEncoding:NSUTF8StringEncoding 
allowLossyConversion:NO];
+    }
+    return data;
+}
+
+- (NSFileWrapper *)notesFileWrapperUsingTemplateFile:(NSString *)templatePath {
+    NSDictionary *docAttributes = nil;
+    NSAttributedString *templateAttrString = [[NSAttributedString alloc] 
initWithPath:templatePath documentAttributes:&docAttributes];
+    NSAttributedString *attrString = [SKTemplateParser 
attributedStringByParsingTemplate:templateAttrString usingObject:self];
+    NSFileWrapper *fileWrapper = [attrString 
RTFDFileWrapperFromRange:NSMakeRange(0, [attrString length]) 
documentAttributes:docAttributes];
+    [templateAttrString release];
+    return fileWrapper;
+}
+
 - (NSArray *)fileIDStrings {
     if (pdfData == nil)
         return nil;


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 2008.
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

Reply via email to