TransferController.mm #1

  • //
  • guest/
  • jeff_argast/
  • P4Cocoa/
  • source/
  • Controllers/
  • TransferController.mm
  • View
  • Commits
  • Open Download .zip Download (13 KB)
/*

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
# Change User Description Committed
#1 2732 Jeff Argast Initial submission of P4Cocoa