Permalink
Browse files

fix the crash reporter

  • Loading branch information...
1 parent fe21aef commit bd0450a5f00ad69d0e69249483844f2ac22f1b8e @dustinrue committed May 24, 2012
View
6 ControlPlane.xcodeproj/project.pbxproj
@@ -83,6 +83,7 @@
DA16392613D4B14A00E3F421 /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = DA16392513D4B14A00E3F421 /* dsa_pub.pem */; };
DA2B4381152161C800E94A1D /* ToggleTFTPAction.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2B4380152161C800E94A1D /* ToggleTFTPAction.m */; };
DA2B4385152161D900E94A1D /* ToggleFTPAction.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2B4384152161D900E94A1D /* ToggleFTPAction.m */; };
+ DA312CA3156DD42E009C1389 /* BWQuincyUI.m in Sources */ = {isa = PBXBuildFile; fileRef = DA312CA2156DD42E009C1389 /* BWQuincyUI.m */; };
DA41954D151C17F000FF7BA0 /* ActionSubmenuItem.m in Sources */ = {isa = PBXBuildFile; fileRef = DA41954C151C17F000FF7BA0 /* ActionSubmenuItem.m */; };
DA4411A514EE03C9005E7B3B /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA4411A414EE03C9005E7B3B /* MapKit.framework */; };
DA461C0C14C33E3C0019594A /* NSString+ShellScriptHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DA461C0B14C33E3B0019594A /* NSString+ShellScriptHelper.m */; };
@@ -373,6 +374,8 @@
DA2B4380152161C800E94A1D /* ToggleTFTPAction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ToggleTFTPAction.m; path = Source/ToggleTFTPAction.m; sourceTree = "<group>"; };
DA2B4383152161D900E94A1D /* ToggleFTPAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ToggleFTPAction.h; path = Source/ToggleFTPAction.h; sourceTree = "<group>"; };
DA2B4384152161D900E94A1D /* ToggleFTPAction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ToggleFTPAction.m; path = Source/ToggleFTPAction.m; sourceTree = "<group>"; };
+ DA312CA1156DD42E009C1389 /* BWQuincyUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BWQuincyUI.h; sourceTree = "<group>"; };
+ DA312CA2156DD42E009C1389 /* BWQuincyUI.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BWQuincyUI.m; sourceTree = "<group>"; };
DA41954B151C17EF00FF7BA0 /* ActionSubmenuItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ActionSubmenuItem.h; path = Source/ActionSubmenuItem.h; sourceTree = "<group>"; };
DA41954C151C17F000FF7BA0 /* ActionSubmenuItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ActionSubmenuItem.m; path = Source/ActionSubmenuItem.m; sourceTree = "<group>"; };
DA4411A414EE03C9005E7B3B /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = Frameworks/MapKit.framework; sourceTree = "<group>"; };
@@ -826,6 +829,8 @@
DAF2F81B150EE5960040DDC7 /* BWQuincyMain.nib */,
DAF2F81C150EE5960040DDC7 /* BWQuincyManager.h */,
DAF2F81D150EE5960040DDC7 /* BWQuincyManager.m */,
+ DA312CA1156DD42E009C1389 /* BWQuincyUI.h */,
+ DA312CA2156DD42E009C1389 /* BWQuincyUI.m */,
DAF2F81E150EE5960040DDC7 /* Quincy-Info.plist */,
DAF2F81F150EE5960040DDC7 /* Quincy-Prefix.pch */,
);
@@ -1274,6 +1279,7 @@
DA2B4385152161D900E94A1D /* ToggleFTPAction.m in Sources */,
DAC672FE152235E800F1C7A1 /* ToggleWebSharingAction.m in Sources */,
DA8E283F156BCAD50040FC35 /* ToggleRemoteLoginAction.m in Sources */,
+ DA312CA3156DD42E009C1389 /* BWQuincyUI.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
172 External Source/Quincy/BWQuincyManager.h
@@ -29,72 +29,69 @@
#import <Cocoa/Cocoa.h>
-#define CRASHREPORTSENDER_MAX_CONSOLE_SIZE 50000
-
typedef enum CrashAlertType {
- CrashAlertTypeSend = 0,
- CrashAlertTypeFeedback = 1,
+ CrashAlertTypeSend = 0,
+ CrashAlertTypeFeedback = 1,
} CrashAlertType;
typedef enum CrashReportStatus {
- // This app version is set to discontinued, no new crash reports accepted by the server
- CrashReportStatusFailureVersionDiscontinued = -30,
+ // This app version is set to discontinued, no new crash reports accepted by the server
+ CrashReportStatusFailureVersionDiscontinued = -30,
- // XML: Sender ersion string contains not allowed characters, only alphanumberical including space and . are allowed
- CrashReportStatusFailureXMLSenderVersionNotAllowed = -21,
+ // XML: Sender ersion string contains not allowed characters, only alphanumberical including space and . are allowed
+ CrashReportStatusFailureXMLSenderVersionNotAllowed = -21,
- // XML: Version string contains not allowed characters, only alphanumberical including space and . are allowed
- CrashReportStatusFailureXMLVersionNotAllowed = -20,
+ // XML: Version string contains not allowed characters, only alphanumberical including space and . are allowed
+ CrashReportStatusFailureXMLVersionNotAllowed = -20,
- // SQL for adding a symoblicate todo entry in the database failed
- CrashReportStatusFailureSQLAddSymbolicateTodo = -18,
+ // SQL for adding a symoblicate todo entry in the database failed
+ CrashReportStatusFailureSQLAddSymbolicateTodo = -18,
- // SQL for adding crash log in the database failed
- CrashReportStatusFailureSQLAddCrashlog = -17,
+ // SQL for adding crash log in the database failed
+ CrashReportStatusFailureSQLAddCrashlog = -17,
- // SQL for adding a new version in the database failed
- CrashReportStatusFailureSQLAddVersion = -16,
-
- // SQL for checking if the version is already added in the database failed
- CrashReportStatusFailureSQLCheckVersionExists = -15,
-
- // SQL for creating a new pattern for this bug and set amount of occurrances to 1 in the database failed
- CrashReportStatusFailureSQLAddPattern = -14,
-
- // SQL for checking the status of the bugfix version in the database failed
- CrashReportStatusFailureSQLCheckBugfixStatus = -13,
-
- // SQL for updating the occurances of this pattern in the database failed
- CrashReportStatusFailureSQLUpdatePatternOccurances = -12,
-
- // SQL for getting all the known bug patterns for the current app version in the database failed
- CrashReportStatusFailureSQLFindKnownPatterns = -11,
-
- // SQL for finding the bundle identifier in the database failed
- CrashReportStatusFailureSQLSearchAppName = -10,
-
- // the post request didn't contain valid data
- CrashReportStatusFailureInvalidPostData = -3,
-
- // incoming data may not be added, because e.g. bundle identifier wasn't found
- CrashReportStatusFailureInvalidIncomingData = -2,
-
- // database cannot be accessed, check hostname, username, password and database name settings in config.php
- CrashReportStatusFailureDatabaseNotAvailable = -1,
-
- CrashReportStatusUnknown = 0,
-
- CrashReportStatusAssigned = 1,
-
- CrashReportStatusSubmitted = 2,
-
- CrashReportStatusAvailable = 3,
+ // SQL for adding a new version in the database failed
+ CrashReportStatusFailureSQLAddVersion = -16,
+
+ // SQL for checking if the version is already added in the database failed
+ CrashReportStatusFailureSQLCheckVersionExists = -15,
+
+ // SQL for creating a new pattern for this bug and set amount of occurrances to 1 in the database failed
+ CrashReportStatusFailureSQLAddPattern = -14,
+
+ // SQL for checking the status of the bugfix version in the database failed
+ CrashReportStatusFailureSQLCheckBugfixStatus = -13,
+
+ // SQL for updating the occurances of this pattern in the database failed
+ CrashReportStatusFailureSQLUpdatePatternOccurances = -12,
+
+ // SQL for getting all the known bug patterns for the current app version in the database failed
+ CrashReportStatusFailureSQLFindKnownPatterns = -11,
+
+ // SQL for finding the bundle identifier in the database failed
+ CrashReportStatusFailureSQLSearchAppName = -10,
+
+ // the post request didn't contain valid data
+ CrashReportStatusFailureInvalidPostData = -3,
+
+ // incoming data may not be added, because e.g. bundle identifier wasn't found
+ CrashReportStatusFailureInvalidIncomingData = -2,
+
+ // database cannot be accessed, check hostname, username, password and database name settings in config.php
+ CrashReportStatusFailureDatabaseNotAvailable = -1,
+
+ CrashReportStatusUnknown = 0,
+
+ CrashReportStatusAssigned = 1,
+
+ CrashReportStatusSubmitted = 2,
+
+ CrashReportStatusAvailable = 3,
} CrashReportStatus;
@class BWQuincyUI;
-// This protocol is used to send the image updates
@protocol BWQuincyManagerDelegate <NSObject>
@required
@@ -107,36 +104,34 @@ typedef enum CrashReportStatus {
// Return the description the crashreport should contain, empty by default. The string will automatically be wrapped into <[DATA[ ]]>, so make sure you don't do that in your string.
-(NSString *) crashReportDescription;
-@optional
-
// Return the userid the crashreport should contain, empty by default
-(NSString *) crashReportUserID;
// Return the contact value (e.g. email) the crashreport should contain, empty by default
-(NSString *) crashReportContact;
@end
+
@interface BWQuincyManager : NSObject
#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
<NSXMLParserDelegate>
#endif
{
- CrashReportStatus _serverResult;
-
- NSInteger _statusCode;
+ CrashReportStatus _serverResult;
+ NSInteger _statusCode;
- NSMutableString *_contentOfProperty;
+ NSMutableString *_contentOfProperty;
- id _delegate;
+ id<BWQuincyManagerDelegate> _delegate;
- NSString *_submissionURL;
- NSString *_companyName;
- NSString *_appIdentifier;
- BOOL _autoSubmitCrashReport;
+ NSString *_submissionURL;
+ NSString *_companyName;
+ NSString *_appIdentifier;
+ BOOL _autoSubmitCrashReport;
- NSString *_crashFile;
-
- BWQuincyUI *_quincyUI;
+ NSString *_crashFile;
+
+ BWQuincyUI *_quincyUI;
}
- (NSString*) modelVersion;
@@ -172,48 +167,3 @@ typedef enum CrashReportStatus {
- (NSString *) applicationVersion;
@end
-
-
-@interface BWQuincyUI : NSWindowController {
- IBOutlet NSTextField *descriptionTextField;
- IBOutlet NSTextView *crashLogTextView;
-
- IBOutlet NSTextField *noteText;
-
- IBOutlet NSButton *showButton;
- IBOutlet NSButton *hideButton;
- IBOutlet NSButton *cancelButton;
- IBOutlet NSButton *submitButton;
-
- BWQuincyManager *_delegate;
-
- NSString *_xml;
-
- NSString *_crashFile;
- NSString *_companyName;
- NSString *_applicationName;
-
- NSMutableString *_consoleContent;
- NSString *_crashLogContent;
-
- BOOL showComments;
- BOOL showDetails;
-}
-
-- (id)init:(id)delegate crashFile:(NSString *)crashFile companyName:(NSString *)companyName applicationName:(NSString *)applicationName;
-
-- (void) askCrashReportDetails;
-
-- (IBAction) cancelReport:(id)sender;
-- (IBAction) submitReport:(id)sender;
-- (IBAction) showDetails:(id)sender;
-- (IBAction) hideDetails:(id)sender;
-- (IBAction) showComments:(id)sender;
-
-- (BOOL)showComments;
-- (void)setShowComments:(BOOL)value;
-
-- (BOOL)showDetails;
-- (void)setShowDetails:(BOOL)value;
-
-@end
View
520 External Source/Quincy/BWQuincyManager.m
@@ -28,8 +28,12 @@
*/
#import "BWQuincyManager.h"
+#import "BWQuincyUI.h"
#import <sys/sysctl.h>
+#define SDK_NAME @"Quincy"
+#define SDK_VERSION @"2.1.6"
+
@interface BWQuincyManager(private)
- (void) startManager;
@@ -39,13 +43,6 @@ - (BOOL) hasPendingCrashReport;
- (void) returnToMainApplication;
@end
-@interface BWQuincyUI(private)
-- (void) askCrashReportDetails;
-- (void) endCrashReporter;
-@end
-
-const CGFloat kCommentsHeight = 105;
-const CGFloat kDetailsHeight = 285;
@implementation BWQuincyManager
@@ -56,64 +53,64 @@ @implementation BWQuincyManager
@synthesize autoSubmitCrashReport = _autoSubmitCrashReport;
+ (BWQuincyManager *)sharedQuincyManager {
- static BWQuincyManager *quincyManager = nil;
-
- if (quincyManager == nil) {
- quincyManager = [[BWQuincyManager alloc] init];
- }
-
- return quincyManager;
+ static BWQuincyManager *quincyManager = nil;
+
+ if (quincyManager == nil) {
+ quincyManager = [[BWQuincyManager alloc] init];
+ }
+
+ return quincyManager;
}
- (id) init {
if ((self = [super init])) {
- _serverResult = CrashReportStatusFailureDatabaseNotAvailable;
- _quincyUI = nil;
+ _serverResult = CrashReportStatusFailureDatabaseNotAvailable;
+ _quincyUI = nil;
- _submissionURL = nil;
+ _submissionURL = nil;
_appIdentifier = nil;
_crashFile = nil;
- self.delegate = nil;
- self.companyName = @"";
- }
- return self;
+ self.delegate = nil;
+ self.companyName = @"";
+ }
+ return self;
}
- (void)dealloc {
- _companyName = nil;
- _delegate = nil;
- _submissionURL = nil;
+ _companyName = nil;
+ _delegate = nil;
+ _submissionURL = nil;
_appIdentifier = nil;
[_crashFile release];
- [_quincyUI release];
-
- [super dealloc];
+ [_quincyUI release];
+
+ [super dealloc];
}
- (void) searchCrashLogFile:(NSString *)path {
- NSFileManager* fman = [NSFileManager defaultManager];
-
+ NSFileManager* fman = [NSFileManager defaultManager];
+
NSError* error;
- NSMutableArray* filesWithModificationDate = [NSMutableArray array];
- NSArray* crashLogFiles = [fman contentsOfDirectoryAtPath:path error:&error];
- NSEnumerator* filesEnumerator = [crashLogFiles objectEnumerator];
- NSString* crashFile;
- while((crashFile = [filesEnumerator nextObject])) {
- NSString* crashLogPath = [path stringByAppendingPathComponent:crashFile];
- NSDate* modDate = [[[NSFileManager defaultManager] attributesOfItemAtPath:crashLogPath error:&error] fileModificationDate];
- [filesWithModificationDate addObject:[NSDictionary dictionaryWithObjectsAndKeys:crashFile,@"name",crashLogPath,@"path",modDate,@"modDate",nil]];
- }
-
- NSSortDescriptor* dateSortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"modDate" ascending:YES] autorelease];
- NSArray* sortedFiles = [filesWithModificationDate sortedArrayUsingDescriptors:[NSArray arrayWithObject:dateSortDescriptor]];
-
- NSPredicate* filterPredicate = [NSPredicate predicateWithFormat:@"name BEGINSWITH %@", [self applicationName]];
- NSArray* filteredFiles = [sortedFiles filteredArrayUsingPredicate:filterPredicate];
-
- _crashFile = [[[filteredFiles valueForKeyPath:@"path"] lastObject] copy];
+ NSMutableArray* filesWithModificationDate = [NSMutableArray array];
+ NSArray* crashLogFiles = [fman contentsOfDirectoryAtPath:path error:&error];
+ NSEnumerator* filesEnumerator = [crashLogFiles objectEnumerator];
+ NSString* crashFile;
+ while((crashFile = [filesEnumerator nextObject])) {
+ NSString* crashLogPath = [path stringByAppendingPathComponent:crashFile];
+ NSDate* modDate = [[[NSFileManager defaultManager] attributesOfItemAtPath:crashLogPath error:&error] fileModificationDate];
+ [filesWithModificationDate addObject:[NSDictionary dictionaryWithObjectsAndKeys:crashFile,@"name",crashLogPath,@"path",modDate,@"modDate",nil]];
+ }
+
+ NSSortDescriptor* dateSortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"modDate" ascending:YES] autorelease];
+ NSArray* sortedFiles = [filesWithModificationDate sortedArrayUsingDescriptors:[NSArray arrayWithObject:dateSortDescriptor]];
+
+ NSPredicate* filterPredicate = [NSPredicate predicateWithFormat:@"name BEGINSWITH %@", [self applicationName]];
+ NSArray* filteredFiles = [sortedFiles filteredArrayUsingPredicate:filterPredicate];
+
+ _crashFile = [[[filteredFiles valueForKeyPath:@"path"] lastObject] copy];
}
#pragma mark -
@@ -160,7 +157,7 @@ - (NSString *)loadAppVersion {
#pragma mark GetCrashData
- (BOOL) hasPendingCrashReport {
- BOOL returnValue = NO;
+ BOOL returnValue = NO;
NSString *appVersion = [self loadAppVersion];
NSDate *lastCrashDate = [self loadLastCrashDate];
@@ -183,6 +180,14 @@ - (BOOL) hasPendingCrashReport {
[self searchCrashLogFile:[libFolderName stringByAppendingPathComponent:@"Logs/DiagnosticReports"]];
}
}
+ // Search machine diagnostic reports directory
+ if (_crashFile == nil) {
+ NSArray* libraryDirectories = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSLocalDomainMask, TRUE);
+ [self searchCrashLogFile:[[libraryDirectories lastObject] stringByAppendingPathComponent:@"Logs/DiagnosticReports"]];
+ if (_crashFile == nil) {
+ [self searchCrashLogFile:[[libraryDirectories lastObject] stringByAppendingPathComponent:@"Logs/CrashReporter"]];
+ }
+ }
}
if (_crashFile) {
@@ -195,19 +200,19 @@ - (BOOL) hasPendingCrashReport {
returnValue = YES;
}
}
-
- return returnValue;
+
+ return returnValue;
}
- (void) returnToMainApplication {
- if ( self.delegate != nil && [self.delegate respondsToSelector:@selector(showMainApplicationWindow)])
- [self.delegate showMainApplicationWindow];
+ if ( self.delegate != nil && [self.delegate respondsToSelector:@selector(showMainApplicationWindow)])
+ [self.delegate showMainApplicationWindow];
}
- (void) startManager {
if ([self hasPendingCrashReport]) {
if (!self.autoSubmitCrashReport) {
- _quincyUI = [[BWQuincyUI alloc] init:self crashFile:_crashFile companyName:_companyName applicationName:[self applicationName]];
+ _quincyUI = [[BWQuincyUI alloc] initWithManager:self crashFile:_crashFile companyName:_companyName applicationName:[self applicationName]];
[_quincyUI askCrashReportDetails];
} else {
NSError* error = nil;
@@ -222,6 +227,8 @@ - (void) startManager {
}
[self sendReportCrash:lastCrash description:description];
+ } else {
+ [self returnToMainApplication];
}
}
} else {
@@ -233,7 +240,7 @@ - (NSString*) modelVersion {
NSString * modelString = nil;
int modelInfo[2] = { CTL_HW, HW_MODEL };
size_t modelSize;
-
+
if (sysctl(modelInfo,
2,
NULL,
@@ -268,361 +275,160 @@ - (void) sendReportCrash:(NSString*)crashContent
description:(NSString*)notes
{
NSString *userid = @"";
- NSString *contact = @"";
-
- SInt32 versionMajor, versionMinor, versionBugFix;
- if (Gestalt(gestaltSystemVersionMajor, &versionMajor) != noErr) versionMajor = 0;
- if (Gestalt(gestaltSystemVersionMinor, &versionMinor) != noErr) versionMinor= 0;
- if (Gestalt(gestaltSystemVersionBugFix, &versionBugFix) != noErr) versionBugFix = 0;
-
- NSString* xml = [NSString stringWithFormat:@"<crash><applicationname>%s</applicationname><bundleidentifier>%s</bundleidentifier><systemversion>%@</systemversion><senderversion>%@</senderversion><version>%@</version><platform>%@</platform><userid>%@</userid><contact>%@</contact><description><![CDATA[%@]]></description><log><![CDATA[%@]]></log></crash>",
- [[self applicationName] UTF8String],
- [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"] UTF8String],
- [NSString stringWithFormat:@"%i.%i.%i", versionMajor, versionMinor, versionBugFix],
- [self applicationVersion],
- [self applicationVersion],
- [self modelVersion],
- userid,
- contact,
- notes,
- crashContent
- ];
+ NSString *contact = @"";
+
+ SInt32 versionMajor, versionMinor, versionBugFix;
+ if (Gestalt(gestaltSystemVersionMajor, &versionMajor) != noErr) versionMajor = 0;
+ if (Gestalt(gestaltSystemVersionMinor, &versionMinor) != noErr) versionMinor= 0;
+ if (Gestalt(gestaltSystemVersionBugFix, &versionBugFix) != noErr) versionBugFix = 0;
+
+ NSString* xml = [NSString stringWithFormat:@"<crash><applicationname>%s</applicationname><bundleidentifier>%s</bundleidentifier><systemversion>%@</systemversion><senderversion>%@</senderversion><version>%@</version><platform>%@</platform><userid>%@</userid><contact>%@</contact><description><![CDATA[%@]]></description><log><![CDATA[%@]]></log></crash>",
+ [[self applicationName] UTF8String],
+ [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"] UTF8String],
+ [NSString stringWithFormat:@"%i.%i.%i", versionMajor, versionMinor, versionBugFix],
+ [self applicationVersion],
+ [self applicationVersion],
+ [self modelVersion],
+ userid,
+ contact,
+ notes,
+ crashContent
+ ];
[self returnToMainApplication];
-
+
[self _postXML:[NSString stringWithFormat:@"<crashes>%@</crashes>", xml] toURL:[NSURL URLWithString:self.submissionURL]];
}
- (void)_postXML:(NSString*)xml toURL:(NSURL*)url {
- NSMutableURLRequest *request = nil;
+ NSMutableURLRequest *request = nil;
NSString *boundary = @"----FOO";
if (self.appIdentifier) {
- request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@api/2/apps/%@/crashes",
- self.submissionURL,
- [self.appIdentifier stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]
- ]
- ]];
+ request = [NSMutableURLRequest requestWithURL:
+ [NSURL URLWithString:[NSString stringWithFormat:@"%@api/2/apps/%@/crashes?sdk=%@&sdk_version=%@",
+ self.submissionURL,
+ [self.appIdentifier stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
+ SDK_NAME,
+ SDK_VERSION
+ ]
+ ]];
} else {
request = [NSMutableURLRequest requestWithURL:url];
}
-
- [request setValue:@"Quincy/Mac" forHTTPHeaderField:@"User-Agent"];
+
+ [request setValue:@"Quincy/Mac" forHTTPHeaderField:@"User-Agent"];
[request setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];
- [request setTimeoutInterval: 15];
- [request setHTTPMethod:@"POST"];
- NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
- [request setValue:contentType forHTTPHeaderField:@"Content-type"];
-
- NSMutableData *postBody = [NSMutableData data];
+ [request setTimeoutInterval: 15];
+ [request setHTTPMethod:@"POST"];
+ NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
+ [request setValue:contentType forHTTPHeaderField:@"Content-type"];
+
+ NSMutableData *postBody = [NSMutableData data];
[postBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
if (self.appIdentifier) {
[postBody appendData:[@"Content-Disposition: form-data; name=\"xml\"; filename=\"crash.xml\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:@"Content-Type: text/xml\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
} else {
[postBody appendData:[@"Content-Disposition: form-data; name=\"xmlstring\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
- }
- [postBody appendData:[xml dataUsingEncoding:NSUTF8StringEncoding]];
+ }
+ [postBody appendData:[xml dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
- [request setHTTPBody:postBody];
-
- _serverResult = CrashReportStatusUnknown;
- _statusCode = 200;
-
- NSHTTPURLResponse *response = nil;
- NSError *error = nil;
-
- NSData *responseData = nil;
- responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
- _statusCode = [response statusCode];
-
- if (responseData != nil) {
- if (_statusCode >= 200 && _statusCode < 400) {
- NSXMLParser *parser = [[NSXMLParser alloc] initWithData:responseData];
- // Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
- [parser setDelegate:self];
- // Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
- [parser setShouldProcessNamespaces:NO];
- [parser setShouldReportNamespacePrefixes:NO];
- [parser setShouldResolveExternalEntities:NO];
-
- [parser parse];
-
- [parser release];
- }
- }
+ [request setHTTPBody:postBody];
+
+ _serverResult = CrashReportStatusUnknown;
+ _statusCode = 200;
+
+ NSHTTPURLResponse *response = nil;
+ NSError *error = nil;
+
+ NSData *responseData = nil;
+ responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
+ _statusCode = [response statusCode];
+
+ if (responseData != nil) {
+ if (_statusCode >= 200 && _statusCode < 400) {
+ NSXMLParser *parser = [[NSXMLParser alloc] initWithData:responseData];
+ // Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
+ [parser setDelegate:self];
+ // Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
+ [parser setShouldProcessNamespaces:NO];
+ [parser setShouldReportNamespacePrefixes:NO];
+ [parser setShouldResolveExternalEntities:NO];
+
+ [parser parse];
+
+ [parser release];
+ }
+ }
}
#pragma mark NSXMLParser
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
- if (qName) {
- elementName = qName;
- }
-
- if ([elementName isEqualToString:@"result"]) {
- _contentOfProperty = [NSMutableString string];
- }
+ if (qName) {
+ elementName = qName;
+ }
+
+ if ([elementName isEqualToString:@"result"]) {
+ _contentOfProperty = [NSMutableString string];
+ }
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
- if (qName) {
- elementName = qName;
- }
-
- if ([elementName isEqualToString:@"result"]) {
- if ([_contentOfProperty intValue] > _serverResult) {
- _serverResult = [_contentOfProperty intValue];
- }
- }
+ if (qName) {
+ elementName = qName;
+ }
+
+ if ([elementName isEqualToString:@"result"]) {
+ if ([_contentOfProperty intValue] > _serverResult) {
+ _serverResult = [_contentOfProperty intValue];
+ }
+ }
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
- if (_contentOfProperty) {
- // If the current element is one whose content we care about, append 'string'
- // to the property that holds the content of the current element.
- if (string != nil) {
- [_contentOfProperty appendString:string];
- }
- }
+ if (_contentOfProperty) {
+ // If the current element is one whose content we care about, append 'string'
+ // to the property that holds the content of the current element.
+ if (string != nil) {
+ [_contentOfProperty appendString:string];
+ }
+ }
}
#pragma mark GetterSetter
- (NSString *) applicationName {
- NSString *applicationName = [[[NSBundle mainBundle] localizedInfoDictionary] valueForKey: @"CFBundleExecutable"];
-
- if (!applicationName)
- applicationName = [[[NSBundle mainBundle] infoDictionary] valueForKey: @"CFBundleExecutable"];
-
- return applicationName;
-}
-
-
-- (NSString*) applicationVersionString {
- NSString* string = [[[NSBundle mainBundle] localizedInfoDictionary] valueForKey: @"CFBundleShortVersionString"];
-
- if (!string)
- string = [[[NSBundle mainBundle] infoDictionary] valueForKey: @"CFBundleShortVersionString"];
-
- return string;
-}
-
-- (NSString *) applicationVersion {
- NSString* string = [[[NSBundle mainBundle] localizedInfoDictionary] valueForKey: @"CFBundleVersion"];
-
- if (!string)
- string = [[[NSBundle mainBundle] infoDictionary] valueForKey: @"CFBundleVersion"];
-
- return string;
-}
-
-@end
-
-
-
-
-@implementation BWQuincyUI
-
-- (id)init:(id)delegate crashFile:(NSString *)crashFile companyName:(NSString *)companyName applicationName:(NSString *)applicationName {
-
- self = [super initWithWindowNibName: @"BWQuincyMain"];
-
- if ( self != nil) {
- _xml = nil;
- _delegate = delegate;
- _crashFile = crashFile;
- _companyName = companyName;
- _applicationName = applicationName;
- [self setShowComments: YES];
- [self setShowDetails: NO];
-
- NSRect windowFrame = [[self window] frame];
- windowFrame.size = NSMakeSize(windowFrame.size.width, windowFrame.size.height - kDetailsHeight);
- windowFrame.origin.y -= kDetailsHeight;
- [[self window] setFrame: windowFrame
- display: YES
- animate: NO];
-
- }
- return self;
-}
-
-
-- (void) endCrashReporter {
- [self close];
-}
-
-
-- (IBAction) showComments: (id) sender {
- NSRect windowFrame = [[self window] frame];
-
- if ([sender intValue]) {
- [self setShowComments: NO];
-
- windowFrame.size = NSMakeSize(windowFrame.size.width, windowFrame.size.height + kCommentsHeight);
- windowFrame.origin.y -= kCommentsHeight;
- [[self window] setFrame: windowFrame
- display: YES
- animate: YES];
-
- [self setShowComments: YES];
- } else {
- [self setShowComments: NO];
-
- windowFrame.size = NSMakeSize(windowFrame.size.width, windowFrame.size.height - kCommentsHeight);
- windowFrame.origin.y += kCommentsHeight;
- [[self window] setFrame: windowFrame
- display: YES
- animate: YES];
- }
-}
-
-
-- (IBAction) showDetails:(id)sender {
- NSRect windowFrame = [[self window] frame];
+ NSString *applicationName = [[[NSBundle mainBundle] localizedInfoDictionary] valueForKey: @"CFBundleExecutable"];
- windowFrame.size = NSMakeSize(windowFrame.size.width, windowFrame.size.height + kDetailsHeight);
- windowFrame.origin.y -= kDetailsHeight;
- [[self window] setFrame: windowFrame
- display: YES
- animate: YES];
-
- [self setShowDetails:YES];
+ if (!applicationName)
+ applicationName = [[[NSBundle mainBundle] infoDictionary] valueForKey: @"CFBundleExecutable"];
+ return applicationName;
}
-- (IBAction) hideDetails:(id)sender {
- NSRect windowFrame = [[self window] frame];
-
- [self setShowDetails:NO];
-
- windowFrame.size = NSMakeSize(windowFrame.size.width, windowFrame.size.height - kDetailsHeight);
- windowFrame.origin.y += kDetailsHeight;
- [[self window] setFrame: windowFrame
- display: YES
- animate: YES];
-}
-
-
-- (IBAction) cancelReport:(id)sender {
- [self endCrashReporter];
- [NSApp stopModal];
-
- if ( _delegate != nil && [_delegate respondsToSelector:@selector(cancelReport)])
- [_delegate cancelReport];
-}
-
-- (void) _sendReportAfterDelay {
- if ( _delegate != nil && [_delegate respondsToSelector:@selector(sendReport:)]) {
- NSString *notes = [NSString stringWithFormat:@"Comments:\n%@\n\nConsole:\n%@", [descriptionTextField stringValue], _consoleContent];
-
- [_delegate sendReportCrash:_crashLogContent description:notes];
- }
-}
-
-- (IBAction) submitReport:(id)sender {
- [submitButton setEnabled:NO];
-
- [[self window] makeFirstResponder: nil];
-
- [self performSelector:@selector(_sendReportAfterDelay) withObject:nil afterDelay:0.01];
-
- [self endCrashReporter];
- [NSApp stopModal];
-}
-
-
-- (void) askCrashReportDetails {
- NSError *error;
-
- [[self window] setTitle:[NSString stringWithFormat:NSLocalizedString(@"Problem Report for %@", @"Window title"), _applicationName]];
-
- [[descriptionTextField cell] setPlaceholderString:NSLocalizedString(@"Please describe any steps needed to trigger the problem", @"User description placeholder")];
- [noteText setStringValue:NSLocalizedString(@"No personal information will be sent with this report.", @"Note text")];
-
- // get the crash log
- NSString *crashLogs = [NSString stringWithContentsOfFile:_crashFile encoding:NSUTF8StringEncoding error:&error];
- NSString *lastCrash = [[crashLogs componentsSeparatedByString: @"**********\n\n"] lastObject];
-
- _crashLogContent = lastCrash;
-
- // get the console log
- NSEnumerator *theEnum = [[[NSString stringWithContentsOfFile:@"/private/var/log/system.log" encoding:NSUTF8StringEncoding error:&error] componentsSeparatedByString: @"\n"] objectEnumerator];
- NSString* currentObject;
- NSMutableArray* applicationStrings = [NSMutableArray array];
-
- NSString* searchString = [[_delegate applicationName] stringByAppendingString:@"["];
- while ( (currentObject = [theEnum nextObject]) ) {
- if ([currentObject rangeOfString:searchString].location != NSNotFound)
- [applicationStrings addObject: currentObject];
- }
-
- _consoleContent = [NSMutableString string];
-
- NSInteger i;
- for(i = ((NSInteger)[applicationStrings count])-1; (i>=0 && i>((NSInteger)[applicationStrings count])-100); i--) {
- [_consoleContent appendString:[applicationStrings objectAtIndex:i]];
- [_consoleContent appendString:@"\n"];
- }
-
- // Now limit the content to CRASHREPORTSENDER_MAX_CONSOLE_SIZE (default: 50kByte)
- if ([_consoleContent length] > CRASHREPORTSENDER_MAX_CONSOLE_SIZE) {
- _consoleContent = (NSMutableString *)[_consoleContent substringWithRange:NSMakeRange([_consoleContent length]-CRASHREPORTSENDER_MAX_CONSOLE_SIZE-1, CRASHREPORTSENDER_MAX_CONSOLE_SIZE)];
- }
-
- [crashLogTextView setString:[NSString stringWithFormat:@"%@\n\n%@", _crashLogContent, _consoleContent]];
+- (NSString*) applicationVersionString {
+ NSString* string = [[[NSBundle mainBundle] localizedInfoDictionary] valueForKey: @"CFBundleShortVersionString"];
+ if (!string)
+ string = [[[NSBundle mainBundle] infoDictionary] valueForKey: @"CFBundleShortVersionString"];
- NSBeep();
- [NSApp runModalForWindow:[self window]];
-}
-
-
-- (void)dealloc {
- _companyName = nil;
- _delegate = nil;
-
- [super dealloc];
-}
-
-
-- (BOOL)showComments {
- return showComments;
+ return string;
}
-
-- (void)setShowComments:(BOOL)value {
- showComments = value;
-}
-
-
-- (BOOL)showDetails {
- return showDetails;
-}
-
-
-- (void)setShowDetails:(BOOL)value {
- showDetails = value;
-}
-
-#pragma mark NSTextField Delegate
-
-- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector {
- BOOL commandHandled = NO;
+- (NSString *) applicationVersion {
+ NSString* string = [[[NSBundle mainBundle] localizedInfoDictionary] valueForKey: @"CFBundleVersion"];
- if (commandSelector == @selector(insertNewline:)) {
- [textView insertNewlineIgnoringFieldEditor:self];
- commandHandled = YES;
- }
+ if (!string)
+ string = [[[NSBundle mainBundle] infoDictionary] valueForKey: @"CFBundleVersion"];
- return commandHandled;
+ return string;
}
@end
-
View
76 External Source/Quincy/BWQuincyUI.h
@@ -0,0 +1,76 @@
+/*
+ * Author: Andreas Linde <mail@andreaslinde.de>
+ * Kent Sutherland
+ *
+ * Copyright (c) 2011 Andreas Linde & Kent Sutherland.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@class BWQuincyManager;
+
+@interface BWQuincyUI : NSWindowController {
+ IBOutlet NSTextField *descriptionTextField;
+ IBOutlet NSTextView *crashLogTextView;
+
+ IBOutlet NSTextField *noteText;
+
+ IBOutlet NSButton *showButton;
+ IBOutlet NSButton *hideButton;
+ IBOutlet NSButton *cancelButton;
+ IBOutlet NSButton *submitButton;
+
+ BWQuincyManager *_quincyManager;
+
+ NSString *_xml;
+
+ NSString *_crashFile;
+ NSString *_companyName;
+ NSString *_applicationName;
+
+ NSMutableString *_consoleContent;
+ NSString *_crashLogContent;
+
+ BOOL showComments;
+ BOOL showDetails;
+}
+
+- (id)initWithManager:(BWQuincyManager *)quincyManager crashFile:(NSString *)crashFile companyName:(NSString *)companyName applicationName:(NSString *)applicationName;
+
+- (void) askCrashReportDetails;
+
+- (IBAction) cancelReport:(id)sender;
+- (IBAction) submitReport:(id)sender;
+- (IBAction) showDetails:(id)sender;
+- (IBAction) hideDetails:(id)sender;
+- (IBAction) showComments:(id)sender;
+
+- (BOOL)showComments;
+- (void)setShowComments:(BOOL)value;
+
+- (BOOL)showDetails;
+- (void)setShowDetails:(BOOL)value;
+
+@end
View
251 External Source/Quincy/BWQuincyUI.m
@@ -0,0 +1,251 @@
+/*
+ * Author: Andreas Linde <mail@andreaslinde.de>
+ * Kent Sutherland
+ *
+ * Copyright (c) 2011 Andreas Linde & Kent Sutherland.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#import "BWQuincyUI.h"
+#import "BWQuincyManager.h"
+#import <sys/sysctl.h>
+
+#define CRASHREPORTSENDER_MAX_CONSOLE_SIZE 50000
+
+@interface BWQuincyUI(private)
+- (void) askCrashReportDetails;
+- (void) endCrashReporter;
+@end
+
+const CGFloat kCommentsHeight = 105;
+const CGFloat kDetailsHeight = 285;
+
+@implementation BWQuincyUI
+
+- (id)initWithManager:(BWQuincyManager *)quincyManager crashFile:(NSString *)crashFile companyName:(NSString *)companyName applicationName:(NSString *)applicationName {
+
+ self = [super initWithWindowNibName: @"BWQuincyMain"];
+
+ if ( self != nil) {
+ _xml = nil;
+ _quincyManager = quincyManager;
+ _crashFile = crashFile;
+ _companyName = companyName;
+ _applicationName = applicationName;
+ [self setShowComments: YES];
+ [self setShowDetails: NO];
+
+ NSRect windowFrame = [[self window] frame];
+ windowFrame.size = NSMakeSize(windowFrame.size.width, windowFrame.size.height - kDetailsHeight);
+ windowFrame.origin.y -= kDetailsHeight;
+ [[self window] setFrame: windowFrame
+ display: YES
+ animate: NO];
+
+ }
+ return self;
+}
+
+
+- (void)awakeFromNib
+{
+ crashLogTextView.editable = NO;
+ crashLogTextView.selectable = NO;
+ crashLogTextView.automaticSpellingCorrectionEnabled = NO;
+}
+
+
+- (void) endCrashReporter {
+ [self close];
+}
+
+
+- (IBAction) showComments: (id) sender {
+ NSRect windowFrame = [[self window] frame];
+
+ if ([sender intValue]) {
+ [self setShowComments: NO];
+
+ windowFrame.size = NSMakeSize(windowFrame.size.width, windowFrame.size.height + kCommentsHeight);
+ windowFrame.origin.y -= kCommentsHeight;
+ [[self window] setFrame: windowFrame
+ display: YES
+ animate: YES];
+
+ [self setShowComments: YES];
+ } else {
+ [self setShowComments: NO];
+
+ windowFrame.size = NSMakeSize(windowFrame.size.width, windowFrame.size.height - kCommentsHeight);
+ windowFrame.origin.y += kCommentsHeight;
+ [[self window] setFrame: windowFrame
+ display: YES
+ animate: YES];
+ }
+}
+
+
+- (IBAction) showDetails:(id)sender {
+ NSRect windowFrame = [[self window] frame];
+
+ windowFrame.size = NSMakeSize(windowFrame.size.width, windowFrame.size.height + kDetailsHeight);
+ windowFrame.origin.y -= kDetailsHeight;
+ [[self window] setFrame: windowFrame
+ display: YES
+ animate: YES];
+
+ [self setShowDetails:YES];
+
+}
+
+
+- (IBAction) hideDetails:(id)sender {
+ NSRect windowFrame = [[self window] frame];
+
+ [self setShowDetails:NO];
+
+ windowFrame.size = NSMakeSize(windowFrame.size.width, windowFrame.size.height - kDetailsHeight);
+ windowFrame.origin.y += kDetailsHeight;
+ [[self window] setFrame: windowFrame
+ display: YES
+ animate: YES];
+}
+
+
+- (IBAction) cancelReport:(id)sender {
+ [self endCrashReporter];
+ [NSApp stopModal];
+
+ [_quincyManager cancelReport];
+}
+
+- (void) _sendReportAfterDelay {
+ NSString *notes = [NSString stringWithFormat:@"Comments:\n%@\n\nConsole:\n%@", [descriptionTextField stringValue], _consoleContent];
+
+ [_quincyManager sendReportCrash:_crashLogContent description:notes];
+ [_crashLogContent release];
+ _crashLogContent = nil;
+}
+
+- (IBAction) submitReport:(id)sender {
+ [submitButton setEnabled:NO];
+
+ [[self window] makeFirstResponder: nil];
+
+ [self performSelector:@selector(_sendReportAfterDelay) withObject:nil afterDelay:0.01];
+
+ [self endCrashReporter];
+ [NSApp stopModal];
+}
+
+
+- (void) askCrashReportDetails {
+ NSError *error;
+
+ [[self window] setTitle:[NSString stringWithFormat:NSLocalizedString(@"Problem Report for %@", @"Window title"), _applicationName]];
+
+ [[descriptionTextField cell] setPlaceholderString:NSLocalizedString(@"Please describe any steps needed to trigger the problem", @"User description placeholder")];
+ [noteText setStringValue:NSLocalizedString(@"No personal information will be sent with this report.", @"Note text")];
+
+ // get the crash log
+ NSString *crashLogs = [NSString stringWithContentsOfFile:_crashFile encoding:NSUTF8StringEncoding error:&error];
+ NSString *lastCrash = [[crashLogs componentsSeparatedByString: @"**********\n\n"] lastObject];
+
+ _crashLogContent = [lastCrash retain];
+
+ // get the console log
+ NSEnumerator *theEnum = [[[NSString stringWithContentsOfFile:@"/private/var/log/system.log" encoding:NSUTF8StringEncoding error:&error] componentsSeparatedByString: @"\n"] objectEnumerator];
+ NSString* currentObject;
+ NSMutableArray* applicationStrings = [NSMutableArray array];
+
+ NSString* searchString = [_applicationName stringByAppendingString:@"["];
+ while ( (currentObject = [theEnum nextObject]) ) {
+ if ([currentObject rangeOfString:searchString].location != NSNotFound)
+ [applicationStrings addObject: currentObject];
+ }
+
+ _consoleContent = [[NSMutableString alloc] initWithString:@""];
+
+ NSInteger i;
+ for(i = ((NSInteger)[applicationStrings count])-1; (i>=0 && i>((NSInteger)[applicationStrings count])-100); i--) {
+ [_consoleContent appendString:[applicationStrings objectAtIndex:i]];
+ [_consoleContent appendString:@"\n"];
+ }
+
+ // Now limit the content to CRASHREPORTSENDER_MAX_CONSOLE_SIZE (default: 50kByte)
+ if ([_consoleContent length] > CRASHREPORTSENDER_MAX_CONSOLE_SIZE) {
+ _consoleContent = (NSMutableString *)[_consoleContent substringWithRange:NSMakeRange([_consoleContent length]-CRASHREPORTSENDER_MAX_CONSOLE_SIZE-1, CRASHREPORTSENDER_MAX_CONSOLE_SIZE)];
+ }
+
+ [crashLogTextView setString:[NSString stringWithFormat:@"%@\n\n%@", _crashLogContent, _consoleContent]];
+
+
+ NSBeep();
+ [NSApp runModalForWindow:[self window]];
+}
+
+
+- (void)dealloc {
+ [_consoleContent release]; _consoleContent = nil;
+ _companyName = nil;
+ _quincyManager = nil;
+
+ [super dealloc];
+}
+
+
+- (BOOL)showComments {
+ return showComments;
+}
+
+
+- (void)setShowComments:(BOOL)value {
+ showComments = value;
+}
+
+
+- (BOOL)showDetails {
+ return showDetails;
+}
+
+
+- (void)setShowDetails:(BOOL)value {
+ showDetails = value;
+}
+
+#pragma mark NSTextField Delegate
+
+- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector {
+ BOOL commandHandled = NO;
+
+ if (commandSelector == @selector(insertNewline:)) {
+ [textView insertNewlineIgnoringFieldEditor:self];
+ commandHandled = YES;
+ }
+
+ return commandHandled;
+}
+
+@end
+

0 comments on commit bd0450a

Please sign in to comment.