]> git.sesse.net Git - vlc/blob - modules/gui/macosx/BWQuincyUI.m
macosx: Fix drawing issues with podcast controls and dropzone
[vlc] / modules / gui / macosx / BWQuincyUI.m
1 /*
2  * Author: Andreas Linde <mail@andreaslinde.de>
3  *         Kent Sutherland
4  *
5  * Copyright (c) 2011 Andreas Linde & Kent Sutherland.
6  * All rights reserved.
7  *
8  * Permission is hereby granted, free of charge, to any person
9  * obtaining a copy of this software and associated documentation
10  * files (the "Software"), to deal in the Software without
11  * restriction, including without limitation the rights to use,
12  * copy, modify, merge, publish, distribute, sublicense, and/or sell
13  * copies of the Software, and to permit persons to whom the
14  * Software is furnished to do so, subject to the following
15  * conditions:
16  *
17  * The above copyright notice and this permission notice shall be
18  * included in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27  * OTHER DEALINGS IN THE SOFTWARE.
28  */
29
30 #import "intf.h"
31 #import "BWQuincyUI.h"
32 #import "BWQuincyManager.h"
33 #import <sys/sysctl.h>
34
35 #define CRASHREPORTSENDER_MAX_CONSOLE_SIZE 50000
36
37 @interface BWQuincyUI(private)
38 - (void) askCrashReportDetails;
39 - (void) endCrashReporter;
40 @end
41
42 const CGFloat kCommentsHeight = 105;
43 const CGFloat kDetailsHeight = 285;
44
45 @implementation BWQuincyUI
46
47 - (id)initWithManager:(BWQuincyManager *)quincyManager crashFile:(NSString *)crashFile companyName:(NSString *)companyName applicationName:(NSString *)applicationName {
48
49   self = [super initWithWindowNibName: @"BWQuincyMain"];
50
51   if ( self != nil) {
52     _xml = nil;
53     _quincyManager = quincyManager;
54     _crashFile = crashFile;
55     _companyName = companyName;
56     _applicationName = applicationName;
57     [self setShowComments: YES];
58     [self setShowDetails: NO];
59
60     NSRect windowFrame = [[self window] frame];
61     windowFrame.size = NSMakeSize(windowFrame.size.width, windowFrame.size.height - kDetailsHeight);
62     windowFrame.origin.y -= kDetailsHeight;
63     [[self window] setFrame: windowFrame
64                     display: YES
65                     animate: NO];
66
67   }
68   return self;
69 }
70
71
72 - (void)awakeFromNib
73 {
74         crashLogTextView.editable = NO;
75         crashLogTextView.selectable = NO;
76         crashLogTextView.automaticSpellingCorrectionEnabled = NO;
77
78     [showButton setTitle:_NS("Show Details")];
79     [hideButton setTitle:_NS("Hide Details")];
80     [cancelButton setTitle:_NS("Cancel")];
81     [submitButton setTitle:_NS("Send")];
82     [titleText setStringValue:[NSString stringWithFormat:_NS("%@ unexpectedly quit the last time it was run. Would you like to send a crash report to %@?"), _applicationName, _companyName]];
83     [commentsText setStringValue:_NS("Comments")];
84     [detailsText setStringValue:_NS("Problem details and system configuration")];
85 }
86
87
88 - (void) endCrashReporter {
89   [self close];
90 }
91
92
93 - (IBAction) showComments: (id) sender {
94   NSRect windowFrame = [[self window] frame];
95
96   if ([sender intValue]) {
97     [self setShowComments: NO];
98
99     windowFrame.size = NSMakeSize(windowFrame.size.width, windowFrame.size.height + kCommentsHeight);
100     windowFrame.origin.y -= kCommentsHeight;
101     [[self window] setFrame: windowFrame
102                     display: YES
103                     animate: YES];
104
105     [self setShowComments: YES];
106   } else {
107     [self setShowComments: NO];
108
109     windowFrame.size = NSMakeSize(windowFrame.size.width, windowFrame.size.height - kCommentsHeight);
110     windowFrame.origin.y += kCommentsHeight;
111     [[self window] setFrame: windowFrame
112                     display: YES
113                     animate: YES];
114   }
115 }
116
117
118 - (IBAction) showDetails:(id)sender {
119   NSRect windowFrame = [[self window] frame];
120
121   windowFrame.size = NSMakeSize(windowFrame.size.width, windowFrame.size.height + kDetailsHeight);
122   windowFrame.origin.y -= kDetailsHeight;
123   [[self window] setFrame: windowFrame
124                   display: YES
125                   animate: YES];
126
127   [self setShowDetails:YES];
128
129 }
130
131
132 - (IBAction) hideDetails:(id)sender {
133   NSRect windowFrame = [[self window] frame];
134
135   [self setShowDetails:NO];
136
137   windowFrame.size = NSMakeSize(windowFrame.size.width, windowFrame.size.height - kDetailsHeight);
138   windowFrame.origin.y += kDetailsHeight;
139   [[self window] setFrame: windowFrame
140                   display: YES
141                   animate: YES];
142 }
143
144
145 - (IBAction) cancelReport:(id)sender {
146   [self endCrashReporter];
147   [NSApp stopModal];
148
149   [_quincyManager cancelReport];
150 }
151
152 - (void) _sendReportAfterDelay {
153   NSString *notes = [NSString stringWithFormat:@"Comments:\n%@\n\nConsole:\n%@", [descriptionTextField stringValue], _consoleContent];
154
155   [_quincyManager sendReportCrash:_crashLogContent description:notes];
156   [_crashLogContent release];
157   _crashLogContent = nil;
158 }
159
160 - (IBAction) submitReport:(id)sender {
161   [submitButton setEnabled:NO];
162
163   [[self window] makeFirstResponder: nil];
164
165   [self performSelector:@selector(_sendReportAfterDelay) withObject:nil afterDelay:0.01];
166
167   [self endCrashReporter];
168   [NSApp stopModal];
169 }
170
171
172 - (void) askCrashReportDetails {
173   NSError *error;
174
175    [[self window] setTitle:[NSString stringWithFormat:_NS("Problem Report for %@"), _applicationName]];
176
177    [[descriptionTextField cell] setPlaceholderString:_NS("Please describe any steps needed to trigger the problem")];
178    [noteText setStringValue:_NS("No personal information will be sent with this report.")];
179
180   // get the crash log
181   NSString *crashLogs = [NSString stringWithContentsOfFile:_crashFile encoding:NSUTF8StringEncoding error:&error];
182   NSString *lastCrash = [[crashLogs componentsSeparatedByString: @"**********\n\n"] lastObject];
183
184   _crashLogContent = [lastCrash retain];
185
186   // get the console log
187   NSEnumerator *theEnum = [[[NSString stringWithContentsOfFile:@"/private/var/log/system.log" encoding:NSUTF8StringEncoding error:&error] componentsSeparatedByString: @"\n"] objectEnumerator];
188   NSString* currentObject;
189   NSMutableArray* applicationStrings = [NSMutableArray array];
190
191   NSString* searchString = [_applicationName stringByAppendingString:@"["];
192   while ( (currentObject = [theEnum nextObject]) ) {
193     if ([currentObject rangeOfString:searchString].location != NSNotFound)
194       [applicationStrings addObject: currentObject];
195   }
196
197   _consoleContent = [[NSMutableString alloc] initWithString:@""];
198
199   NSInteger i;
200   for(i = ((NSInteger)[applicationStrings count])-1; (i>=0 && i>((NSInteger)[applicationStrings count])-100); i--) {
201     [_consoleContent appendString:[applicationStrings objectAtIndex:i]];
202     [_consoleContent appendString:@"\n"];
203   }
204
205   // Now limit the content to CRASHREPORTSENDER_MAX_CONSOLE_SIZE (default: 50kByte)
206   if ([_consoleContent length] > CRASHREPORTSENDER_MAX_CONSOLE_SIZE) {
207     _consoleContent = (NSMutableString *)[_consoleContent substringWithRange:NSMakeRange([_consoleContent length]-CRASHREPORTSENDER_MAX_CONSOLE_SIZE-1, CRASHREPORTSENDER_MAX_CONSOLE_SIZE)]; 
208   }
209
210   [crashLogTextView setString:[NSString stringWithFormat:@"%@\n\n%@", _crashLogContent, _consoleContent]];
211
212   [NSApp runModalForWindow:[self window]];
213 }
214
215
216 - (void)dealloc {
217   [_consoleContent release]; _consoleContent = nil;
218   _companyName = nil;
219   _quincyManager = nil;
220
221   [super dealloc];
222 }
223
224
225 - (BOOL)showComments {
226   return showComments;
227 }
228
229
230 - (void)setShowComments:(BOOL)value {
231   showComments = value;
232 }
233
234
235 - (BOOL)showDetails {
236   return showDetails;
237 }
238
239
240 - (void)setShowDetails:(BOOL)value {
241   showDetails = value;
242 }
243
244 #pragma mark NSTextField Delegate
245
246 - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector {
247   BOOL commandHandled = NO;
248
249   if (commandSelector == @selector(insertNewline:)) {
250     [textView insertNewlineIgnoringFieldEditor:self];
251     commandHandled = YES;
252   }
253
254   return commandHandled;
255 }
256
257 @end
258