1 /*****************************************************************************
2 * DebugMessageVisualizer.m: Mac OS X interface crash reporter
3 *****************************************************************************
4 * Copyright (C) 2004-2013 VLC authors and VideoLAN
7 * Authors: Felix Paul Kühne <fkuehne at videolan dot org>
8 * Pierre d'Herbemont <pdherbemont # videolan org>
9 * Derk-Jan Hartman <hartman at videolan.org>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
26 #import "DebugMessageVisualizer.h"
28 #import <vlc_common.h>
30 static void MsgCallback(void *data, int type, const vlc_log_t *item, const char *format, va_list ap);
32 /*****************************************************************************
33 * MsgCallback: Callback triggered by the core once a new debug message is
34 * ready to be displayed. We store everything in a NSArray in our Cocoa part
36 *****************************************************************************/
38 @interface VLCDebugMessageVisualizer () <NSWindowDelegate>
40 NSMutableArray * _msg_arr;
43 - (void)processReceivedlibvlcMessage:(const vlc_log_t *) item ofType: (int)i_type withStr: (char *)str;
47 static void MsgCallback(void *data, int type, const vlc_log_t *item, const char *format, va_list ap)
51 VLCDebugMessageVisualizer *visualizer = (__bridge VLCDebugMessageVisualizer*)data;
53 int canc = vlc_savecancel();
56 if (vasprintf(&str, format, ap) == -1) {
57 vlc_restorecancel(canc);
61 [visualizer processReceivedlibvlcMessage: item ofType: type withStr: str];
63 vlc_restorecancel(canc);
68 @implementation VLCDebugMessageVisualizer
72 self = [super initWithWindowNibName:@"DebugMessageVisualizer"];
74 _msg_lock = [[NSLock alloc] init];
75 _msg_arr = [NSMutableArray arrayWithCapacity:600];
82 vlc_LogSet( VLCIntf->p_libvlc, NULL, NULL );
87 [self.window setExcludedFromWindowsMenu: YES];
88 [self.window setDelegate: self];
89 [self.window setTitle: _NS("Messages")];
90 [_msgs_save_btn setTitle: _NS("Save this Log...")];
91 [_msgs_refresh_btn setImage: [NSImage imageNamed: NSImageNameRefreshTemplate]];
94 #pragma mark - UI interaction
96 - (void)showWindow:(id)sender
98 /* subscribe to LibVLCCore's messages */
99 vlc_LogSet(VLCIntf->p_libvlc, MsgCallback, (__bridge void*)self);
101 [super showWindow:sender];
104 - (IBAction)updateMessagesPanel:(id)sender
106 [self windowDidBecomeKey:nil];
109 - (void)windowDidBecomeKey:(NSNotification *)notification
111 [_msgs_table reloadData];
112 [_msgs_table scrollRowToVisible: [_msg_arr count] - 1];
115 - (void)windowWillClose:(NSNotification *)notification
117 /* unsubscribe from LibVLCCore's messages */
118 vlc_LogSet( VLCIntf->p_libvlc, NULL, NULL );
121 - (IBAction)saveDebugLog:(id)sender
123 NSSavePanel * saveFolderPanel = [[NSSavePanel alloc] init];
125 [saveFolderPanel setCanSelectHiddenExtension: NO];
126 [saveFolderPanel setCanCreateDirectories: YES];
127 [saveFolderPanel setAllowedFileTypes: [NSArray arrayWithObject:@"rtf"]];
128 [saveFolderPanel setNameFieldStringValue:[NSString stringWithFormat: _NS("VLC Debug Log (%s).rtf"), VERSION_MESSAGE]];
129 [saveFolderPanel beginSheetModalForWindow: self.window completionHandler:^(NSInteger returnCode) {
130 if (returnCode == NSOKButton) {
131 NSUInteger count = [_msg_arr count];
132 NSMutableAttributedString * string = [[NSMutableAttributedString alloc] init];
133 for (NSUInteger i = 0; i < count; i++)
134 [string appendAttributedString: [_msg_arr objectAtIndex:i]];
136 NSData *data = [string RTFFromRange:NSMakeRange(0, [string length])
137 documentAttributes:[NSDictionary dictionaryWithObject: NSRTFTextDocumentType forKey: NSDocumentTypeDocumentAttribute]];
139 if ([data writeToFile: [[saveFolderPanel URL] path] atomically: YES] == NO)
140 msg_Warn(VLCIntf, "Error while saving the debug log");
145 #pragma mark - data handling
147 - (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
149 if (aTableView == _msgs_table)
150 return [_msg_arr count];
154 - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
156 NSMutableAttributedString *result = NULL;
159 if (rowIndex < [_msg_arr count])
160 result = [_msg_arr objectAtIndex:rowIndex];
169 - (void)processReceivedlibvlcMessage:(const vlc_log_t *) item ofType: (int)i_type withStr: (char *)str
172 NSColor *_white = [NSColor whiteColor];
173 NSColor *_red = [NSColor redColor];
174 NSColor *_yellow = [NSColor yellowColor];
175 NSColor *_gray = [NSColor grayColor];
176 NSString * firstString, * secondString;
178 NSColor * pp_color[4] = { _white, _red, _yellow, _gray };
179 static const char * ppsz_type[4] = { ": ", " error: ", " warning: ", " debug: " };
182 NSMutableAttributedString *_msg_color;
186 if ([_msg_arr count] > 10000) {
187 [_msg_arr removeObjectAtIndex: 0];
188 [_msg_arr removeObjectAtIndex: 1];
190 if (!item->psz_module)
195 firstString = [NSString stringWithFormat:@"%s%s", item->psz_module, ppsz_type[i_type]];
196 secondString = [NSString stringWithFormat:@"%@%s\n", firstString, str];
198 _attr = [NSDictionary dictionaryWithObject: pp_color[i_type] forKey: NSForegroundColorAttributeName];
199 _msg_color = [[NSMutableAttributedString alloc] initWithString: secondString attributes: _attr];
200 _attr = [NSDictionary dictionaryWithObject: pp_color[3] forKey: NSForegroundColorAttributeName];
201 [_msg_color setAttributes: _attr range: NSMakeRange(0, [firstString length])];
202 [_msg_arr addObject:_msg_color];