diff --git a/English.lproj/PBRemoteProgressSheet.xib b/English.lproj/PBRemoteProgressSheet.xib
new file mode 100644
index 0000000..2a01a42
--- /dev/null
+++ b/English.lproj/PBRemoteProgressSheet.xib
@@ -0,0 +1,807 @@
+
+
+
+ 1050
+ 10C540
+ 732
+ 1038.25
+ 458.00
+
+
+
+
+
+ YES
+
+ PBRemoteProgressSheet
+
+
+ FirstResponder
+
+
+ NSApplication
+
+
+ 1
+ 2
+ {{196, 412}, {397, 98}}
+ 544736256
+ Window
+ NSWindow
+
+ {1.79769e+308, 1.79769e+308}
+
+
+ 274
+
+ YES
+
+
+ 1314
+
+ {{35, 16}, {344, 20}}
+
+ 16394
+ 100
+
+
+
+ 274
+ {{17, 44}, {363, 34}}
+
+ YES
+
+ 67239424
+ 272891904
+ Operation in progress.
+
+ LucidaGrande
+ 13
+ 16
+
+
+
+ 6
+ System
+ controlColor
+
+ 3
+ MC42NjY2NjY2NjY3AA
+
+
+
+ 6
+ System
+ controlTextColor
+
+ 3
+ MAA
+
+
+
+
+
+ {397, 98}
+
+
+ {{0, 0}, {1680, 1028}}
+ {1.79769e+308, 1.79769e+308}
+
+
+
+
+ YES
+
+
+ window
+
+
+
+ 21
+
+
+
+ progressIndicator
+
+
+
+ 22
+
+
+
+ progressDescription
+
+
+
+ 33
+
+
+
+
+ YES
+
+ 0
+
+
+
+
+
+ -2
+
+
+ File's Owner
+
+
+ -1
+
+
+ First Responder
+
+
+ -3
+
+
+ Application
+
+
+ 1
+
+
+ YES
+
+
+
+ Progress Window (Window)
+
+
+ 2
+
+
+ YES
+
+
+
+
+
+
+ 16
+
+
+
+
+ 31
+
+
+ YES
+
+
+
+
+
+ 32
+
+
+
+
+
+
+ YES
+
+ YES
+ 1.IBEditorWindowLastContentRect
+ 1.IBPluginDependency
+ 1.IBWindowTemplateEditedContentRect
+ 1.NSWindowTemplate.visibleAtLaunch
+ 1.WindowOrigin
+ 1.editorWindowContentRectSynchronizationRect
+ 1.windowTemplate.hasMinSize
+ 1.windowTemplate.minSize
+ 16.IBPluginDependency
+ 2.IBPluginDependency
+ 31.IBPluginDependency
+ 32.IBPluginDependency
+
+
+ YES
+ {{639, 822}, {397, 98}}
+ com.apple.InterfaceBuilder.CocoaPlugin
+ {{639, 822}, {397, 98}}
+
+ {196, 240}
+ {{202, 428}, {480, 270}}
+
+ {420, 170}
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+ YES
+
+
+ YES
+
+
+
+
+ YES
+
+
+ YES
+
+
+
+ 33
+
+
+
+ YES
+
+ PBRemoteProgressSheet
+ NSWindowController
+
+ YES
+
+ YES
+ progressDescription
+ progressIndicator
+
+
+ YES
+ NSTextField
+ NSProgressIndicator
+
+
+
+ IBProjectSource
+ PBRemoteProgressSheet.h
+
+
+
+
+ YES
+
+ NSActionCell
+ NSCell
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSActionCell.h
+
+
+
+ NSApplication
+ NSResponder
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSApplication.h
+
+
+
+ NSApplication
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSApplicationScripting.h
+
+
+
+ NSApplication
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSColorPanel.h
+
+
+
+ NSApplication
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSHelpManager.h
+
+
+
+ NSApplication
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSPageLayout.h
+
+
+
+ NSApplication
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSUserInterfaceItemSearching.h
+
+
+
+ NSCell
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSCell.h
+
+
+
+ NSControl
+ NSView
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSControl.h
+
+
+
+ NSFormatter
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSFormatter.h
+
+
+
+ NSMenu
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSMenu.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSAccessibility.h
+
+
+
+ NSObject
+
+
+
+ NSObject
+
+
+
+ NSObject
+
+
+
+ NSObject
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSDictionaryController.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSDragging.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSFontManager.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSFontPanel.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSKeyValueBinding.h
+
+
+
+ NSObject
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSNibLoading.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSOutlineView.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSPasteboard.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSSavePanel.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSTableView.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSToolbarItem.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSView.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSArchiver.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSClassDescription.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSError.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSFileManager.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSKeyValueCoding.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSKeyValueObserving.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSKeyedArchiver.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSObject.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSObjectScripting.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSPortCoder.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSRunLoop.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSScriptClassDescription.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSScriptKeyValueCoding.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSScriptObjectSpecifiers.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSScriptWhoseTests.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSThread.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSURL.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSURLConnection.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSURLDownload.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Sparkle.framework/Headers/SUAppcast.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Sparkle.framework/Headers/SUUpdater.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebDownload.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebEditingDelegate.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebFrameLoadDelegate.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebJavaPlugIn.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebPlugin.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebPluginContainer.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebPolicyDelegate.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebResourceLoadDelegate.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebScriptObject.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebUIDelegate.h
+
+
+
+ NSProgressIndicator
+ NSView
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSProgressIndicator.h
+
+
+
+ NSResponder
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSInterfaceStyle.h
+
+
+
+ NSResponder
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSResponder.h
+
+
+
+ NSTextField
+ NSControl
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSTextField.h
+
+
+
+ NSTextFieldCell
+ NSActionCell
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSTextFieldCell.h
+
+
+
+ NSView
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSClipView.h
+
+
+
+ NSView
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSMenuItem.h
+
+
+
+ NSView
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSRulerView.h
+
+
+
+ NSView
+ NSResponder
+
+
+
+ NSWindow
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSDrawer.h
+
+
+
+ NSWindow
+ NSResponder
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSWindow.h
+
+
+
+ NSWindow
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSWindowScripting.h
+
+
+
+ NSWindowController
+ NSResponder
+
+ showWindow:
+ id
+
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSWindowController.h
+
+
+
+
+ 0
+
+ com.apple.InterfaceBuilder.CocoaPlugin.macosx
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3
+
+
+ YES
+ ../GitX.xcodeproj
+ 3
+
+
diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj
index 7caba38..f8ee3bb 100644
--- a/GitX.xcodeproj/project.pbxproj
+++ b/GitX.xcodeproj/project.pbxproj
@@ -44,6 +44,8 @@
93CB42C20EAB7B2200530609 /* PBGitDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 93CB42C10EAB7B2200530609 /* PBGitDefaults.m */; };
93F7857F0EA3ABF100C1F443 /* PBCommitMessageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F7857E0EA3ABF100C1F443 /* PBCommitMessageView.m */; };
D26DC6450E782C9000C777B2 /* gitx.icns in Resources */ = {isa = PBXBuildFile; fileRef = D26DC6440E782C9000C777B2 /* gitx.icns */; };
+ D8083A43111E045D00337480 /* PBRemoteProgressSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = D8083A42111E045D00337480 /* PBRemoteProgressSheet.m */; };
+ D8357535112640F100DE249D /* PBRemoteProgressSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = D8C1B77110E875CF009B7F8B /* PBRemoteProgressSheet.xib */; };
D854948610D5C01B0083B917 /* PBCreateBranchSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = D854948510D5C01B0083B917 /* PBCreateBranchSheet.m */; };
D85B939310E3D8B4007F3C28 /* PBCreateBranchSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = D85B939210E3D8B4007F3C28 /* PBCreateBranchSheet.xib */; };
D889EB3110E6BCBB00F08413 /* PBCreateTagSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = D889EB3010E6BCBB00F08413 /* PBCreateTagSheet.xib */; };
@@ -213,11 +215,14 @@
93F7857E0EA3ABF100C1F443 /* PBCommitMessageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBCommitMessageView.m; sourceTree = ""; };
93FCCBA80EA8AF450061B02B /* PBGitConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitConfig.m; sourceTree = ""; };
D26DC6440E782C9000C777B2 /* gitx.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = gitx.icns; sourceTree = ""; };
+ D8083A2D111E045300337480 /* PBRemoteProgressSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBRemoteProgressSheet.h; sourceTree = ""; };
+ D8083A42111E045D00337480 /* PBRemoteProgressSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBRemoteProgressSheet.m; sourceTree = ""; };
D823487410CB382C00944BDE /* Terminal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Terminal.h; sourceTree = ""; };
D854948410D5C01B0083B917 /* PBCreateBranchSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBCreateBranchSheet.h; sourceTree = ""; };
D854948510D5C01B0083B917 /* PBCreateBranchSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBCreateBranchSheet.m; sourceTree = ""; };
D854949310D5C3E20083B917 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/PBCreateBranchSheet.xib; sourceTree = ""; };
D85B93F610E51279007F3C28 /* PBGitRefish.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitRefish.h; sourceTree = ""; };
+ D8C1B77210E875CF009B7F8B /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/PBRemoteProgressSheet.xib; sourceTree = ""; };
D8E3B2B710DC9FB2001096A3 /* ScriptingBridge.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ScriptingBridge.framework; path = /System/Library/Frameworks/ScriptingBridge.framework; sourceTree = ""; };
D8E3B34B10DCA958001096A3 /* PBCreateTagSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBCreateTagSheet.h; sourceTree = ""; };
D8E3B34C10DCA958001096A3 /* PBCreateTagSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBCreateTagSheet.m; sourceTree = ""; };
@@ -462,6 +467,7 @@
F59116E50E843BB50072CCB1 /* PBGitCommitView.xib */,
D85B939210E3D8B4007F3C28 /* PBCreateBranchSheet.xib */,
D889EB3010E6BCBB00F08413 /* PBCreateTagSheet.xib */,
+ D8C1B77110E875CF009B7F8B /* PBRemoteProgressSheet.xib */,
47DBDB680E94EF6500671A1E /* Preferences.xib */,
F569AE920F2CBD7C00C2FFA7 /* Credits.html */,
);
@@ -511,6 +517,8 @@
D854948510D5C01B0083B917 /* PBCreateBranchSheet.m */,
D8E3B34B10DCA958001096A3 /* PBCreateTagSheet.h */,
D8E3B34C10DCA958001096A3 /* PBCreateTagSheet.m */,
+ D8083A2D111E045300337480 /* PBRemoteProgressSheet.h */,
+ D8083A42111E045D00337480 /* PBRemoteProgressSheet.m */,
);
name = Sheets;
sourceTree = "";
@@ -853,6 +861,7 @@
F569AE930F2CBD7C00C2FFA7 /* Credits.html in Resources */,
D85B939310E3D8B4007F3C28 /* PBCreateBranchSheet.xib in Resources */,
D889EB3110E6BCBB00F08413 /* PBCreateTagSheet.xib in Resources */,
+ D8357535112640F100DE249D /* PBRemoteProgressSheet.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -974,6 +983,7 @@
F59F1DD5105C4FF300115F88 /* PBGitIndex.m in Sources */,
D854948610D5C01B0083B917 /* PBCreateBranchSheet.m in Sources */,
D8E3B34D10DCA958001096A3 /* PBCreateTagSheet.m in Sources */,
+ D8083A43111E045D00337480 /* PBRemoteProgressSheet.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1082,6 +1092,14 @@
name = PBCreateTagSheet.xib;
sourceTree = "";
};
+ D8C1B77110E875CF009B7F8B /* PBRemoteProgressSheet.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ D8C1B77210E875CF009B7F8B /* English */,
+ );
+ name = PBRemoteProgressSheet.xib;
+ sourceTree = "";
+ };
F5B721C20E05CF7E00AF29DC /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
diff --git a/PBRemoteProgressSheet.h b/PBRemoteProgressSheet.h
new file mode 100644
index 0000000..71a52b9
--- /dev/null
+++ b/PBRemoteProgressSheet.h
@@ -0,0 +1,47 @@
+//
+// PBRemoteProgressSheetController.h
+// GitX
+//
+// Created by Nathan Kinsinger on 12/6/09.
+// Copyright 2009 Nathan Kinsinger. All rights reserved.
+//
+
+#import
+
+
+extern NSString * const kGitXProgressDescription;
+extern NSString * const kGitXProgressSuccessDescription;
+extern NSString * const kGitXProgressSuccessInfo;
+extern NSString * const kGitXProgressErrorDescription;
+extern NSString * const kGitXProgressErrorInfo;
+
+
+@class PBGitRepository;
+@class PBGitWindowController;
+
+@interface PBRemoteProgressSheet : NSWindowController {
+ PBGitWindowController *controller;
+
+ NSArray *arguments;
+ NSString *title;
+ NSString *description;
+
+ NSTask *gitTask;
+ NSInteger returnCode;
+
+ NSTextField *progressDescription;
+ NSProgressIndicator *progressIndicator;
+
+ NSTimer *taskTimer;
+}
+
++ (void) beginRemoteProgressSheetForArguments:(NSArray *)args title:(NSString *)theTitle description:(NSString *)theDescription inDir:(NSString *)dir windowController:(NSWindowController *)windowController;
+
++ (void) beginRemoteProgressSheetForArguments:(NSArray *)args title:(NSString *)theTitle description:(NSString *)theDescription inRepository:(PBGitRepository *)repo;
+
+
+@property (assign) IBOutlet NSTextField *progressDescription;
+@property (assign) IBOutlet NSProgressIndicator *progressIndicator;
+
+
+@end
\ No newline at end of file
diff --git a/PBRemoteProgressSheet.m b/PBRemoteProgressSheet.m
new file mode 100644
index 0000000..77b250e
--- /dev/null
+++ b/PBRemoteProgressSheet.m
@@ -0,0 +1,249 @@
+//
+// 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:(PBGitWindowController *)controller;
+- (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:(PBGitWindowController *)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:(PBGitWindowController *)windowController
+{
+ controller = windowController;
+ arguments = args;
+ title = theTitle;
+ description = theDescription;
+
+ [self window]; // loads the window (if it wasn't already)
+ [self.progressDescription setStringValue:[self progressTitle]];
+ [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)])
+ [controller.repository reloadRefs];
+}
+
+
+
+#pragma mark taskTimer
+
+- (void) checkTask:(NSTimer *)timer
+{
+ if (![gitTask isRunning]) {
+ NSLog(@"[%@ %s] gitTask terminated without notification", [self class], _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]];
+
+ [(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];
+
+ [(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