mirror of
https://github.com/kennethreitz-archive/gitx.git
synced 2026-06-05 15:30:18 +00:00
266 lines
7.7 KiB
Objective-C
266 lines
7.7 KiB
Objective-C
//
|
|
// PBRemoteProgressSheetController.m
|
|
// GitX
|
|
//
|
|
// Created by Nathan Kinsinger on 12/6/09.
|
|
// Copyright 2009 Nathan Kinsinger. All rights reserved.
|
|
//
|
|
|
|
#import "PBRemoteProgressSheet.h"
|
|
#import "PBGitWindowController.h"
|
|
#import "PBGitRepository.h"
|
|
#import "PBGitBinary.h"
|
|
#import "PBEasyPipe.h"
|
|
|
|
|
|
|
|
NSString * const kGitXProgressDescription = @"PBGitXProgressDescription";
|
|
NSString * const kGitXProgressSuccessDescription = @"PBGitXProgressSuccessDescription";
|
|
NSString * const kGitXProgressSuccessInfo = @"PBGitXProgressSuccessInfo";
|
|
NSString * const kGitXProgressErrorDescription = @"PBGitXProgressErrorDescription";
|
|
NSString * const kGitXProgressErrorInfo = @"PBGitXProgressErrorInfo";
|
|
|
|
|
|
|
|
@interface PBRemoteProgressSheet ()
|
|
|
|
- (void) beginRemoteProgressSheetForArguments:(NSArray *)args title:(NSString *)theTitle description:(NSString *)theDescription inDir:(NSString *)dir windowController:(NSWindowController *)windowController;
|
|
- (void) showSuccessMessage;
|
|
- (void) showErrorMessage;
|
|
|
|
- (NSString *) progressTitle;
|
|
- (NSString *) successTitle;
|
|
- (NSString *) successDescription;
|
|
- (NSString *) errorTitle;
|
|
- (NSString *) errorDescription;
|
|
- (NSString *) commandDescription;
|
|
- (NSString *) standardOutputDescription;
|
|
- (NSString *) standardErrorDescription;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation PBRemoteProgressSheet
|
|
|
|
|
|
@synthesize progressDescription;
|
|
@synthesize progressIndicator;
|
|
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark PBRemoteProgressSheet
|
|
|
|
+ (void) beginRemoteProgressSheetForArguments:(NSArray *)args title:(NSString *)theTitle description:(NSString *)theDescription inDir:(NSString *)dir windowController:(NSWindowController *)windowController
|
|
{
|
|
PBRemoteProgressSheet *sheet = [[self alloc] initWithWindowNibName:@"PBRemoteProgressSheet"];
|
|
[sheet beginRemoteProgressSheetForArguments:args title:theTitle description:theDescription inDir:dir windowController:windowController];
|
|
}
|
|
|
|
|
|
+ (void) beginRemoteProgressSheetForArguments:(NSArray *)args title:(NSString *)theTitle description:(NSString *)theDescription inRepository:(PBGitRepository *)repo
|
|
{
|
|
[PBRemoteProgressSheet beginRemoteProgressSheetForArguments:args title:theTitle description:theDescription inDir:[repo workingDirectory] windowController:repo.windowController];
|
|
}
|
|
|
|
|
|
- (void) beginRemoteProgressSheetForArguments:(NSArray *)args title:(NSString *)theTitle description:(NSString *)theDescription inDir:(NSString *)dir windowController:(NSWindowController *)windowController
|
|
{
|
|
controller = windowController;
|
|
arguments = args;
|
|
title = theTitle;
|
|
description = theDescription;
|
|
|
|
[self window]; // loads the window (if it wasn't already)
|
|
|
|
// resize window if the description is larger than the default text field
|
|
NSRect originalFrame = [self.progressDescription frame];
|
|
[self.progressDescription setStringValue:[self progressTitle]];
|
|
NSAttributedString *attributedTitle = [self.progressDescription attributedStringValue];
|
|
NSSize boundingSize = originalFrame.size;
|
|
boundingSize.height = 0.0f;
|
|
NSRect boundingRect = [attributedTitle boundingRectWithSize:boundingSize options:NSStringDrawingUsesLineFragmentOrigin];
|
|
CGFloat heightDelta = boundingRect.size.height - originalFrame.size.height;
|
|
if (heightDelta > 0.0f) {
|
|
NSRect windowFrame = [[self window] frame];
|
|
windowFrame.size.height += heightDelta;
|
|
[[self window] setFrame:windowFrame display:NO];
|
|
}
|
|
|
|
[self.progressIndicator startAnimation:nil];
|
|
[NSApp beginSheet:[self window] modalForWindow:[controller window] modalDelegate:self didEndSelector:nil contextInfo:nil];
|
|
|
|
gitTask = [PBEasyPipe taskForCommand:[PBGitBinary path] withArgs:arguments inDir:dir];
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskCompleted:) name:NSTaskDidTerminateNotification object:gitTask];
|
|
|
|
// having intermittent problem with long running git tasks not sending a termination notice, so periodically check whether the task is done
|
|
taskTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(checkTask:) userInfo:nil repeats:YES];
|
|
|
|
[gitTask launch];
|
|
}
|
|
|
|
|
|
|
|
#pragma mark Notifications
|
|
|
|
- (void) taskCompleted:(NSNotification *)notification
|
|
{
|
|
[taskTimer invalidate];
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
|
|
[self.progressIndicator stopAnimation:nil];
|
|
[NSApp endSheet:[self window]];
|
|
[[self window] orderOut:self];
|
|
|
|
returnCode = [gitTask terminationStatus];
|
|
if (returnCode)
|
|
[self showErrorMessage];
|
|
else
|
|
[self showSuccessMessage];
|
|
|
|
if ([controller respondsToSelector:@selector(repository)])
|
|
[[(PBGitWindowController *)controller repository] reloadRefs];
|
|
}
|
|
|
|
|
|
|
|
#pragma mark taskTimer
|
|
|
|
- (void) checkTask:(NSTimer *)timer
|
|
{
|
|
if (![gitTask isRunning]) {
|
|
DLog(@"[%@ %@] gitTask terminated without notification", [self class], NSStringFromSelector(_cmd));
|
|
[self taskCompleted:nil];
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#pragma mark Messages
|
|
|
|
- (void) showSuccessMessage
|
|
{
|
|
NSMutableString *info = [NSMutableString string];
|
|
[info appendString:[self successDescription]];
|
|
[info appendString:[self commandDescription]];
|
|
[info appendString:[self standardOutputDescription]];
|
|
|
|
if ([controller respondsToSelector:@selector(showMessageSheet:infoText:)])
|
|
[(PBGitWindowController *)controller showMessageSheet:[self successTitle] infoText:info];
|
|
}
|
|
|
|
|
|
- (void) showErrorMessage
|
|
{
|
|
NSMutableString *info = [NSMutableString string];
|
|
[info appendString:[self errorDescription]];
|
|
[info appendString:[self commandDescription]];
|
|
[info appendString:[self standardOutputDescription]];
|
|
[info appendString:[self standardErrorDescription]];
|
|
|
|
NSDictionary *errorUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
|
|
[self errorTitle], NSLocalizedDescriptionKey,
|
|
info, NSLocalizedRecoverySuggestionErrorKey,
|
|
nil];
|
|
NSError *error = [NSError errorWithDomain:PBGitRepositoryErrorDomain code:0 userInfo:errorUserInfo];
|
|
|
|
if ([controller respondsToSelector:@selector(showErrorSheet:)])
|
|
[(PBGitWindowController *)controller showErrorSheet:error];
|
|
}
|
|
|
|
|
|
|
|
#pragma mark Display Strings
|
|
|
|
- (NSString *) progressTitle
|
|
{
|
|
NSString *progress = description;
|
|
if (!progress)
|
|
progress = @"Operation in progress.";
|
|
|
|
return progress;
|
|
}
|
|
|
|
|
|
- (NSString *) successTitle
|
|
{
|
|
NSString *success = title;
|
|
if (!success)
|
|
success = @"Operation";
|
|
|
|
return [success stringByAppendingString:@" completed."];
|
|
}
|
|
|
|
|
|
- (NSString *) successDescription
|
|
{
|
|
NSString *info = description;
|
|
if (!info)
|
|
return @"";
|
|
|
|
return [info stringByAppendingString:@" completed successfully.\n\n"];
|
|
}
|
|
|
|
|
|
- (NSString *) errorTitle
|
|
{
|
|
NSString *error = title;
|
|
if (!error)
|
|
error = @"Operation";
|
|
|
|
return [error stringByAppendingString:@" failed."];
|
|
}
|
|
|
|
|
|
- (NSString *) errorDescription
|
|
{
|
|
NSString *info = description;
|
|
if (!info)
|
|
return @"";
|
|
|
|
return [info stringByAppendingString:@" encountered an error.\n\n"];
|
|
}
|
|
|
|
|
|
- (NSString *) commandDescription
|
|
{
|
|
if (!arguments || ([arguments count] == 0))
|
|
return @"";
|
|
|
|
return [NSString stringWithFormat:@"command: git %@", [arguments componentsJoinedByString:@" "]];
|
|
}
|
|
|
|
|
|
- (NSString *) standardOutputDescription
|
|
{
|
|
if (!gitTask || [gitTask isRunning])
|
|
return @"";
|
|
|
|
NSData *data = [[[gitTask standardOutput] fileHandleForReading] readDataToEndOfFile];
|
|
NSString *standardOutput = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
|
|
if ([standardOutput isEqualToString:@""])
|
|
return @"";
|
|
|
|
return [NSString stringWithFormat:@"\n\n%@", standardOutput];
|
|
}
|
|
|
|
|
|
- (NSString *) standardErrorDescription
|
|
{
|
|
if (!gitTask || [gitTask isRunning])
|
|
return @"";
|
|
|
|
NSData *data = [[[gitTask standardError] fileHandleForReading] readDataToEndOfFile];
|
|
NSString *standardError = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
|
|
if ([standardError isEqualToString:@""])
|
|
return [NSString stringWithFormat:@"\nerror = %d", returnCode];
|
|
|
|
return [NSString stringWithFormat:@"\n\n%@\nerror = %d", standardError, returnCode];
|
|
}
|
|
|
|
|
|
@end
|