/*
Copyright (C) 2002-2003, Matt Joss.
The authors make NO WARRANTY or representation, either express or implied,
with respect to this software, its quality, accuracy, merchantability, or
fitness for a particular purpose. This software is provided "AS IS", and you,
its user, assume the entire risk as to its quality and accuracy.
Permission is hereby granted to use, copy, modify, and distribute this
software or portions thereof for any purpose, without fee, subject to these
conditions:
(1) If any part of the source code is distributed, then this
statement must be included, with this copyright and no-warranty notice
unaltered.
(2) Permission for use of this software is granted only if the user accepts
full responsibility for any undesirable consequences; the authors accept
NO LIABILITY for damages of any kind.
*/
#import "TransferController.h"
#import "PerforceClient.h"
#import "PerforceAction.h"
#import "PerforceChangeFile.h"
#import <CoreServices/CoreServices.h>
#import <string>
#import <fstream>
@implementation TransferController
- (BOOL) setFileLockStatus:(NSString*)filePath isLocked:(BOOL)locked
{
OSStatus status;
OSErr err;
FSRef pathRef;
FSSpec fileSpec;
// Now relock the file we just moved
status = FSPathMakeRef((UInt8*)[filePath cString], &pathRef, nil);
if (status != noErr)
NSLog(@"Couldn't make FSRef in Carbon for:%@, err = %d", filePath, status);
// convert FSRef to FSSpec for use in lock call
err = FSGetCatalogInfo ( &pathRef, NULL, NULL, NULL, &fileSpec, NULL);
if (err != noErr)
NSLog(@"Couldn't convert FSRef to FSSpec in Carbon for:%@, err = %d", filePath, err);
if (locked)
err = FSpSetFLock(&fileSpec);
else
err = FSpRstFLock(&fileSpec);
if (err != noErr)
{
NSLog(@"Couldn't %@ %@, err = %d", (locked == YES ? @"lock" : @"unlock"), filePath, err);
return NO;
}
return YES;
}
- (IBAction)transferFromMacToPC:(id)sender
{
return; // for now 11/7/2002
NSString* firstOpenedFile;
PerforceClient* client;
NSArray* fileTypes;
NSOpenPanel* openPanel;
NSString* depotBasePath;
NSString* pcBasePath;
int i;
unsigned int openedPos, chosenPos;
NSString *chosenFile;
NSString *lcChosenFile;
NSArray* openedFiles = nil;//[[PerforceAction defaultAction] opened:0];
//if ([openedFiles count] <= 0)
//return;
firstOpenedFile = [[[openedFiles objectAtIndex:[openedFiles count] - 1] depotFileName] lowercaseString];
client = [[PerforceAction defaultAction] clientInfo:nil];
fileTypes = [NSArray arrayWithObject:[firstOpenedFile pathExtension]];
openPanel = [NSOpenPanel openPanel];
[openPanel setAllowsMultipleSelection:NO];
[openPanel setCanChooseDirectories:NO];
[openPanel setTitle:[NSString stringWithFormat:@"Find %@", firstOpenedFile] ];
[openPanel runModalForDirectory:@"/" file:nil types:fileTypes];
// Make the user pick the one of the checked out files from the PC path
if ([[openPanel filenames] count] == 1)
{
BOOL found = NO;
chosenFile = [[openPanel filenames] objectAtIndex:0];
lcChosenFile = [chosenFile lowercaseString];
chosenPos = [chosenFile length];
openedPos = [firstOpenedFile length];
while (chosenPos > 0 && openedPos > 0 && !found)
{
unichar openChar = [firstOpenedFile characterAtIndex:openedPos - 1];
unichar chosenChar = [lcChosenFile characterAtIndex:chosenPos - 1];
if (openChar != chosenChar)
found = YES;
else
{
chosenPos--;
openedPos--;
}
}
depotBasePath = [firstOpenedFile substringToIndex:openedPos];
pcBasePath = [chosenFile substringToIndex:chosenPos];
for (i = 0; i < [openedFiles count]; i++)
{
NSString* openedFile = [[openedFiles objectAtIndex:i] depotFileName];
NSRange endingPathRange = NSMakeRange([depotBasePath length],[openedFile length] - [depotBasePath length]);
NSString* pcFilePath = [NSString stringWithFormat:@"%@%@", pcBasePath, [openedFile substringWithRange:endingPathRange]];
NSString* macFilePath = [[openedFiles objectAtIndex:i] clientFileName];
// NSLog(@"Copy %@ to %@", macFilePath, pcFilePath);
// NSArray* extensionArray = [NSArray arrayWithObjects:@"cpp", @"h", @"fr", @"fh"];
// NSString* extension = [macFilePath pathExtension];
// if ([extensionArray indexOfObject:extension] >= 0)
if ( ![[macFilePath pathExtension] isEqual:@"mcp"])
{
[self copyTextFile:macFilePath toPath:pcFilePath];
} else
{
// NSFileManager* fileMgr = [NSFileManager defaultManager];
// [fileMgr removeFileAtPath:pcFilePath handler:nil];
// [fileMgr copyPath:macFilePath toPath:pcFilePath handler:nil];
}
}
}
}
- (IBAction)transferFromPCToMac:(id)sender
{
return; // for now 11/7/2002
NSString* firstOpenedFile;
PerforceClient* client;
NSArray* fileTypes;
NSOpenPanel* openPanel;
NSString* depotBasePath;
NSString* pcBasePath;
int i;
unsigned int openedPos, chosenPos;
NSString *chosenFile;
NSString *lcChosenFile;
PerforceAction* p4 = [PerforceAction actionWithClient:@"mjosspc" withUser:nil];
NSArray* openedFiles = nil;//[p4 opened:YES];
//if ([openedFiles count] <= 0)
//return;
firstOpenedFile = [[[openedFiles objectAtIndex:[openedFiles count] - 1] depotFileName] lowercaseString];
client = [[PerforceAction defaultAction] clientInfo:nil];
fileTypes = [NSArray arrayWithObject:[firstOpenedFile pathExtension]];
openPanel = [NSOpenPanel openPanel];
[openPanel setAllowsMultipleSelection:NO];
[openPanel setCanChooseDirectories:NO];
[openPanel setTitle:[NSString stringWithFormat:@"Find %@", firstOpenedFile] ];
[openPanel runModalForDirectory:@"/" file:nil types:fileTypes];
// Make the user pick the one of the checked out files from the PC path
if ([[openPanel filenames] count] == 1)
{
// Parse thru the depot file name and the name of the file chosen on PC volume to determine
// the base paths(Point up to where the paths are different)
BOOL found = NO;
chosenFile = [[openPanel filenames] objectAtIndex:0];
lcChosenFile = [chosenFile lowercaseString];
chosenPos = [chosenFile length];
openedPos = [firstOpenedFile length];
while (chosenPos > 0 && openedPos > 0 && !found)
{
unichar openChar = [firstOpenedFile characterAtIndex:openedPos - 1];
unichar chosenChar = [lcChosenFile characterAtIndex:chosenPos - 1];
if (openChar != chosenChar)
found = YES;
else
{
chosenPos--;
openedPos--;
}
}
// We;ve now got the depot base path and the pc volume base path
depotBasePath = [firstOpenedFile substringToIndex:openedPos];
pcBasePath = [chosenFile substringToIndex:chosenPos];
// Go thru the checked out files and copy them to the mac
for (i = 0; i < [openedFiles count]; i++)
{
NSString* openedFile = [[openedFiles objectAtIndex:i] depotFileName];
NSRange endingPathRange = NSMakeRange([depotBasePath length],[openedFile length] - [depotBasePath length]);
NSString* pcFilePath = [NSString stringWithFormat:@"%@%@", pcBasePath, [openedFile substringWithRange:endingPathRange]];
NSString* macFilePath = [[openedFiles objectAtIndex:i] clientFileName];
// NSLog(@"Copy %@ to %@", macFilePath, pcFilePath);
// NSArray* extensionArray = [NSArray arrayWithObjects:@"cpp", @"h", @"fr", @"fh"];
// NSString* extension = [macFilePath pathExtension];
// if ([extensionArray indexOfObject:extension] >= 0)
if ( ![[macFilePath pathExtension] isEqual:@"dsp"])
{
NSLog(@"Copy %@ to %@", pcFilePath, macFilePath);
[self copyTextFile:pcFilePath toPath:macFilePath];
// Now relock the file we just moved
[self setFileLockStatus:macFilePath isLocked:YES];
} else
{
// NSFileManager* fileMgr = [NSFileManager defaultManager];
// [fileMgr removeFileAtPath:pcFilePath handler:nil];
// [fileMgr copyPath:macFilePath toPath:pcFilePath handler:nil];
}
}
}
}
- (void)copyTextFile:(NSString*)fromThePath toPath:(NSString*)thePath
{
std::string buffer;
FSRef pathRef;
NSString* toPath;
NSString* fromPath;
NSArray* matches;
OSStatus status;
OSErr err;
int taskStatus;
NSTask* task;
NSFileManager* fileMgr = [NSFileManager defaultManager];
unsigned rc = [thePath completePathIntoString:&toPath caseSensitive:NO matchesIntoArray:&matches filterTypes:nil];
toPath = [self convertPathNameToCorrectCapitalization:thePath];
fromPath = [self convertPathNameToCorrectCapitalization:fromThePath];
// NSArray* array = [NSArray arrayWithObjects:toPath, @"/Volumes/dragontail/Trash"];
// Now unlock the file before writing to it
[self setFileLockStatus:toPath isLocked:NO];
// Also change it's permissions to "writable"
NSMutableArray* array = [[NSMutableArray alloc] init];
[array addObject:@"+w"];
[array addObject:toPath];
task = [NSTask launchedTaskWithLaunchPath:@"/bin/chmod" arguments:array];
[task waitUntilExit];
taskStatus = [task terminationStatus];
if (taskStatus == 0)
NSLog(@"Permissions change succeeded.");
else
NSLog(@"Permissions change failed.");
/* we need this for mac->pc but not pc->mac, so comment out for now
NSMutableArray* array = [[NSMutableArray alloc] init];
[array addObject:toPath];
[array addObject:@"/Volumes/dragontail/Trash"];
task = [NSTask launchedTaskWithLaunchPath:@"/bin/mv" arguments:array];
[task waitUntilExit];
taskStatus = [task terminationStatus];
if (taskStatus == 0)
NSLog(@"Task succeeded.");
else
NSLog(@"Task failed.");
end of code commented for pc->mac*/
/* status = FSPathMakeRef([toPath cString], &pathRef, nil);
if (status != noErr)
NSLog(@"Couldn't make FSRef in Carbon for:%@", toPath);
err = FSDeleteObject(&pathRef);
if (err != noErr)
NSLog(@"Couldn't delete with Carbon:%@", toPath);
*/
if ( [fileMgr fileExistsAtPath:toPath] )
{
// not valid for pc->mac NSLog(@"The file is still there: %@", toPath);
/* if ( [fileMgr isDeletableFileAtPath:toPath] )
{
BOOL wasRemoved = [fileMgr removeFileAtPath:toPath handler:self];
if (!wasRemoved)
{
NSLog(@"The following file could not be deleted:%@", toPath);
}
} else
{
NSLog(@"The following file is not deletable:%@", toPath);
}
*/ }
std::ifstream fromFile([fromPath cString]);
std::ofstream toFile([toPath cString]);
// if (!toFile.is_open())
// NSLog(@"To file:%@ was not opened", toPath);
// if (!toFile.good())
// NSLog(@"To file:%@ is not in good state", toPath);
/*mac -> pc
char newline = '\n';
while ( std::getline(fromFile, buffer, newline) || fromFile.gcount() )
{
toFile << buffer;
toFile << "\r\n";
}
mac->pc */
char newline = '\r';
while ( std::getline(fromFile, buffer, newline) || fromFile.gcount() )
{
toFile << buffer;
// toFile << "\r\n";
}
// if (!toFile.good())
// NSLog(@"To file:%@ still not in good state", toPath);
}
- (BOOL)fileManager:(NSFileManager *)manager willProcessPath:(NSString *)path
{
return YES;
}
- (BOOL)fileManager:(NSFileManager *)manager shouldProceedAfterError:(NSDictionary *)errorDict
{
// int result;
// NSString* errorString = [errorDict objectForKey:@"Error"];
NSLog(@"Error deleting %@", [errorDict objectForKey:@"Path"]);
// result = NSRunAlertPanel(@"Gumby App", @"File operation error:
// %@ with file: %@", @"Proceed", @"Stop", NULL,
// errorString,
// [errorDict objectForKey:@"Path"]);
// if (result == NSAlertDefaultReturn)
// return YES;
// else
// return NO;
}
- (NSString*) convertPathNameToCorrectCapitalization:(NSString*) path
{
int i;
NSFileManager* fileMgr = [NSFileManager defaultManager];
NSArray* pathComponents = [path pathComponents];
NSMutableArray* newPathComponents = [[NSMutableArray alloc] init];
[newPathComponents addObject:@"/"];
for (i = 1; i < [pathComponents count]; i++)
{
NSString* tempPath = [NSString pathWithComponents:newPathComponents ];
NSArray* contents = [fileMgr directoryContentsAtPath:tempPath];
NSString* currentComponent = [pathComponents objectAtIndex:i];
NSEnumerator *enumerator = [contents objectEnumerator];
id fileOrDir;
BOOL wasFound = NO;
while (!wasFound && (fileOrDir = [enumerator nextObject]))
{
if ([fileOrDir caseInsensitiveCompare:currentComponent] == NSOrderedSame)
{
[newPathComponents addObject:fileOrDir];
wasFound = YES;
}
}
if (!wasFound)
{
int j;
for (j = [newPathComponents count]; j < [pathComponents count]; j++)
{
[newPathComponents addObject:[pathComponents objectAtIndex:j]];
}
}
}
return [NSString pathWithComponents:newPathComponents];
}
@end