2009-11-10 16:48:42 +01:00
//
// QuietUnrarAppDelegate . m
// QuietUnrar
//
// Created by Robert McGovern on 2009 / 09 / 06.
// Copyright 2009 Tarasis . All rights reserved .
//
# import < Carbon / Carbon . h >
# import "QuietUnrarAppDelegate.h"
# import "libunrar/dll.hpp"
2009-11-15 15:43:54 +01:00
QuietUnrarAppDelegate * quietUnrar ;
2009-11-15 00:18:58 +01:00
int changeVolume ( char * volumeName , int mode ) ;
int callbackFunction ( UINT message , LPARAM userData , LPARAM parameterOne , LPARAM parameterTwo ) ;
int changeVolume ( char * volumeName , int mode ) {
NSLog ( @ "Volume Name: %s and mode %d" , volumeName , mode ) ;
2009-11-15 15:43:54 +01:00
if ( mode = = RAR_VOL _ASK )
{
[ ( QuietUnrarAppDelegate * ) quietUnrar alertUserOfMissing : volumeName ] ;
}
2009-11-15 00:18:58 +01:00
}
int callbackFunction ( UINT message , LPARAM userData , LPARAM parameterOne , LPARAM parameterTwo ) {
NSLog ( @ "Callback Function, args: %d, %D, %D, %D" , message , userData , parameterOne , parameterTwo ) ;
}
2009-11-10 16:48:42 +01:00
@ implementation QuietUnrarAppDelegate
@ synthesize window ;
2009-11-14 23:12:16 +01:00
- ( void ) applicationWillFinishLaunching : ( NSNotification * ) notification {
2009-11-10 16:48:42 +01:00
KeyMap map ;
GetKeys ( map ) ;
2009-11-15 13:54:07 +01:00
NSLog ( @ "Shift or Right Shift: %d" , KEYMAP_GET ( map , kVKC_Shift ) || KEYMAP_GET ( map , kVKC_rShift ) ) ;
2009-11-10 16:48:42 +01:00
}
2009-11-14 23:12:16 +01:00
- ( void ) applicationDidFinishLaunching : ( NSNotification * ) aNotification {
2009-11-15 13:54:07 +01:00
// Having extracted our file or not , quit . Though should not if error is displayed .
[ [ NSApplication sharedApplication ] terminate : self ] ;
2009-11-10 16:48:42 +01:00
}
2009-11-14 23:12:16 +01:00
// - ( BOOL ) application : ( id ) sender openFileWithoutUI : ( NSString * ) filename {
// NSLog ( @ "openFileWithoutUI with file: %@" , filename ) ;
// return YES ;
// }
2009-11-10 16:48:42 +01:00
- ( BOOL ) application : ( NSApplication * ) theApplication openFile : ( NSString * ) filename {
NSLog ( @ "openFile: %@" , filename ) ;
2009-11-14 23:12:16 +01:00
2009-11-15 15:43:54 +01:00
[ self extractRarWith : filename ] ;
// Always return YES even if there is an error to avoid dialog indicating unable to
// handle files of type RAR if the archive is corrupt or part of it is missing
return YES ;
2009-11-10 16:48:42 +01:00
}
// - ( void ) application : ( NSApplication * ) sender openFiles : ( NSArray * ) filenames {
// for ( NSString * filename in filenames ) {
// NSLog ( @ "openFiles: %@" , filename ) ;
// }
//
// // If we get passed files don ' t open the UI
// [ sender replyToOpenOrPrint : NSApplicationDelegateReplySuccess ] ;
// }
2009-11-14 23:12:16 +01:00
- ( BOOL ) extractRarWith : ( NSString * ) filename {
2009-11-15 15:43:54 +01:00
quietUnrar = ( void * ) self ;
2009-11-14 23:12:16 +01:00
char commentBuffer [ BUF_LEN ] ;
BOOL extractionSuccessful = YES ;
// Determine the folder we should extract the archive to . This by default
// is the < folderContainingTheArchive > / < archiveNameWithPathExtension >
NSString * defaultFolderToExtractTo = [ filename stringByDeletingPathExtension ] ;
2009-11-15 00:18:58 +01:00
char * filenameCString = ( char * ) [ filename cStringUsingEncoding : NSISOLatin1StringEncoding ] ;
2009-11-14 23:12:16 +01:00
// Open the Archive for extraction , we set the open result to 3 so we can see it has changed
2009-11-15 00:18:58 +01:00
struct RAROpenArchiveData arcData = { filenameCString , RAR_OM _EXTRACT , 3 , & commentBuffer [ 0 ] , BUF_LEN , 0 , 0 } ;
2009-11-14 23:12:16 +01:00
HANDLE archive = RAROpenArchive ( & arcData ) ;
2009-11-15 00:18:58 +01:00
NSLog ( @ "Opening Archive %s with result %d" , filenameCString , arcData . OpenResult ) ;
2009-11-14 23:12:16 +01:00
// set call backs for if password needed or need to change volume
2009-11-15 15:43:54 +01:00
RARSetChangeVolProc ( archive , & changeVolume ) ;
2009-11-15 13:54:07 +01:00
// RARSetCallback ( archive , & callbackFunction , 0 ) ;
2009-11-14 23:12:16 +01:00
2009-11-15 00:18:58 +01:00
//
2009-11-15 13:54:07 +01:00
struct RARHeaderData headerData ;
NSString * lastExtractedFilename = @ "" ;
NSString * currentFilename ;
2009-11-14 23:12:16 +01:00
while ( RARReadHeader ( archive , & headerData ) ! = ERAR_END _ARCHIVE ) {
NSLog ( @ "Attempting to extract %s to %@" , headerData . FileName , defaultFolderToExtractTo ) ;
2009-11-15 13:54:07 +01:00
int processResult = 0 ;
BOOL extractFile = YES ;
currentFilename = [ NSString stringWithCString : ( const char * ) headerData . FileName encoding : NSISOLatin1StringEncoding ] ;
NSFileManager * fileManager = [ NSFileManager defaultManager ] ;
if ( [ fileManager fileExistsAtPath : [ NSString stringWithFormat : @ "%@/%s" , defaultFolderToExtractTo , headerData . FileName ] ] ) {
// If we have already processed the file once and the user has told us to skip
// don ' t ask them again , even though we ' ve changed volumes . Otherwise
// ask the user what to do .
if ( [ lastExtractedFilename isEqualToString : currentFilename ] || ! [ self shouldFileBeReplaced : currentFilename ] ) {
extractFile = NO ;
}
}
// NSLog ( @ "Last filename %@, currentFilename %@, equality %d" , lastExtractedFilename , currentFilename , [ lastExtractedFilename isEqualToString : currentFilename ] ) ;
if ( extractFile ) {
NSLog ( @ "...Extracting" ) ;
processResult = RARProcessFile ( archive , RAR_EXTRACT , ( char * ) [ defaultFolderToExtractTo cStringUsingEncoding : NSISOLatin1StringEncoding ] , NULL ) ;
} else {
NSLog ( @ "...Skipping as already exists" ) ;
processResult = RARProcessFile ( archive , RAR_SKIP , NULL , NULL ) ;
// Curious behavior by the lib , you have SKIP a file number of times ( 4 in my test example ) before
// it is skipped . However if you extract it is only processed once .
}
2009-11-14 23:12:16 +01:00
2009-11-15 00:18:58 +01:00
if ( processResult ! = 0 ) {
2009-11-15 13:54:07 +01:00
NSLog ( @ "Error: Process Result was %d" , processResult ) ;
2009-11-14 23:12:16 +01:00
extractionSuccessful = NO ;
2009-11-15 13:54:07 +01:00
break ;
2009-11-14 23:12:16 +01:00
// DISPLAY ERROR DIALOG , ALERT THE USER
}
2009-11-15 13:54:07 +01:00
lastExtractedFilename = currentFilename ;
2009-11-14 23:12:16 +01:00
}
2009-11-15 00:18:58 +01:00
int closeResult = RARCloseArchive ( archive ) ;
NSLog ( @ "Closing Archive %s with result %d" , filenameCString , closeResult ) ;
2009-11-14 23:12:16 +01:00
return extractionSuccessful ;
}
2009-11-15 13:54:07 +01:00
- ( BOOL ) shouldFileBeReplaced : ( NSString * ) filename {
BOOL result = NO ;
NSAlert * alert = [ [ NSAlert alloc ] init ] ;
[ alert addButtonWithTitle : @ "Overwrite" ] ;
2009-11-15 15:54:55 +01:00
NSButton * skipButton = [ alert addButtonWithTitle : @ "Skip" ] ;
[ skipButton setKeyEquivalent : @ "\e" ] ;
2009-11-15 13:54:07 +01:00
[ alert setMessageText : [ NSString stringWithFormat : @ "Overwrite %@?" , filename ] ] ;
[ alert setInformativeText : [ NSString stringWithFormat : @ "The file already exists. Do you wish to extract it again, overwriting the original file?" , filename ] ] ;
[ alert setAlertStyle : NSWarningAlertStyle ] ;
if ( [ alert runModal ] = = NSAlertFirstButtonReturn ) {
result = YES ;
}
[ alert release ] ;
return result ;
}
2009-11-15 15:43:54 +01:00
- ( void ) alertUserOfMissing : ( const char * ) volume {
NSLog ( @ "Alerting user of missing volume" ) ;
NSAlert * alert = [ [ NSAlert alloc ] init ] ;
[ alert addButtonWithTitle : @ "OK" ] ;
[ alert setMessageText : [ NSString stringWithFormat : @ "Archive part %s is missing." , volume ] ] ;
[ alert setInformativeText : @ "Unable to extract all files from RAR archive as part of it is missing" ] ;
[ alert setAlertStyle : NSCriticalAlertStyle ] ;
[ alert runModal ] ;
[ alert release ] ;
}
2009-11-10 16:48:42 +01:00
@ end