Revision: 3833
          http://skim-app.svn.sourceforge.net/skim-app/?rev=3833&view=rev
Author:   hofman
Date:     2008-05-01 10:56:35 -0700 (Thu, 01 May 2008)

Log Message:
-----------
Add actions to send an archived version of the document by email. 

Modified Paths:
--------------
    trunk/English.lproj/MainMenu.nib/classes.nib
    trunk/English.lproj/MainMenu.nib/info.nib
    trunk/English.lproj/MainMenu.nib/keyedobjects.nib
    trunk/Files_SKExtensions.h
    trunk/Files_SKExtensions.m
    trunk/SKPDFDocument.h
    trunk/SKPDFDocument.m

Modified: trunk/English.lproj/MainMenu.nib/classes.nib
===================================================================
--- trunk/English.lproj/MainMenu.nib/classes.nib        2008-04-29 12:57:25 UTC 
(rev 3832)
+++ trunk/English.lproj/MainMenu.nib/classes.nib        2008-05-01 17:56:35 UTC 
(rev 3833)
@@ -41,6 +41,8 @@
                 doZoomToSelection = id;
                 editBookmarks = id;
                 editNote = id;
+                emailArchive = id;
+                emailDiskImage = id;
                 getInfo = id;
                 goToMarkedPage = id;
                 markPage = id;

Modified: trunk/English.lproj/MainMenu.nib/info.nib
===================================================================
--- trunk/English.lproj/MainMenu.nib/info.nib   2008-04-29 12:57:25 UTC (rev 
3832)
+++ trunk/English.lproj/MainMenu.nib/info.nib   2008-05-01 17:56:35 UTC (rev 
3833)
@@ -16,6 +16,6 @@
                <integer>29</integer>
        </array>
        <key>IBSystem Version</key>
-       <string>9C31</string>
+       <string>9C7010</string>
 </dict>
 </plist>

Modified: trunk/English.lproj/MainMenu.nib/keyedobjects.nib
===================================================================
(Binary files differ)

Modified: trunk/Files_SKExtensions.h
===================================================================
--- trunk/Files_SKExtensions.h  2008-04-29 12:57:25 UTC (rev 3832)
+++ trunk/Files_SKExtensions.h  2008-05-01 17:56:35 UTC (rev 3833)
@@ -48,6 +48,7 @@
 extern BOOL SKFileExistsAtPath(NSString *path);
 extern NSDate *SKFileModificationDateAtPath(NSString *path);
 extern NSString *SKUniqueDirectoryCreating(NSString *basePath, BOOL create);
+extern NSString *SKChewableItemsDirectory();
 
 extern OSErr FSDeleteContainerContents(const FSRef *container);
 extern OSErr FSDeleteContainer(const FSRef *container);

Modified: trunk/Files_SKExtensions.m
===================================================================
--- trunk/Files_SKExtensions.m  2008-04-29 12:57:25 UTC (rev 3832)
+++ trunk/Files_SKExtensions.m  2008-05-01 17:56:35 UTC (rev 3833)
@@ -120,6 +120,46 @@
     return success ? [basePath stringByAppendingPathComponent:tmpDirName] : 
nil;
 }
 
+NSString *SKChewableItemsDirectory() {
+    // chewable items are automatically cleaned up at restart, and it's hidden 
from the user
+    static NSString *chewableItemsDirectory = nil;
+    if (chewableItemsDirectory == nil) {
+        FSRef chewableRef;
+        OSErr err = FSFindFolder(kUserDomain, kChewableItemsFolderType, TRUE, 
&chewableRef);
+        
+        CFAllocatorRef alloc = CFAllocatorGetDefault();
+        CFURLRef chewableURL = NULL;
+        if (noErr == err) {
+            chewableURL = CFURLCreateFromFSRef(alloc, &chewableRef);
+            
+            CFStringRef baseName = 
CFStringCreateWithFileSystemRepresentation(alloc, "Skim");
+            CFURLRef newURL = CFURLCreateCopyAppendingPathComponent(alloc, 
chewableURL, baseName, TRUE);
+            FSRef newRef;
+            
+            if (chewableURL) CFRelease(chewableURL);
+            
+            assert(NULL != newURL);
+            
+            if (CFURLGetFSRef(newURL, &newRef) == false) {
+                int nameLength = CFStringGetLength(baseName);
+                UniChar *nameBuf = CFAllocatorAllocate(alloc, nameLength * 
sizeof(UniChar), 0);
+                CFStringGetCharacters(baseName, CFRangeMake(0, nameLength), 
nameBuf);
+                err = FSCreateDirectoryUnicode(&chewableRef, nameLength, 
nameBuf, kFSCatInfoNone, NULL, NULL, NULL, NULL);
+                CFAllocatorDeallocate(alloc, nameBuf);
+            }
+            
+            if (noErr == err)
+                chewableItemsDirectory = (NSString 
*)CFURLCopyFileSystemPath(newURL, kCFURLPOSIXPathStyle);
+            
+            if (newURL) CFRelease(newURL);
+            if (baseName) CFRelease(baseName);
+            
+            assert(nil != chewableItemsDirectory);
+        }
+    }
+    return chewableItemsDirectory;
+}
+
 // These are taken from MoreFilesX
 
 struct FSDeleteContainerGlobals

Modified: trunk/SKPDFDocument.h
===================================================================
--- trunk/SKPDFDocument.h       2008-04-29 12:57:25 UTC (rev 3832)
+++ trunk/SKPDFDocument.h       2008-05-01 17:56:35 UTC (rev 3833)
@@ -94,6 +94,8 @@
 - (IBAction)convertNotes:(id)sender;
 - (IBAction)saveArchive:(id)sender;
 - (IBAction)saveDiskImage:(id)sender;
+- (IBAction)emailArchive:(id)sender;
+- (IBAction)emailDiskImage:(id)sender;
 
 - (BOOL)saveNotesToExtendedAttributesAtURL:(NSURL *)aURL error:(NSError 
**)outError;
 - (BOOL)readNotesFromExtendedAttributesAtURL:(NSURL *)aURL error:(NSError 
**)outError;

Modified: trunk/SKPDFDocument.m
===================================================================
--- trunk/SKPDFDocument.m       2008-04-29 12:57:25 UTC (rev 3832)
+++ trunk/SKPDFDocument.m       2008-05-01 17:56:35 UTC (rev 3833)
@@ -860,14 +860,15 @@
     [alert beginSheetModalForWindow:[self windowForSheet] modalDelegate:self 
didEndSelector:@selector(convertNotesSheetDidEnd:returnCode:contextInfo:) 
contextInfo:NULL];
 }
 
+- (void)saveArchiveToFile:(NSString *)fileName {
+    [NSTask runTaskWithLaunchPath:@"/usr/bin/tar"
+                        arguments:[NSArray arrayWithObjects:@"-czf", fileName, 
[[[self fileURL] path] lastPathComponent], nil]
+             currentDirectoryPath:[[[self fileURL] path] 
stringByDeletingLastPathComponent]];
+}
+
 - (void)archiveSavePanelDidEnd:(NSSavePanel *)sheet returnCode:(int)returnCode 
 contextInfo:(void  *)contextInfo {
-    
-    if (NSOKButton == returnCode && [self fileURL]) {
-                            
-        [NSTask runTaskWithLaunchPath:@"/usr/bin/tar"
-                            arguments:[NSArray arrayWithObjects:@"-czf", 
[sheet filename], [[[self fileURL] path] lastPathComponent], nil]
-                 currentDirectoryPath:[[[self fileURL] path] 
stringByDeletingLastPathComponent]];
-    }
+    if (NSOKButton == returnCode && [self fileURL])
+        [self saveArchiveToFile:[sheet filename]];
 }
 
 - (IBAction)saveArchive:(id)sender {
@@ -888,6 +889,70 @@
     }
 }
 
+- (void)emailAttachmentFile:(NSString *)fileName {
+    NSMutableString *scriptString = nil;
+    
+    NSString *mailAppName = nil;
+    CFURLRef mailAppURL = NULL;
+    OSStatus status = LSGetApplicationForURL((CFURLRef)[NSURL 
URLWithString:@"mailto:";], kLSRolesAll, NULL, &mailAppURL);
+    if (status == noErr)
+        mailAppName = [[[(NSURL *)mailAppURL path] lastPathComponent] 
stringByDeletingPathExtension];
+    
+    if ([mailAppName rangeOfString:@"Entourage" 
options:NSCaseInsensitiveSearch].length) {
+        scriptString = [NSMutableString stringWithString:@"tell application 
\"Microsoft Entourage\"\n"];
+        [scriptString appendString:@"activate\n"];
+        [scriptString appendString:@"set m to make new draft window\n"];
+        [scriptString appendString:@"tell m\n"];
+        [scriptString appendFormat:@"set subject to \"[EMAIL PROTECTED]"\n", 
[self displayName]];
+        [scriptString appendFormat:@"make new attachment at end of attchements 
with properties {file: POSIX file \"[EMAIL PROTECTED]"}\n", fileName];
+        [scriptString appendString:@"end tell\n"];
+        [scriptString appendString:@"end tell\n"];
+    } else if ([mailAppName rangeOfString:@"Mailsmith" 
options:NSCaseInsensitiveSearch].length) {
+        scriptString = [NSMutableString stringWithString:@"tell application 
\"Mailsmith\"\n"];
+        [scriptString appendString:@"activate\n"];
+        [scriptString appendString:@"set m to make new message window\n"];
+        [scriptString appendString:@"tell m\n"];
+        [scriptString appendFormat:@"set subject to \"[EMAIL PROTECTED]"\n", 
[self displayName]];
+        [scriptString appendFormat:@"make new enclosure at end of enclosures 
with properties {file: POSIX file \"[EMAIL PROTECTED]"}\n", fileName];
+        [scriptString appendString:@"end tell\n"];
+        [scriptString appendString:@"end tell\n"];
+    } else {
+        scriptString = [NSMutableString stringWithString:@"tell application 
\"Mail\"\n"];
+        [scriptString appendString:@"activate\n"];
+        [scriptString appendString:@"set m to make new outgoing message at 
beginning of outgoing messages\n"];
+        [scriptString appendString:@"tell m\n"];
+        [scriptString appendFormat:@"set subject to \"[EMAIL PROTECTED]"\n", 
[self displayName]];
+        [scriptString appendString:@"tell content\n"];
+        [scriptString appendFormat:@"make new attachment with properties {file 
name: \"[EMAIL PROTECTED]"} at after last character\n", fileName];
+        [scriptString appendString:@"end tell\n"];
+        [scriptString appendString:@"set visible to true\n"];
+        [scriptString appendString:@"end tell\n"];
+        [scriptString appendString:@"end tell\n"];
+    }
+    
+    if (scriptString) {
+        NSAppleScript *script = [[[NSAppleScript alloc] 
initWithSource:scriptString] autorelease];
+        NSDictionary *errorDict = nil;
+        if ([script compileAndReturnError:&errorDict] == NO)
+            NSLog(@"Error compiling mail to script: %@", errorDict);
+        else if ([script executeAndReturnError:&errorDict] == NO)
+            NSLog(@"Error running mail to script: %@", errorDict);
+    }
+}
+
+- (IBAction)emailArchive:(id)sender {
+    NSString *path = [[self fileURL] path];
+    if (path && [[NSFileManager defaultManager] fileExistsAtPath:path] && 
[self isDocumentEdited] == NO) {
+        NSString *tmpDir = 
SKUniqueDirectoryCreating(SKChewableItemsDirectory(), YES);
+        NSString *tmpFile = [tmpDir stringByAppendingPathComponent:[[[[self 
fileURL] path] lastPathComponent] stringByReplacingPathExtension:@"tgz"]];
+        [self saveArchiveToFile:tmpFile];
+        [self emailAttachmentFile:tmpFile];
+    } else {
+        NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"You 
must save this file first", @"Alert text when trying to create archive for 
unsaved document") defaultButton:nil alternateButton:nil otherButton:nil 
informativeTextWithFormat:NSLocalizedString(@"The document has unsaved changes, 
or has not previously been saved to disk.", @"Informative text in alert 
dialog")];
+        [alert beginSheetModalForWindow:[self windowForSheet] 
modalDelegate:nil didEndSelector:NULL contextInfo:NULL];
+    }
+}
+
 - (void)saveDiskImageWithInfo:(NSDictionary *)info {
     
     NSAutoreleasePool *pool = [NSAutoreleasePool new];
@@ -910,24 +975,26 @@
     
     [[self progressController] performSelectorOnMainThread:@selector(hide) 
withObject:nil waitUntilDone:NO];
     
+    if ([[info objectForKey:@"email"] boolValue])
+        [self performSelectorOnMainThread:@selector(emailAttachmentFile:) 
withObject:targetPath waitUntilDone:NO];
+    
     [pool release];
 }
 
-- (void)diskImageSavePanelDidEnd:(NSSavePanel *)sheet 
returnCode:(int)returnCode  contextInfo:(void  *)contextInfo {
+- (void)saveDiskImageToFile:(NSString *)fileName email:(BOOL)email {
+    [[self progressController] setMessage:[NSLocalizedString(@"Saving Disk 
Image", @"Message for progress sheet") stringByAppendingEllipsis]];
+    [[self progressController] setIndeterminate:YES];
+    [[self progressController] show];
     
-    if (NSOKButton == returnCode && [self fileURL]) {
-        
-        [[self progressController] setMessage:[NSLocalizedString(@"Saving Disk 
Image", @"Message for progress sheet") stringByAppendingEllipsis]];
-        [[self progressController] setIndeterminate:YES];
-        
-        [sheet orderOut:self];
-        [[self progressController] show];
-        
-        NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:[[self 
fileURL] path], @"sourcePath", [sheet filename], @"targetPath", nil];
-        [NSThread detachNewThreadSelector:@selector(saveDiskImageWithInfo:) 
toTarget:self withObject:info];
-    }
+    NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:[[self 
fileURL] path], @"sourcePath", fileName, @"targetPath", [NSNumber 
numberWithBool:email], @"email", nil];
+    [NSThread detachNewThreadSelector:@selector(saveDiskImageWithInfo:) 
toTarget:self withObject:info];
 }
 
+- (void)diskImageSavePanelDidEnd:(NSSavePanel *)sheet 
returnCode:(int)returnCode  contextInfo:(void  *)contextInfo {
+    if (NSOKButton == returnCode && [self fileURL])
+        [self saveDiskImageToFile:[sheet filename] email:NO];
+}
+
 - (IBAction)saveDiskImage:(id)sender {
     NSString *path = [[self fileURL] path];
     if (path && [[NSFileManager defaultManager] fileExistsAtPath:path] && 
[self isDocumentEdited] == NO) {
@@ -946,6 +1013,18 @@
     }
 }
 
+- (IBAction)emailDiskImage:(id)sender {
+    NSString *path = [[self fileURL] path];
+    if (path && [[NSFileManager defaultManager] fileExistsAtPath:path] && 
[self isDocumentEdited] == NO) {
+        NSString *tmpDir = 
SKUniqueDirectoryCreating(SKChewableItemsDirectory(), YES);
+        NSString *tmpFile = [tmpDir stringByAppendingPathComponent:[[[[self 
fileURL] path] lastPathComponent] stringByReplacingPathExtension:@"dmg"]];
+        [self saveDiskImageToFile:tmpFile email:YES];
+    } else {
+        NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"You 
must save this file first", @"Alert text when trying to create archive for 
unsaved document") defaultButton:nil alternateButton:nil otherButton:nil 
informativeTextWithFormat:NSLocalizedString(@"The document has unsaved changes, 
or has not previously been saved to disk.", @"Informative text in alert 
dialog")];
+        [alert beginSheetModalForWindow:[self windowForSheet] 
modalDelegate:nil didEndSelector:NULL contextInfo:NULL];
+    }
+}
+
 - (void)revertAlertDidEnd:(NSAlert *)alert returnCode:(int)returnCode 
contextInfo:(void *)contextInfo {
     if (returnCode == NSAlertDefaultReturn) {
         NSError *error = nil;
@@ -990,6 +1069,9 @@
         return [[self pdfDocument] allowsPrinting];
     } else if ([anItem action] == @selector(convertNotes:)) {
         return [[self pdfDocument] isLocked] == NO;
+    } else if ([anItem action] == @selector(saveArchive:) || [anItem action] 
== @selector(saveDiskImage:) || [anItem action] == @selector(emailArchive:) || 
[anItem action] == @selector(emailDiskImage:)) {
+        NSString *path = [[self fileURL] path];
+        return path && [[NSFileManager defaultManager] fileExistsAtPath:path] 
&& [self isDocumentEdited] == NO;
     }
     return [super validateUserInterfaceItem:anItem];
 }


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 the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit

Reply via email to