adium 5667:b9eb03f69530: Resurrect the old crash reporter and re...
commits at adium.im
commits at adium.im
Thu Jul 18 00:59:45 UTC 2013
details: http://hg.adium.im/adium/rev/b9eb03f69530
revision: 5667:b9eb03f69530
branch: adium-1.6
author: Frank Dowsett <wixardy at adium.im>
date: Wed Jul 17 20:55:11 2013 -0400
Resurrect the old crash reporter and redo it to use HockeyApp for crashlog viewing. Fixes #1540
The old crash reporter was a separate process and replaced the system crash dialog, this one just sends a crash log (not automatically) the next time Adium is launched. We aren't using the HockeyApp SDK for this since there's some custom stuff we do in our crash reporter, e.g. check for updates and maybe launch the Xtras manager.
diffs (truncated from 17398 to 1000 lines):
diff -r 554440dd29ca -r b9eb03f69530 Adium.xcodeproj/project.pbxproj
--- a/Adium.xcodeproj/project.pbxproj Sat Jul 13 12:46:57 2013 -0400
+++ b/Adium.xcodeproj/project.pbxproj Wed Jul 17 20:55:11 2013 -0400
@@ -1027,6 +1027,9 @@
5A1E3A1214DCE60400724574 /* Preferences-Xtras.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5A1E3A1114DCE60400724574 /* Preferences-Xtras.xib */; };
5A22D6E214834F44004E15F7 /* AIFacebookXMPPAccountView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5A22D6E014834F44004E15F7 /* AIFacebookXMPPAccountView.xib */; };
5A27FA7E14A272330063489D /* pref-messagestyle.png in Resources */ = {isa = PBXBuildFile; fileRef = 5A27FA7A14A272330063489D /* pref-messagestyle.png */; };
+ 5A2FF9B81797336100C2EF12 /* crashDuck.icns in Resources */ = {isa = PBXBuildFile; fileRef = 5A72C1A117013D9400075BBA /* crashDuck.icns */; };
+ 5A2FF9BC1797337200C2EF12 /* CrashReporter.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5A72C1A517013D9400075BBA /* CrashReporter.xib */; };
+ 5A2FF9BD1797351500C2EF12 /* AICrashReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A72C1AD17013D9400075BBA /* AICrashReporter.m */; };
5A3B4D7916D878AC00903E40 /* NSString+STTwitter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A3B4D6C16D878AB00903E40 /* NSString+STTwitter.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
5A3B4D7A16D878AC00903E40 /* STTwitterAPIWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A3B4D6E16D878AB00903E40 /* STTwitterAPIWrapper.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
5A3B4D7C16D878AC00903E40 /* STTwitterOAuth.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A3B4D7216D878AB00903E40 /* STTwitterOAuth.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
@@ -3934,6 +3937,14 @@
5A5F8BBB12D560E400019727 /* AIDockNameOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIDockNameOverlay.h; path = "Plugins/Dock Icon Badging/AIDockNameOverlay.h"; sourceTree = "<group>"; };
5A5F8BBC12D560E400019727 /* AIDockNameOverlay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIDockNameOverlay.m; path = "Plugins/Dock Icon Badging/AIDockNameOverlay.m"; sourceTree = "<group>"; };
5A675E8D13C00AEA006192C5 /* Preferences-General.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = "Preferences-General.xib"; path = "Resources/Preferences-General.xib"; sourceTree = "<group>"; };
+ 5A72C1A117013D9400075BBA /* crashDuck.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = crashDuck.icns; sourceTree = "<group>"; };
+ 5A72C1A217013D9400075BBA /* crashDuck.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = crashDuck.png; sourceTree = "<group>"; };
+ 5A72C1A617013D9400075BBA /* cs */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = cs; path = cs.lproj/CrashReporter.xib; sourceTree = "<group>"; };
+ 5A72C1A817013D9400075BBA /* de */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = de; path = de.lproj/CrashReporter.xib; sourceTree = "<group>"; };
+ 5A72C1AA17013D9400075BBA /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/CrashReporter.xib; sourceTree = "<group>"; };
+ 5A72C1AC17013D9400075BBA /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = fr.lproj/CrashReporter.xib; sourceTree = "<group>"; };
+ 5A72C1AD17013D9400075BBA /* AICrashReporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AICrashReporter.m; path = "Other/Adium Crash Reporter/AICrashReporter.m"; sourceTree = "<group>"; };
+ 5A72C1AE17013D9400075BBA /* AICrashReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AICrashReporter.h; path = "Other/Adium Crash Reporter/AICrashReporter.h"; sourceTree = "<group>"; };
5A7642A811E044B900E5E0AF /* sk_SK */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xib; name = sk_SK; path = Resources/sk_SK.lproj/AccountProxy.xib; sourceTree = "<group>"; };
5A7642A911E044B900E5E0AF /* sk_SK */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xib; name = sk_SK; path = Resources/sk_SK.lproj/AIAdvancedInspectorPane.xib; sourceTree = "<group>"; };
5A7642AB11E044B900E5E0AF /* sk_SK */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = sk_SK; path = Resources/sk_SK.lproj/Buttons.strings; sourceTree = "<group>"; };
@@ -7120,6 +7131,7 @@
4BCAC53407B59F9C006641B9 /* Other */ = {
isa = PBXGroup;
children = (
+ 5A72C19C17013B1A00075BBA /* Crash Reporter */,
11BE28E30FCC7DA8000E6A10 /* Image Uploading */,
34FDD6E305632BFD00F5B30F /* ESFileTransferController.h */,
34FDD6E405632BFD00F5B30F /* ESFileTransferController.m */,
@@ -7406,6 +7418,27 @@
name = Vendor;
sourceTree = "<group>";
};
+ 5A72C19C17013B1A00075BBA /* Crash Reporter */ = {
+ isa = PBXGroup;
+ children = (
+ 5A72C1A017013D9400075BBA /* Resources */,
+ 5A72C1AD17013D9400075BBA /* AICrashReporter.m */,
+ 5A72C1AE17013D9400075BBA /* AICrashReporter.h */,
+ );
+ name = "Crash Reporter";
+ sourceTree = "<group>";
+ };
+ 5A72C1A017013D9400075BBA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 5A72C1A117013D9400075BBA /* crashDuck.icns */,
+ 5A72C1A217013D9400075BBA /* crashDuck.png */,
+ 5A72C1A517013D9400075BBA /* CrashReporter.xib */,
+ );
+ name = Resources;
+ path = "Other/Adium Crash Reporter/Resources";
+ sourceTree = "<group>";
+ };
5A8A6A46124456B1004965A8 /* Segmented control with menu popup */ = {
isa = PBXGroup;
children = (
@@ -9814,6 +9847,7 @@
110763FA08676D05005987A5 /* BlockEditorWindow.xib in Resources */,
EE147A6D0896B18800A21377 /* ABSearch.png in Resources */,
EE147A790896B32400A21377 /* ABSearch.xib in Resources */,
+ 5A2FF9BC1797337200C2EF12 /* CrashReporter.xib in Resources */,
63C120750910A0DD00C9DB57 /* DefaultXtraReadme.rtf in Resources */,
348F579E0936FA6D00288E41 /* EditStatusGroup.xib in Resources */,
6333699409497DB000970871 /* EmoticonPreviewView.xib in Resources */,
@@ -9878,6 +9912,7 @@
317D83680E89F40500298BDB /* msg-bookmark-chat.tiff in Resources */,
11BD73D30F5A54BB007D438A /* twitter-small.png in Resources */,
11BD73D40F5A54BB007D438A /* twitter.png in Resources */,
+ 5A2FF9B81797336100C2EF12 /* crashDuck.icns in Resources */,
1109634C0F61C1D00064CA0E /* AITwitterReplyWindow.xib in Resources */,
113892270F6B70CA00A7D7DC /* laconica-small.png in Resources */,
113892280F6B70CA00A7D7DC /* laconica.png in Resources */,
@@ -10532,6 +10567,7 @@
34DC88410A7EEE2E003E1636 /* AdiumPreferredAccounts.m in Sources */,
34DC88430A7EEE2E003E1636 /* AdiumServices.m in Sources */,
34DC88450A7EEE2E003E1636 /* AdiumApplescriptRunner.m in Sources */,
+ 5A2FF9BD1797351500C2EF12 /* AICrashReporter.m in Sources */,
34DC884C0A7EEE2E003E1636 /* AdiumContentFiltering.m in Sources */,
34DC884E0A7EEE2E003E1636 /* AdiumFormatting.m in Sources */,
34DC88510A7EEE2E003E1636 /* AdiumTyping.m in Sources */,
@@ -12322,6 +12358,17 @@
name = SearchTerms.plist;
sourceTree = "<group>";
};
+ 5A72C1A517013D9400075BBA /* CrashReporter.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 5A72C1A617013D9400075BBA /* cs */,
+ 5A72C1A817013D9400075BBA /* de */,
+ 5A72C1AA17013D9400075BBA /* en */,
+ 5A72C1AC17013D9400075BBA /* fr */,
+ );
+ name = CrashReporter.xib;
+ sourceTree = "<group>";
+ };
633D50ED0F9D31BD004F491E /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
diff -r 554440dd29ca -r b9eb03f69530 Other/Adium Crash Reporter/AICrashReporter.h
--- a/Other/Adium Crash Reporter/AICrashReporter.h Sat Jul 13 12:46:57 2013 -0400
+++ b/Other/Adium Crash Reporter/AICrashReporter.h Wed Jul 17 20:55:11 2013 -0400
@@ -14,50 +14,27 @@
* write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#define RELATIVE_PATH_TO_CRASH_REPORTER @"/Contents/Resources/Adium Crash Reporter.app"
-#define EXCEPTIONS_PATH [@"~/Library/Logs/CrashReporter/Adium.exception.log" stringByExpandingTildeInPath]
-#define CRASHES_PATH [[NSString stringWithFormat:@"~/Library/Logs/CrashReporter/%@.crash.log", \
- [[NSProcessInfo processInfo] processName]] stringByExpandingTildeInPath]
+ at class AIAutoScrollView, AITextViewWithPlaceholder;
- at class AIAutoScrollView, AITextViewWithPlaceholder, SUStatusChecker;
- at protocol SUStatusCheckerDelegate;
+ at interface AICrashReporter : NSWindowController <NSWindowDelegate> {
+ IBOutlet AIAutoScrollView *scrollView_details;
+ IBOutlet AITextViewWithPlaceholder *textView_details;
- at interface AICrashReporter : NSObject <SUStatusCheckerDelegate> {
- IBOutlet NSWindow *window_MainWindow;
- IBOutlet NSTextField *textField_emailAddress;
- IBOutlet NSTextField *textField_accountIM;
- IBOutlet NSTextField *textField_description;
-
- IBOutlet AIAutoScrollView *scrollView_details;
- IBOutlet AITextViewWithPlaceholder *textView_details;
-
- IBOutlet NSProgressIndicator *progress_sending;
IBOutlet NSButton *button_close;
IBOutlet NSPanel *panel_privacySheet;
IBOutlet NSTextView *textView_crashLog;
- NSString *crashLog; //Current crash log
-
- NSDate *buildDate;
- NSString *buildNumber, *buildUser;
- NSAppleScript *slayerScript;
-
- NSString *adiumPath;
- SUStatusChecker *statusChecker;
-
- BOOL sentCrashLog;
+ NSString *crashLog;
}
-- (void)awakeFromNib;
+ at property (retain) NSString *crashLog;
+
++ (void)checkForCrash;
- (IBAction)showPrivacyDetails:(id)sender;
- (IBAction)closePrivacyDetails:(id)sender;
-- (BOOL)reportCrashForLogAtPath:(NSString *)inPath;
-- (void)sendReport:(NSDictionary *)crashReport;
- (IBAction)send:(id)sender;
-- (void)_loadBuildInformation;
-
@end
diff -r 554440dd29ca -r b9eb03f69530 Other/Adium Crash Reporter/AICrashReporter.m
--- a/Other/Adium Crash Reporter/AICrashReporter.m Sat Jul 13 12:46:57 2013 -0400
+++ b/Other/Adium Crash Reporter/AICrashReporter.m Wed Jul 17 20:55:11 2013 -0400
@@ -20,180 +20,96 @@
#import <AIUtilities/AIFileManagerAdditions.h>
#import <AIUtilities/AIApplicationAdditions.h>
#import <AIUtilities/AIAutoScrollView.h>
-#import <Sparkle/Sparkle.h>
+#import "JSONKit.h"
+#import <sys/sysctl.h>
-#define CRASH_REPORT_URL @"http://www.visualdistortion.org/crash/post.jsp"
-#define KEY_CRASH_EMAIL_ADDRESS @"AdiumCrashReporterEmailAddress"
-#define KEY_CRASH_AIM_ACCOUNT @"AdiumCrashReporterAIMAccount"
+#define CRASH_REPORT_URL @"https://sdk.hockeyapp.net/"
+#define HOCKEY_APP_ID @"a703119f260a58377333db4a07fecadb"
-#define CRASH_REPORT_SLAY_ATTEMPTS 100
-#define CRASH_REPORT_SLAY_INTERVAL 0.1
-
-#define CRASH_LOG_WAIT_ATTEMPTS 100
-#define CRASH_LOG_WAIT_INTERVAL 0.2
-
-#define ADIUM_UPDATE_URL @"http://download.adiumx.com/"
-#define ADIUM_UPDATE_BETA_URL @"http://beta.adiumx.com/"
+#define LAST_CRASH_DATE @"lastKnownCrashDate"
+#define CRASH_LOG_DIRECTORY [@"~/Library/Logs/DiagnosticReports" stringByStandardizingPath]
#define UNABLE_TO_SEND AILocalizedString(@"Unable to send crash report",nil)
- at interface AICrashReporter (PRIVATE)
-- (void)performVersionChecking;
- at end
+ at implementation AICrashReporter
+ at synthesize crashLog;
- at implementation AICrashReporter
++ (void)checkForCrash
+{
+ AICrashReporter *reporter = [[AICrashReporter alloc] init];
+ [reporter _checkForCrash];
+}
-//
-- (id)init
+- (void)_checkForCrash
{
- if ((self = [super init])) {
- slayerScript = [[NSAppleScript alloc] initWithSource:@"tell application \"UserNotificationCenter\" to quit"];
+ // get a list of files beginning with 'Adium' from the crash reporter folder
+ NSFileManager *fm = [[[NSFileManager alloc] init] autorelease];
+ NSArray *files = [fm contentsOfDirectoryAtPath:CRASH_LOG_DIRECTORY error:nil];
+ NSArray *filteredFiles = [files filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF BEGINSWITH[c] 'Adium'"]];
+
+ NSDate *mostRecentCrashDate = [NSDate distantPast];
+ // Enumerate crash files to find most recent crash report
+ for (NSString *file in filteredFiles) {
+ NSDate *date = [[fm attributesOfItemAtPath:[CRASH_LOG_DIRECTORY stringByAppendingPathComponent:file] error:nil] objectForKey:NSFileCreationDate];
+ if ([date compare:mostRecentCrashDate] == NSOrderedDescending) {
+ mostRecentCrashDate = date;
+ [self setCrashLog:file];
+ }
+ [self setCrashLog:file];
}
+
+ // obtain the last known crash date from the prefs
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ NSDate *lastKnownCrashDate = [defaults objectForKey:LAST_CRASH_DATE];
+
+ // check to see if Adium crashed since the last crash (there's a newer crash report)
+ if (lastKnownCrashDate && [mostRecentCrashDate compare:lastKnownCrashDate] == NSOrderedDescending) {
+ [NSBundle loadNibNamed:@"CrashReporter" owner:self];
+
+ // save last crash date
+ [defaults setObject:mostRecentCrashDate forKey:LAST_CRASH_DATE];
+ }
+}
- return self;
-}
-
-//
- (void)dealloc
{
- [buildUser release];
- [buildDate release];
- [buildNumber release];
[crashLog release];
- [slayerScript release];
- [adiumPath release];
- [statusChecker release];
-
[super dealloc];
}
-//
- (void)awakeFromNib
{
- [textView_details setPlaceholderString:AILocalizedString(@"A detailed explanation of what you were doing when Adium crashed (optional)",nil)];
-
+ [textView_details setPlaceholderString:AILocalizedString(@"A detailed explanation of what you were doing when Adium crashed (optional)", nil)];
[scrollView_details setAlwaysDrawFocusRingIfFocused:YES];
-
- //Search for an exception log
- if ([[NSFileManager defaultManager] fileExistsAtPath:EXCEPTIONS_PATH]) {
- [self reportCrashForLogAtPath:EXCEPTIONS_PATH];
- } else {
- //Kill the apple crash reporter
- [NSTimer scheduledTimerWithTimeInterval:CRASH_REPORT_SLAY_INTERVAL
- target:self
- selector:@selector(appleCrashReportSlayer:)
- userInfo:nil
- repeats:YES];
-
- //Wait for a valid crash log to appear
- [NSTimer scheduledTimerWithTimeInterval:CRASH_LOG_WAIT_INTERVAL
- target:self
- selector:@selector(delayedCrashLogDiscovery:)
- userInfo:nil
- repeats:YES];
- }
-
- if ([progress_sending respondsToSelector:@selector(setHidden:)]) {
- [progress_sending setHidden:YES];
- }
+ [self.window makeKeyAndOrderFront:self];
}
-- (BOOL)application:(NSApplication *)app openFile:(NSString *)path {
- [adiumPath release];
- adiumPath = [path retain];
- return YES;
-}
-
-//Actively tries to kill Apple's "Report this crash" dialog
-- (void)appleCrashReportSlayer:(NSTimer *)inTimer
+- (void)windowWillClose:(id)sender
{
- static int countdown = CRASH_REPORT_SLAY_ATTEMPTS;
-
- //Kill the notification app if it's open
- if (countdown-- == 0 || ![[slayerScript executeAndReturnError:nil] booleanValue]) {
- [inTimer invalidate];
- }
-}
-
-#pragma mark Crash log loading
-//Waits for a crash log to be written
-- (void)delayedCrashLogDiscovery:(NSTimer *)inTimer
-{
- static int countdown = CRASH_LOG_WAIT_ATTEMPTS;
-
- //Kill the notification app if it's open
- if (countdown-- == 0 ||
- [self reportCrashForLogAtPath:[@"~/Library/Logs/CrashReporter/Adium.real.crash.log" stringByExpandingTildeInPath]] ||
- [self reportCrashForLogAtPath:[@"~/Library/Logs/CrashReporter/Adium.crash.log" stringByExpandingTildeInPath]]) {
- [inTimer invalidate];
- }
-}
-
-//Display the report crash window for the passed log
-- (BOOL)reportCrashForLogAtPath:(NSString *)inPath
-{
- NSString *emailAddress, *aimAccount;
- NSRange binaryRange;
-
- if ([[NSFileManager defaultManager] fileExistsAtPath:inPath]) {
- NSString *newLog = [NSString stringWithContentsOfFile:inPath];
- if (newLog && [newLog length]) {
- //Hang onto and delete the log
- crashLog = [newLog retain];
- [[NSFileManager defaultManager] trashFileAtPath:inPath];
-
- //Strip off PPC thread state and binary descriptions.. we don't need to send all that
- binaryRange = [crashLog rangeOfString:@"PPC Thread State:"];
- if (binaryRange.location != NSNotFound) {
- NSString *shortLog = [crashLog substringToIndex:binaryRange.location];
- [crashLog release]; crashLog = [shortLog retain];
- }
-
- //Restore the user's email address and account if they've entered it previously
- if ((emailAddress = [[NSUserDefaults standardUserDefaults] objectForKey:KEY_CRASH_EMAIL_ADDRESS])) {
- [textField_emailAddress setStringValue:emailAddress];
- }
- if ((aimAccount = [[NSUserDefaults standardUserDefaults] objectForKey:KEY_CRASH_AIM_ACCOUNT])) {
- [textField_accountIM setStringValue:aimAccount];
- }
-
- //Highlight the existing details text
- [textView_details setSelectedRange:NSMakeRange(0, [[textView_details textStorage] length])
- affinity:NSSelectionAffinityUpstream
- stillSelecting:NO];
-
- //Open our window
- [window_MainWindow makeKeyAndOrderFront:nil];
-
- return YES;
- }
- }
-
- return NO;
+ [self autorelease];
}
#pragma mark Privacy Details
//Display privacy information sheet
- (IBAction)showPrivacyDetails:(id)sender
{
- if (crashLog) {
- NSDictionary *attributes = [NSDictionary dictionaryWithObject:[NSFont systemFontOfSize:11]
- forKey:NSFontAttributeName];
- NSAttributedString *attrLogString = [[[NSAttributedString alloc] initWithString:crashLog
- attributes:attributes] autorelease];
-
- //Fill in crash log
- [[textView_crashLog textStorage] setAttributedString:attrLogString];
-
- //Display the sheet
- [NSApp beginSheet:panel_privacySheet
- modalForWindow:window_MainWindow
- modalDelegate:nil
- didEndSelector:nil
- contextInfo:nil];
- } else {
- NSBeep();
- }
+ NSDictionary *attributes = [NSDictionary dictionaryWithObject:[NSFont systemFontOfSize:11]
+ forKey:NSFontAttributeName];
+
+ NSString *file = [NSString stringWithContentsOfFile:[CRASH_LOG_DIRECTORY stringByAppendingPathComponent:self.crashLog]
+ encoding:NSUTF8StringEncoding error:nil];
+ NSAttributedString *attrLogString = [[[NSAttributedString alloc] initWithString:file
+ attributes:attributes] autorelease];
+
+ //Fill in crash log
+ [[textView_crashLog textStorage] setAttributedString:attrLogString];
+
+ //Display the sheet
+ [NSApp beginSheet:panel_privacySheet
+ modalForWindow:self.window
+ modalDelegate:nil
+ didEndSelector:nil
+ contextInfo:nil];
}
//Close the privacy details sheet
@@ -204,284 +120,151 @@
}
#pragma mark Report sending
-
-/*!
- * @brief Disable the close button and begin spinning the indeterminate progress indicator
- */
-- (void)activateProgressIndicator
-{
- [button_close setHidden:YES];
-
- //Display immediately since we need it for this run loop.
- [[button_close superview] display];
-
- [progress_sending setHidden:NO];
-
- //start the progress spinner (using multi-threading)
- [progress_sending setUsesThreadedAnimation:YES];
- [progress_sending startAnimation:nil];
-}
-
/*!
* @brief User wants to send the report
*/
- (IBAction)send:(id)sender
{
- if ([[textField_emailAddress stringValue] isEqualToString:@""] &&
- [[textField_accountIM stringValue] isEqualToString:@""]) {
- NSBeginCriticalAlertSheet(AILocalizedString(@"Contact Information Required",nil),
- @"OK", nil, nil, window_MainWindow, nil, nil, nil, NULL,
- AILocalizedString(@"Please provide either your email address or IM name in case we need to contact you for additional information (or to suggest a solution).",nil));
- } else {
- //Begin showing progress
- [self activateProgressIndicator];
-
- //Load the build information
- [self _loadBuildInformation];
-
- //Perform version checking; when it is complete or fails, the submission process wil continue
- [self performVersionChecking];
- }
-}
-
-/*!
- * @brief Build the crash report and associated information, then pass it to sendReport:
- */
-- (void)buildAndSendReport
-{
- //If we already sent the crash log, do nothing and just return
- if (sentCrashLog) return;
-
- NSString *shortDescription = [textField_description stringValue];
+ [self.window orderOut:nil];
- //Truncate description field to 300 characters
- if ([shortDescription length] > 300) {
- shortDescription = [shortDescription substringToIndex:300];
- }
-
- //Build the report
- NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] initWithDateFormat:@"%m-%d"
- allowNaturalLanguage:NO] autorelease];
- NSString *buildDateAndInfo = [NSString stringWithFormat:@"%@ (%@)",
- [dateFormatter stringForObjectValue:buildDate],
- (buildUser ? [NSString stringWithFormat:@"%@.%@",buildNumber,buildUser] : buildNumber)];
-
- NSDictionary *crashReport = [NSDictionary dictionaryWithObjectsAndKeys:
- buildDateAndInfo, @"build",
- [textField_emailAddress stringValue], @"email",
- [textField_accountIM stringValue], @"service_name",
- shortDescription, @"short_desc",
- [textView_details string], @"desc",
- crashLog, @"log",
- nil];
-
- //Send
- [self sendReport:crashReport];
+ [self sendReport];
+ [self.window close];
}
/*!
* @brief Send a crash report to the crash reporter web site
*/
-- (void)sendReport:(NSDictionary *)crashReport
+- (void)sendReport
{
- NSMutableString *reportString = [[[NSMutableString alloc] init] autorelease];
- NSEnumerator *enumerator;
- NSString *key;
- NSData *data = nil;
-
- //Compact the fields of the report into a long URL string
- enumerator = [[crashReport allKeys] objectEnumerator];
- while ((key = [enumerator nextObject])) {
- if ([reportString length] != 0) [reportString appendString:@"&"];
- [reportString appendFormat:@"%@=%@", key, [[crashReport objectForKey:key] stringByEncodingURLEscapes]];
- }
+ NSString *reportString = [NSString stringWithContentsOfFile:[CRASH_LOG_DIRECTORY stringByAppendingPathComponent:self.crashLog]
+ encoding:NSUTF8StringEncoding error:nil];
+
+ NSXMLDocument *doc = [[NSXMLDocument alloc] initWithRootElement:[NSXMLElement elementWithName:@"crashes"]];
+ NSXMLElement *crash = [NSXMLElement elementWithName:@"crash"];
+ [crash addChild:[NSXMLElement elementWithName:@"applicationname" stringValue:[self applicationName]]];
+ [crash addChild:[NSXMLElement elementWithName:@"bundleidentifier" stringValue:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"]]];
+ [crash addChild:[NSXMLElement elementWithName:@"systemversion" stringValue:[self OSVersion]]];
+ [crash addChild:[NSXMLElement elementWithName:@"senderversion" stringValue:[self applicationVersion]]];
+ [crash addChild:[NSXMLElement elementWithName:@"version" stringValue:[self applicationVersion]]];
+ [crash addChild:[NSXMLElement elementWithName:@"platform" stringValue:[self modelVersion]]];
+ [crash addChild:[NSXMLElement elementWithName:@"description" stringValue:[textView_details string]]];
+ [crash addChild:[NSXMLElement elementWithName:@"log" stringValue:reportString]];
+ [[doc rootElement] addChild:crash];
+
+ NSMutableURLRequest *request = nil;
+ NSString *boundary = @"----FOO";
+
+ NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@api/2/apps/%@/crashes?sdk=%@&sdk_version=%@&feedbackEnabled=no",
+ CRASH_REPORT_URL,
+ [HOCKEY_APP_ID stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
+ @"Adium",
+ @"1.0"
+ ]];
+ request = [NSMutableURLRequest requestWithURL:url];
+
+ [request setValue:@"Adium" 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];
+ [postBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
+ [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]];
- //
- while (!data || [data length] == 0) {
- NSError *error;
- NSURLResponse *reply;
- NSMutableURLRequest *request;
-
- //Build the URL request
- request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:CRASH_REPORT_URL]
- cachePolicy:NSURLRequestReloadIgnoringCacheData
- timeoutInterval:120];
- [request addValue:@"Adium 2.0a" forHTTPHeaderField:@"X-Adium-Bug-Report"];
- [request setHTTPMethod:@"POST"];
- [request setHTTPBody:[reportString dataUsingEncoding:NSUTF8StringEncoding]];
-
- //Attempt to send report
- data = [NSURLConnection sendSynchronousRequest:request returningResponse:&reply error:&error];
-
- //stop the progress spinner
- [progress_sending stopAnimation:nil];
-
- //Alert on failure, and offer the option to quit or retry
- if (!data || [data length] == 0) {
- if (NSRunAlertPanel(UNABLE_TO_SEND,
- [error localizedDescription],
- AILocalizedString(@"Try Again",nil),
- AILocalizedString(@"Quit",nil),
- nil) == NSAlertAlternateReturn) {
- break;
- }
- } else {
- sentCrashLog = YES;
+ [postBody appendData:[doc XMLData]];
+ [postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
+ [request setHTTPBody:postBody];
+ [doc release];
+
+ NSHTTPURLResponse *response = nil;
+ NSError *error = nil;
+ [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
+
+ //Check for success and offer to try once more if there was an error sending
+ if ([response statusCode] != 201) {
+ NSString *reason = [NSString stringWithFormat:@"%lu: %@\n%@", response.statusCode, [NSHTTPURLResponse localizedStringForStatusCode:response.statusCode], [error localizedDescription] ?: @""];
+ if (NSRunAlertPanel(UNABLE_TO_SEND,
+ reason,
+ AILocalizedString(@"Try Again", nil),
+ AILocalizedString(@"Close", nil),
+ nil) == NSAlertDefaultReturn) {
+ [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
+ if ([response statusCode] != 201) {
+ reason = [NSString stringWithFormat:@"%lu: %@\n%@", response.statusCode, [NSHTTPURLResponse localizedStringForStatusCode:response.statusCode], [error localizedDescription] ?: @""];
+ NSRunAlertPanel(UNABLE_TO_SEND, reason, nil, nil, nil);
+ }
}
- }
+ }
}
-#pragma mark Closing behavior
-//Save some of the information for next time on quit
-- (void)windowWillClose:(id)sender
-{
- //Remember the user's email address, account name
- [[NSUserDefaults standardUserDefaults] setObject:[textField_emailAddress stringValue]
- forKey:KEY_CRASH_EMAIL_ADDRESS];
- [[NSUserDefaults standardUserDefaults] setObject:[textField_accountIM stringValue]
- forKey:KEY_CRASH_AIM_ACCOUNT];
+#pragma mark - System/Application Information
+
+- (NSString *) applicationName {
+ NSString *applicationName = [[[NSBundle mainBundle] localizedInfoDictionary] valueForKey: @"CFBundleExecutable"];
+
+ if (!applicationName)
+ applicationName = [[[NSBundle mainBundle] infoDictionary] valueForKey: @"CFBundleExecutable"];
+
+ return applicationName;
}
-//Terminate if our window is closed
-- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
-{
- return YES;
+
+- (NSString*) applicationVersionString {
+ NSString* string = [[[NSBundle mainBundle] localizedInfoDictionary] valueForKey: @"CFBundleShortVersionString"];
+
+ if (!string)
+ string = [[[NSBundle mainBundle] infoDictionary] valueForKey: @"CFBundleShortVersionString"];
+
+ return string;
}
-#pragma mark Build information
-//Load the current build date and our svn revision
-- (void)_loadBuildInformation
-{
- //Grab the info from our buildnum script
- char *path, unixDate[256], num[256],whoami[256];
- FILE *f;
- if ((path = (char *)[[[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/../../../buildnum"] fileSystemRepresentation]) &&
- ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithUTF8String:path]]) &&
- (f= fopen(path, "r"))) {
- if (f) {
- fscanf(f, "%s | %s | %s", num, unixDate, whoami);
- fclose(f);
- }
+- (NSString *) applicationVersion {
+ NSString* string = [[[NSBundle mainBundle] localizedInfoDictionary] valueForKey: @"CFBundleVersion"];
+
+ if (!string)
+ string = [[[NSBundle mainBundle] infoDictionary] valueForKey: @"CFBundleVersion"];
+
+ return string;
+}
+
+- (NSString *) OSVersion {
+ 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;
+
+ return [NSString stringWithFormat:@"%i.%i.%i", versionMajor, versionMinor, versionBugFix];
+}
+
+- (NSString *) modelVersion {
+ NSString * modelString = nil;
+ int modelInfo[2] = { CTL_HW, HW_MODEL };
+ size_t modelSize;
+
+ if (sysctl(modelInfo,
+ 2,
+ NULL,
+ &modelSize,
+ NULL, 0) == 0) {
+ void * modelData = malloc(modelSize);
- if (*num) {
- buildNumber = [[NSString stringWithFormat:@"%s", num] retain];
- }
-
- if (*unixDate) {
- buildDate = [[NSDate dateWithTimeIntervalSince1970:[[NSString stringWithCString:unixDate] doubleValue]] retain];
- }
-
- if (*whoami) {
- //If the application was built by one of these people, we assume that it is a release, which means we should not show their username in the crash log.
- //Otherwise, this is somebody's custom build, and including the username marks it as such.
- buildUser = [[NSString stringWithFormat:@"%s", whoami] retain];
- if ([buildUser isEqualToString:@"adamiser"] ||
- [buildUser isEqualToString:@"evands"] ||
- [buildUser isEqualToString:@"jmelloy"] ||
- [buildUser isEqualToString:@"durin"] ||
- [buildUser isEqualToString:@"rfackler"] ||
- [buildUser isEqualToString:@"david"]) {
- [buildUser release];
- buildUser = nil;
+ if (modelData) {
+ if (sysctl(modelInfo,
+ 2,
+ modelData,
+ &modelSize,
+ NULL, 0) == 0) {
+ modelString = [NSString stringWithUTF8String:modelData];
}
- }
-
- } else {
- NSLog(@"Unable to open the buildnum file.");
- }
-
- //Default to empty strings if something goes wrong
- if (!buildDate) buildDate = [@"" retain];
- if (!buildNumber) buildNumber = [@"" retain];
-}
-
-/*!
- * @brief Invoked when version information is received
- */
-- (void)finishWithAcceptableVersion:(BOOL)allowReport newVersionString:(NSString *)versionString
-{
- BOOL shouldRelaunchAdium = YES;
-
- if (allowReport) {
- [self buildAndSendReport];
-
- } else {
- if (NSRunAlertPanel(UNABLE_TO_SEND,
- [NSString stringWithFormat:AILocalizedString(@"Your version of Adium is out of date, so crash reporting has been disabled. Your version is %@; the current version is %@. Please update to the latest version, as your crash may have already been fixed.",nil),
- [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"],
- versionString],
- AILocalizedString(@"Update Now",nil),
- AILocalizedString(@"Cancel",nil),
- nil) == NSAlertDefaultReturn) {
- shouldRelaunchAdium = NO;
-#ifdef BETA_RELEASE
- [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:ADIUM_UPDATE_BETA_URL]];
-#else
- [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:ADIUM_UPDATE_URL]];
-#endif
- }
- }
-
- //Relaunch Adium if appropriate
- if (shouldRelaunchAdium) {
- if (adiumPath) {
- [[NSWorkspace sharedWorkspace] openFile:adiumPath];
- } else {
- [[NSWorkspace sharedWorkspace] launchApplication:@"Adium"];
+ free(modelData);
}
}
- //Close our window to terminate
- [window_MainWindow performClose:nil];
-}
-
-
-- (void)versionCheckingTimedOut
-{
- [self statusChecker:nil foundVersion:nil isNewVersion:NO];
-}
-
-/*!
- * @brief Returns the date of the most recent Adium build (contacts adiumx.com asynchronously)
- */
-- (void)performVersionChecking
-{
- statusChecker = [[SUStatusChecker statusCheckerForDelegate:self] retain];
- [self performSelector:@selector(versionCheckingTimedOut)
- withObject:nil
- afterDelay:10.0];
-}
-
-- (void)statusChecker:(SUStatusChecker *)statusChecker foundVersion:(NSString *)versionString isNewVersion:(BOOL)isNewVersion
-{
- //Only send the report if there is not a new version
- if (!versionString) {
- NSLog(@"Adium Crash Reporter warning: Could not retrieve version information from the server. Perhaps it is blocked? Allowing the crash reporter anyways.");
- isNewVersion = NO;
- }
-
- [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(versionCheckingTimedOut) object:nil];
- [self finishWithAcceptableVersion:!isNewVersion newVersionString:versionString];
-}
-
-#ifdef BETA_RELEASE
-#define UPDATE_TYPE_DICT [NSDictionary dictionaryWithObjectsAndKeys:@"type", @"key", @"Update Type", @"visibleKey", @"beta", @"value", @"Beta or Release Versions", @"visibleValue", nil]
-#else
-#define UPDATE_TYPE_DICT [NSDictionary dictionaryWithObjectsAndKeys:@"type", @"key", @"Update Type", @"visibleKey", @"release", @"value", @"Release Versions Only", @"visibleValue", nil]
-#endif
-
-/* This method gives the delegate the opportunity to customize the information that will
-* be included with update checks. Add or remove items from the dictionary as desired.
-* Each entry in profileInfo is an NSDictionary with the following keys:
-* key: The key to be used when reporting data to the server
-* visibleKey: Alternate version of key to be used in UI displays of profile information
-* value: Value to be used when reporting data to the server
-* visibleValue: Alternate version of value to be used in UI displays of profile information.
-*/
-- (NSMutableArray *)updaterCustomizeProfileInfo:(NSMutableArray *)profileInfo
-{
- return [NSMutableArray arrayWithObject:UPDATE_TYPE_DICT];
+ return modelString;
}
@end
diff -r 554440dd29ca -r b9eb03f69530 Other/Adium Crash Reporter/Resources/crashDuck.icns
Binary file Other/Adium Crash Reporter/Resources/crashDuck.icns has changed
diff -r 554440dd29ca -r b9eb03f69530 Other/Adium Crash Reporter/Resources/crashDuck.png
Binary file Other/Adium Crash Reporter/Resources/crashDuck.png has changed
diff -r 554440dd29ca -r b9eb03f69530 Other/Adium Crash Reporter/Resources/cs.lproj/CrashReporter.xib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Other/Adium Crash Reporter/Resources/cs.lproj/CrashReporter.xib Wed Jul 17 20:55:11 2013 -0400
@@ -0,0 +1,465 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4457.6" systemVersion="12E55" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
+ <dependencies>
+ <deployment version="1070" defaultVersion="1060" identifier="macosx"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4457.6"/>
+ </dependencies>
+ <objects>
+ <customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
+ <connections>
+ <action selector="hide:" destination="134" id="152"/>
+ <action selector="hideOtherApplications:" destination="145" id="146"/>
+ <action selector="orderFrontStandardAboutPanel:" destination="58" id="142"/>
+ <action selector="terminate:" destination="136" id="139"/>
+ <action selector="unhideAllApplications:" destination="150" id="153"/>
+ <outlet property="delegate" destination="246" id="306"/>
+ </connections>
+ </customObject>
+ <customObject id="-1" userLabel="First Responder" customClass="FirstResponder">
+ <connections>
+ <action selector="arrangeInFront:" destination="5" id="39"/>
+ <action selector="centerSelectionInVisibleArea:" destination="210" id="245"/>
+ <action selector="checkSpelling:" destination="201" id="225"/>
+ <action selector="clearRecentDocuments:" destination="126" id="127"/>
+ <action selector="copy:" destination="197" id="224"/>
+ <action selector="cut:" destination="199" id="228"/>
+ <action selector="delete:" destination="202" id="235"/>
+ <action selector="paste:" destination="203" id="226"/>
+ <action selector="performClose:" destination="73" id="193"/>
+ <action selector="performFindPanelAction:" destination="209" id="241"/>
+ <action selector="performFindPanelAction:" destination="208" id="242"/>
+ <action selector="performFindPanelAction:" destination="213" id="243"/>
+ <action selector="performFindPanelAction:" destination="221" id="244"/>
+ <action selector="performMiniaturize:" destination="23" id="37"/>
+ <action selector="performZoom:" destination="239" id="240"/>
+ <action selector="print:" destination="78" id="86"/>
+ <action selector="redo:" destination="215" id="231"/>
+ <action selector="runPageLayout:" destination="77" id="87"/>
+ <action selector="selectAll:" destination="198" id="232"/>
+ <action selector="showGuessPanel:" destination="204" id="230"/>
+ <action selector="showHelp:" destination="111" id="122"/>
+ <action selector="startSpeaking:" destination="196" id="233"/>
+ <action selector="stopSpeaking:" destination="195" id="227"/>
+ <action selector="toggleContinuousSpellChecking:" destination="219" id="222"/>
+ <action selector="undo:" destination="207" id="223"/>
+ </connections>
+ </customObject>
+ <customObject id="-3" userLabel="Application"/>
+ <window title="Záznamník havárií Adium" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" wantsToBeColor="NO" animationBehavior="default" id="21" userLabel="Window">
+ <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
+ <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
+ <rect key="contentRect" x="213" y="80" width="600" height="476"/>
+ <rect key="screenRect" x="0.0" y="0.0" width="1280" height="1002"/>
+ <value key="minSize" type="size" width="595" height="412"/>
+ <value key="maxSize" type="size" width="800" height="600"/>
+ <view key="contentView" autoresizesSubviews="NO" id="2">
+ <rect key="frame" x="0.0" y="0.0" width="600" height="476"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <subviews>
+ <progressIndicator horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="100" displayedWhenStopped="NO" bezeled="NO" indeterminate="YES" controlSize="small" style="spinning" id="335">
+ <rect key="frame" x="292" y="22" width="16" height="16"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </progressIndicator>
+ <imageView id="291">
+ <rect key="frame" x="336" y="217" width="280" height="280"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+ <imageCell key="cell" refusesFirstResponder="YES" alignment="left" image="crashDuck" id="361"/>
+ </imageView>
+ <imageView id="259">
+ <rect key="frame" x="694" y="127" width="141" height="87"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="357"/>
+ </imageView>
+ <button verticalHuggingPriority="750" id="247">
+ <rect key="frame" x="345" y="12" width="241" height="32"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+ <buttonCell key="cell" type="push" title="Odeslat záznam a spustit aplikaci Adium" bezelStyle="rounded" alignment="center" borderStyle="border" inset="2" id="354">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="system"/>
+ </buttonCell>
+ </button>
+ <textField verticalHuggingPriority="750" id="249">
+ <rect key="frame" x="107" y="346" width="194" height="22"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" alignment="left" placeholderString="Vaše elektronická adresa (e-mail)" drawsBackground="YES" id="355">
+ <font key="font" metaFont="system"/>
+ <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ <connections>
+ <outlet property="nextKeyView" destination="308" id="320"/>
+ </connections>
+ </textField>
+ <textField verticalHuggingPriority="750" id="258">
+ <rect key="frame" x="105" y="258" width="381" height="22"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" alignment="left" placeholderString="Krátký popis havárie" drawsBackground="YES" id="356">
+ <font key="font" metaFont="system"/>
+ <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ <connections>
+ <outlet property="nextKeyView" destination="328" id="341"/>
+ </connections>
+ </textField>
+ <textField verticalHuggingPriority="750" id="281">
+ <rect key="frame" x="17" y="348" width="85" height="17"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="right" title="Váš e-mail:" id="358">
+ <font key="font" metaFont="system"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <textField verticalHuggingPriority="750" id="282">
+ <rect key="frame" x="17" y="260" width="83" height="17"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="right" title="Popis:" id="359">
+ <font key="font" metaFont="system"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <textField verticalHuggingPriority="750" id="283">
+ <rect key="frame" x="17" y="233" width="83" height="17"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="right" title="Vysvětlení:" id="360">
+ <font key="font" metaFont="system"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <textField verticalHuggingPriority="750" id="295">
+ <rect key="frame" x="17" y="445" width="317" height="17"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="Aplikace Adium byla neočekávaně ukončena" id="362">
+ <font key="font" metaFont="systemBold"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <textField verticalHuggingPriority="750" id="296">
+ <rect key="frame" x="17" y="406" width="317" height="31"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="Prosím udělejte si chvíli čas na odeslání záznamu havárie. Pomůže to k vylepšení aplikace Adium." id="363">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <button verticalHuggingPriority="750" id="297">
+ <rect key="frame" x="259" y="12" width="86" height="32"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+ <buttonCell key="cell" type="push" title="Zavřít" bezelStyle="rounded" alignment="center" borderStyle="border" inset="2" id="364">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="system"/>
+ </buttonCell>
+ </button>
+ <textField verticalHuggingPriority="750" id="307">
+ <rect key="frame" x="17" y="320" width="85" height="17"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="right" title="Vaše AIM:" id="365">
+ <font key="font" metaFont="system"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <textField verticalHuggingPriority="750" id="308">
+ <rect key="frame" x="107" y="318" width="194" height="22"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" alignment="left" placeholderString="Jméno vašeho účtu:" drawsBackground="YES" id="366">
+ <font key="font" metaFont="system"/>
+ <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
More information about the commits
mailing list