macosx: Rename VLCDebugMessageWindowController to VLCLogWindowController
authorMarvin Scholz <epirat07@gmail.com>
Wed, 9 Aug 2017 12:23:43 +0000 (14:23 +0200)
committerMarvin Scholz <epirat07@gmail.com>
Wed, 9 Aug 2017 12:27:33 +0000 (14:27 +0200)
This name is much shorter and a lot easier to understand, as it is less
likely to be confused with the error messages window stuff.

extras/package/macosx/VLC.xcodeproj/project.pbxproj
modules/gui/macosx/Makefile.am
modules/gui/macosx/UI/LogMessageWindow.xib
modules/gui/macosx/VLCDebugMessageWindowController.h [deleted file]
modules/gui/macosx/VLCDebugMessageWindowController.m [deleted file]
modules/gui/macosx/VLCLogWindowController.h [new file with mode: 0644]
modules/gui/macosx/VLCLogWindowController.m [new file with mode: 0644]
modules/gui/macosx/VLCMain.h
modules/gui/macosx/VLCMain.m
modules/gui/macosx/VLCMainMenu.m

index bfea595..c7e4c23 100644 (file)
@@ -21,7 +21,7 @@
                1C3113A11E508C6900D4DD76 /* VLCConvertAndSaveWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0663351566C34C003A411C /* VLCConvertAndSaveWindowController.m */; };
                1C3113A31E508C6900D4DD76 /* VLCCoreDialogProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4A33210F8CB017000FC4A7 /* VLCCoreDialogProvider.m */; };
                1C3113A51E508C6900D4DD76 /* VLCCoreInteraction.m in Sources */ = {isa = PBXBuildFile; fileRef = CC448A6113B68A0B009F72E0 /* VLCCoreInteraction.m */; };
-               1C3113A71E508C6900D4DD76 /* VLCDebugMessageWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D8BB0B418302AC000FAE9B7 /* VLCDebugMessageWindowController.m */; };
+               1C3113A71E508C6900D4DD76 /* VLCLogWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D8BB0B418302AC000FAE9B7 /* VLCLogWindowController.m */; };
                1C3113A91E508C6900D4DD76 /* VLCDocumentController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1C39ABBD1DA9AB9B00FE052A /* VLCDocumentController.m */; };
                1C3113AB1E508C6900D4DD76 /* VLCExtensionsDialogProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 5CCED71114C0D4A90057F8D1 /* VLCExtensionsDialogProvider.m */; };
                1C3113AD1E508C6900D4DD76 /* VLCExtensionsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5CCED71314C0D4A90057F8D1 /* VLCExtensionsManager.m */; };
                7D871D371B5E6844000B56C0 /* VLCMain+OldPrefs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "VLCMain+OldPrefs.h"; sourceTree = "<group>"; };
                7D871D381B5E6844000B56C0 /* VLCMain+OldPrefs.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "VLCMain+OldPrefs.m"; sourceTree = "<group>"; };
                7D871D391B5E684D000B56C0 /* helpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = helpers.h; sourceTree = "<group>"; };
-               7D8BB0B318302AC000FAE9B7 /* VLCDebugMessageWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCDebugMessageWindowController.h; sourceTree = "<group>"; };
-               7D8BB0B418302AC000FAE9B7 /* VLCDebugMessageWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCDebugMessageWindowController.m; sourceTree = "<group>"; };
+               7D8BB0B318302AC000FAE9B7 /* VLCLogWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLogWindowController.h; sourceTree = "<group>"; };
+               7D8BB0B418302AC000FAE9B7 /* VLCLogWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLogWindowController.m; sourceTree = "<group>"; };
                7D9516B81C60B6AB00D14E1A /* VLCStatusBarIcon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCStatusBarIcon.h; sourceTree = "<group>"; };
                7D9516B91C60B6AB00D14E1A /* VLCStatusBarIcon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCStatusBarIcon.m; sourceTree = "<group>"; };
                7DA481221B5FC13700917FD7 /* VLCPlaylistView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCPlaylistView.h; sourceTree = "<group>"; };
                                CC4A33210F8CB017000FC4A7 /* VLCCoreDialogProvider.m */,
                                CC448A6013B68A0B009F72E0 /* VLCCoreInteraction.h */,
                                CC448A6113B68A0B009F72E0 /* VLCCoreInteraction.m */,
-                               7D8BB0B318302AC000FAE9B7 /* VLCDebugMessageWindowController.h */,
-                               7D8BB0B418302AC000FAE9B7 /* VLCDebugMessageWindowController.m */,
+                               7D8BB0B318302AC000FAE9B7 /* VLCLogWindowController.h */,
+                               7D8BB0B418302AC000FAE9B7 /* VLCLogWindowController.m */,
                                1C39ABBC1DA9AB9B00FE052A /* VLCDocumentController.h */,
                                1C39ABBD1DA9AB9B00FE052A /* VLCDocumentController.m */,
                                5CCED71014C0D4A90057F8D1 /* VLCExtensionsDialogProvider.h */,
                                1C3113A31E508C6900D4DD76 /* VLCCoreDialogProvider.m in Sources */,
                                6B2EFC631F281A0900F3C0EA /* VLCVolumeSliderCell.m in Sources */,
                                1C3113A51E508C6900D4DD76 /* VLCCoreInteraction.m in Sources */,
-                               1C3113A71E508C6900D4DD76 /* VLCDebugMessageWindowController.m in Sources */,
+                               1C3113A71E508C6900D4DD76 /* VLCLogWindowController.m in Sources */,
                                6BF5C5071EFE7E58008A9C12 /* VLCTintedImageButtonCell.m in Sources */,
                                1C3113A91E508C6900D4DD76 /* VLCDocumentController.m in Sources */,
                                1C3113AB1E508C6900D4DD76 /* VLCExtensionsDialogProvider.m in Sources */,
index e4be71e..c24c902 100644 (file)
@@ -71,7 +71,7 @@ libmacosx_plugin_la_SOURCES = \
        gui/macosx/VLCAudioEffectsWindowController.h gui/macosx/VLCAudioEffectsWindowController.m \
        gui/macosx/VLCBookmarksWindowController.h gui/macosx/VLCBookmarksWindowController.m \
        gui/macosx/VLCCoreDialogProvider.h gui/macosx/VLCCoreDialogProvider.m \
-       gui/macosx/VLCDebugMessageWindowController.h gui/macosx/VLCDebugMessageWindowController.m \
+       gui/macosx/VLCLogWindowController.h gui/macosx/VLCLogWindowController.m \
        gui/macosx/VLCHUDSliderCell.h gui/macosx/VLCHUDSliderCell.m \
        gui/macosx/VLCHUDButtonCell.h gui/macosx/VLCHUDButtonCell.m \
        gui/macosx/VLCHUDCheckboxCell.h gui/macosx/VLCHUDCheckboxCell.m \
index 73ee0c0..98c0758 100644 (file)
@@ -5,7 +5,7 @@
         <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="12120"/>
     </dependencies>
     <objects>
-        <customObject id="-2" userLabel="File's Owner" customClass="VLCDebugMessageWindowController">
+        <customObject id="-2" userLabel="File's Owner" customClass="VLCLogWindowController">
             <connections>
                 <outlet property="arrayController" destination="0Or-bh-QJU" id="Wo9-Rk-Jkb"/>
                 <outlet property="detailView" destination="ESj-Mw-X94" id="YDo-hQ-k1t"/>
diff --git a/modules/gui/macosx/VLCDebugMessageWindowController.h b/modules/gui/macosx/VLCDebugMessageWindowController.h
deleted file mode 100644 (file)
index 075e90d..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*****************************************************************************
- * VLCDebugMessageWindowController.m: Mac OS X interface crash reporter
- *****************************************************************************
- * Copyright (C) 2004-2013 VLC authors and VideoLAN
- * $Id$
- *
- * Authors: Felix Paul Kühne <fkuehne at videolan dot org>
- *          Pierre d'Herbemont <pdherbemont # videolan org>
- *          Derk-Jan Hartman <hartman at videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#import <Cocoa/Cocoa.h>
-
-@interface VLCDebugMessageWindowController : NSWindowController
-
-@property (assign) IBOutlet NSTableView *messageTable;
-@property (assign) IBOutlet NSButton *saveButton;
-@property (assign) IBOutlet NSButton *clearButton;
-@property (assign) IBOutlet NSButton *refreshButton;
-@property (assign) IBOutlet NSButton *toggleDetailsButton;
-@property (assign) IBOutlet NSSplitView *splitView;
-@property (assign) IBOutlet NSView *detailView;
-@property (assign) IBOutlet NSArrayController *arrayController;
-
-- (IBAction)saveDebugLog:(id)sender;
-- (IBAction)refreshLog:(id)sender;
-- (IBAction)clearLog:(id)sender;
-
-@end
diff --git a/modules/gui/macosx/VLCDebugMessageWindowController.m b/modules/gui/macosx/VLCDebugMessageWindowController.m
deleted file mode 100644 (file)
index 55752cc..0000000
+++ /dev/null
@@ -1,348 +0,0 @@
-/*****************************************************************************
- * VLCDebugMessageWindowController.m: Mac OS X interface crash reporter
- *****************************************************************************
- * Copyright (C) 2004-2013 VLC authors and VideoLAN
- * $Id$
- *
- * Authors: Felix Paul Kühne <fkuehne at videolan dot org>
- *          Pierre d'Herbemont <pdherbemont # videolan org>
- *          Derk-Jan Hartman <hartman at videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#import "VLCDebugMessageWindowController.h"
-#import "VLCMain.h"
-#import <vlc_common.h>
-
-@interface VLCDebugMessageWindowController () <NSWindowDelegate>
-
-/* This array stores messages that are managed by the arrayController */
-@property (retain) NSMutableArray *messagesArray;
-
-/* This array stores messages before they are added to the messagesArray on refresh */
-@property (retain) NSMutableArray *messageBuffer;
-
-/* We do not want to refresh the table for every message, as that would be very frequent when
- * there are a lot of messages, therefore we use a timer to refresh the table with new data
- * from the messageBuffer every now and then, which is much more efficient and still fast
- * enough for a good user experience
- */
-@property (retain) NSTimer        *refreshTimer;
-
-- (void)addMessage:(NSDictionary *)message;
-
-@end
-
-/*
- * MsgCallback: Callback triggered by the core once a new debug message is
- * ready to be displayed. We store everything in a NSArray in our Cocoa part
- * of this file.
- */
-static void MsgCallback(void *data, int type, const vlc_log_t *item, const char *format, va_list ap)
-{
-    @autoreleasepool {
-        int state;
-        char *msg;
-        VLCDebugMessageWindowController *controller = (__bridge VLCDebugMessageWindowController*)data;
-        static NSString *types[4] = { @"info", @"error", @"warning", @"debug" };
-
-        if (vasprintf(&msg, format, ap) == -1) {
-            return;
-        }
-
-        if (!item->psz_module || !msg) {
-            free(msg);
-            return;
-        }
-
-        NSString *position = [NSString stringWithFormat:@"%s:%i", item->file, item->line];
-
-        NSDictionary *messageDict = @{
-                                      @"type"       : types[type],
-                                      @"message"    : toNSStr(msg),
-                                      @"component"  : toNSStr(item->psz_module),
-                                      @"position"   : position,
-                                      @"func"       : toNSStr(item->func)
-                                      };
-        [controller addMessage:messageDict];
-        free(msg);
-    }
-}
-
-@implementation VLCDebugMessageWindowController
-
-- (id)init
-{
-    self = [super initWithWindowNibName:@"LogMessageWindow"];
-    if (self) {
-        _messagesArray = [[NSMutableArray alloc] initWithCapacity:500];
-        _messageBuffer = [[NSMutableArray alloc] initWithCapacity:100];
-    }
-    return self;
-}
-
-- (void)dealloc
-{
-    if (getIntf())
-        vlc_LogSet( getIntf()->obj.libvlc, NULL, NULL );
-}
-
-- (void)windowDidLoad
-{
-    [self.window setExcludedFromWindowsMenu:YES];
-    [self.window setDelegate:self];
-    [self.window setTitle:_NS("Messages")];
-    [self.window setLevel:NSModalPanelWindowLevel];
-
-#define setupButton(target, title, desc)                                              \
-    [target accessibilitySetOverrideValue:title                                       \
-                             forAttribute:NSAccessibilityTitleAttribute];             \
-    [target accessibilitySetOverrideValue:desc                                        \
-                             forAttribute:NSAccessibilityDescriptionAttribute];       \
-    [target setToolTip:desc];
-
-    setupButton(_saveButton,
-                _NS("Save log"),
-                _NS("Click to save the debug log to a file."));
-    setupButton(_refreshButton,
-                _NS("Refresh log"),
-                _NS("Click to frefresh the log output."));
-    setupButton(_clearButton,
-                _NS("Clear log"),
-                _NS("Click to clear the log output."));
-    setupButton(_toggleDetailsButton,
-                _NS("Toggle details"),
-                _NS("Click to show/hide details about a log message."));
-
-#undef setupButton
-}
-
-- (void)showWindow:(id)sender
-{
-    // Do nothing if window is already visible
-    if ([self.window isVisible]) {
-        return [super showWindow:sender];
-    }
-
-    // Subscribe to LibVLCCore's messages
-    vlc_LogSet(getIntf()->obj.libvlc, MsgCallback, (__bridge void*)self);
-    _refreshTimer = [NSTimer scheduledTimerWithTimeInterval:0.3
-                                                     target:self
-                                                   selector:@selector(appendMessageBuffer)
-                                                   userInfo:nil
-                                                    repeats:YES];
-    return [super showWindow:sender];
-}
-
-- (void)windowWillClose:(NSNotification *)notification
-{
-    // Unsubscribe from LibVLCCore's messages
-    vlc_LogSet( getIntf()->obj.libvlc, NULL, NULL );
-
-    // Remove all messages
-    [self clearMessageBuffer];
-    [self clearMessageTable];
-
-    // Invalidate timer
-    [_refreshTimer invalidate];
-    _refreshTimer = nil;
-}
-
-#pragma mark -
-#pragma mark Delegate methods
-
-/*
- * Called when a row is added to the table
- * We use this to set the correct background color for the row, depending on the
- * message type.
- */
-- (void)tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row
-{
-    // Initialize background colors
-    static NSDictionary *colors = nil;
-    static dispatch_once_t onceToken;
-    dispatch_once(&onceToken, ^{
-        colors = @{
-                   @"info"     : [NSColor colorWithCalibratedRed:0.65 green:0.91 blue:1.0 alpha:0.7],
-                   @"error"    : [NSColor colorWithCalibratedRed:1.0 green:0.49 blue:0.45 alpha:0.5],
-                   @"warning"  : [NSColor colorWithCalibratedRed:1.0 green:0.88 blue:0.45 alpha:0.7],
-                   @"debug"    : [NSColor colorWithCalibratedRed:0.96 green:0.96 blue:0.96 alpha:0.5]
-                   };
-    });
-
-    // Lookup color for message type
-    NSDictionary *message = [[_arrayController arrangedObjects] objectAtIndex:row];
-    rowView.backgroundColor = [colors objectForKey:[message objectForKey:@"type"]];
-}
-
-- (void)splitViewDidResizeSubviews:(NSNotification *)notification
-{
-    if ([_splitView isSubviewCollapsed:_detailView]) {
-        [_toggleDetailsButton setState:NSOffState];
-    } else {
-        [_toggleDetailsButton setState:NSOnState];
-    }
-}
-
-#pragma mark -
-#pragma mark UI actions
-
-/* Save debug log to file action
- */
-- (IBAction)saveDebugLog:(id)sender
-{
-    NSSavePanel * saveFolderPanel = [[NSSavePanel alloc] init];
-
-    [saveFolderPanel setCanSelectHiddenExtension: NO];
-    [saveFolderPanel setCanCreateDirectories: YES];
-    [saveFolderPanel setAllowedFileTypes: [NSArray arrayWithObject:@"txt"]];
-    [saveFolderPanel setNameFieldStringValue:[NSString stringWithFormat: _NS("VLC Debug Log (%s).txt"), VERSION_MESSAGE]];
-    [saveFolderPanel beginSheetModalForWindow: self.window completionHandler:^(NSInteger returnCode) {
-        if (returnCode != NSOKButton) {
-            return;
-        }
-        NSMutableString *string = [[NSMutableString alloc] init];
-
-        for (NSDictionary *line in _messagesArray) {
-            NSString *message = [NSString stringWithFormat:@"%@ %@ %@\n",
-                                 [line objectForKey:@"component"],
-                                 [line objectForKey:@"type"],
-                                 [line objectForKey:@"message"]];
-            [string appendString:message];
-        }
-        NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
-        if ([data writeToFile: [[saveFolderPanel URL] path] atomically: YES] == NO)
-            msg_Warn(getIntf(), "Error while saving the debug log");
-    }];
-}
-
-/* Clear log action
- */
-- (IBAction)clearLog:(id)sender
-{
-    // Unregister handler
-    vlc_LogSet(getIntf()->obj.libvlc, NULL, NULL);
-
-    // Remove all messages
-    [self clearMessageBuffer];
-    [self clearMessageTable];
-
-    // Reregister handler, to write new header to log
-    vlc_LogSet(getIntf()->obj.libvlc, MsgCallback, (__bridge void*)self);
-}
-
-/* Refresh log action
- */
-- (IBAction)refreshLog:(id)sender
-{
-    [self appendMessageBuffer];
-    [_messageTable scrollToEndOfDocument:self];
-}
-
-/* Show/Hide details action
- */
-- (IBAction)toggleDetails:(id)sender
-{
-    if ([_splitView isSubviewCollapsed:_detailView]) {
-        [_detailView setHidden:NO];
-    } else {
-        [_detailView setHidden:YES];
-    }
-}
-
-/* Called when the user hits CMD + C or copy is clicked in the edit menu
- */
-- (void) copy:(id)sender {
-    NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
-    [pasteBoard clearContents];
-    for (NSDictionary *line in [_arrayController selectedObjects]) {
-        NSString *message = [NSString stringWithFormat:@"%@ %@ %@",
-                             [line objectForKey:@"component"],
-                             [line objectForKey:@"type"],
-                             [line objectForKey:@"message"]];
-        [pasteBoard writeObjects:@[message]];
-    }
-}
-
-#pragma mark -
-#pragma mark UI validation
-
-/* Validate the copy menu item
- */
-- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem
-{
-    SEL theAction = [anItem action];
-
-    if (theAction == @selector(copy:)) {
-        if ([[_arrayController selectedObjects] count] > 0) {
-            return YES;
-        }
-        return NO;
-    }
-    /* Indicate that we handle the validation method,
-     * even if we don’t implement the action
-     */
-    return YES;
-}
-
-#pragma mark -
-#pragma mark Data handling
-
-/** 
- Adds a message to the messageBuffer, it does not has to be called from the main thread, as
- items are only added to the messageArray on refresh.
- */
-- (void)addMessage:(NSDictionary *)messageDict
-{
-    @synchronized (_messageBuffer) {
-        [_messageBuffer addObject:messageDict];
-    }
-}
-
-/**
- Clears the message buffer
- */
-- (void)clearMessageBuffer
-{
-    @synchronized (_messageBuffer) {
-        [_messageBuffer removeAllObjects];
-    }
-}
-
-/**
- Clears all messages in the message table by removing all items from the arrayController
- */
-- (void)clearMessageTable
-{
-    NSRange range = NSMakeRange(0, [[_arrayController arrangedObjects] count]);
-    [_arrayController removeObjectsAtArrangedObjectIndexes:[NSIndexSet indexSetWithIndexesInRange:range]];
-}
-
-/**
- Appends all messages from the buffer to the arrayController and clears the buffer
- */
-- (void)appendMessageBuffer
-{
-    if ([_messagesArray count] > 1000000) {
-        [_messagesArray removeObjectsInRange:NSMakeRange(0, 2)];
-    }
-    @synchronized (_messageBuffer) {
-        [_arrayController addObjects:_messageBuffer];
-        [_messageBuffer removeAllObjects];
-    }
-}
-
-@end
diff --git a/modules/gui/macosx/VLCLogWindowController.h b/modules/gui/macosx/VLCLogWindowController.h
new file mode 100644 (file)
index 0000000..6ed196c
--- /dev/null
@@ -0,0 +1,43 @@
+/*****************************************************************************
+ * VLCLogWindowController.h: Mac OS X interface crash reporter
+ *****************************************************************************
+ * Copyright (C) 2004-2013 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Felix Paul Kühne <fkuehne at videolan dot org>
+ *          Pierre d'Herbemont <pdherbemont # videolan org>
+ *          Derk-Jan Hartman <hartman at videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import <Cocoa/Cocoa.h>
+
+@interface VLCLogWindowController : NSWindowController
+
+@property (assign) IBOutlet NSTableView *messageTable;
+@property (assign) IBOutlet NSButton *saveButton;
+@property (assign) IBOutlet NSButton *clearButton;
+@property (assign) IBOutlet NSButton *refreshButton;
+@property (assign) IBOutlet NSButton *toggleDetailsButton;
+@property (assign) IBOutlet NSSplitView *splitView;
+@property (assign) IBOutlet NSView *detailView;
+@property (assign) IBOutlet NSArrayController *arrayController;
+
+- (IBAction)saveDebugLog:(id)sender;
+- (IBAction)refreshLog:(id)sender;
+- (IBAction)clearLog:(id)sender;
+
+@end
diff --git a/modules/gui/macosx/VLCLogWindowController.m b/modules/gui/macosx/VLCLogWindowController.m
new file mode 100644 (file)
index 0000000..607d88e
--- /dev/null
@@ -0,0 +1,348 @@
+/*****************************************************************************
+ * VLCLogWindowController.m: Mac OS X interface crash reporter
+ *****************************************************************************
+ * Copyright (C) 2004-2013 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Felix Paul Kühne <fkuehne at videolan dot org>
+ *          Pierre d'Herbemont <pdherbemont # videolan org>
+ *          Derk-Jan Hartman <hartman at videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import "VLCLogWindowController.h"
+#import "VLCMain.h"
+#import <vlc_common.h>
+
+@interface VLCLogWindowController () <NSWindowDelegate>
+
+/* This array stores messages that are managed by the arrayController */
+@property (retain) NSMutableArray *messagesArray;
+
+/* This array stores messages before they are added to the messagesArray on refresh */
+@property (retain) NSMutableArray *messageBuffer;
+
+/* We do not want to refresh the table for every message, as that would be very frequent when
+ * there are a lot of messages, therefore we use a timer to refresh the table with new data
+ * from the messageBuffer every now and then, which is much more efficient and still fast
+ * enough for a good user experience
+ */
+@property (retain) NSTimer        *refreshTimer;
+
+- (void)addMessage:(NSDictionary *)message;
+
+@end
+
+/*
+ * MsgCallback: Callback triggered by the core once a new debug message is
+ * ready to be displayed. We store everything in a NSArray in our Cocoa part
+ * of this file.
+ */
+static void MsgCallback(void *data, int type, const vlc_log_t *item, const char *format, va_list ap)
+{
+    @autoreleasepool {
+        int state;
+        char *msg;
+        VLCLogWindowController *controller = (__bridge VLCLogWindowController*)data;
+        static NSString *types[4] = { @"info", @"error", @"warning", @"debug" };
+
+        if (vasprintf(&msg, format, ap) == -1) {
+            return;
+        }
+
+        if (!item->psz_module || !msg) {
+            free(msg);
+            return;
+        }
+
+        NSString *position = [NSString stringWithFormat:@"%s:%i", item->file, item->line];
+
+        NSDictionary *messageDict = @{
+                                      @"type"       : types[type],
+                                      @"message"    : toNSStr(msg),
+                                      @"component"  : toNSStr(item->psz_module),
+                                      @"position"   : position,
+                                      @"func"       : toNSStr(item->func)
+                                      };
+        [controller addMessage:messageDict];
+        free(msg);
+    }
+}
+
+@implementation VLCLogWindowController
+
+- (id)init
+{
+    self = [super initWithWindowNibName:@"LogMessageWindow"];
+    if (self) {
+        _messagesArray = [[NSMutableArray alloc] initWithCapacity:500];
+        _messageBuffer = [[NSMutableArray alloc] initWithCapacity:100];
+    }
+    return self;
+}
+
+- (void)dealloc
+{
+    if (getIntf())
+        vlc_LogSet( getIntf()->obj.libvlc, NULL, NULL );
+}
+
+- (void)windowDidLoad
+{
+    [self.window setExcludedFromWindowsMenu:YES];
+    [self.window setDelegate:self];
+    [self.window setTitle:_NS("Messages")];
+    [self.window setLevel:NSModalPanelWindowLevel];
+
+#define setupButton(target, title, desc)                                              \
+    [target accessibilitySetOverrideValue:title                                       \
+                             forAttribute:NSAccessibilityTitleAttribute];             \
+    [target accessibilitySetOverrideValue:desc                                        \
+                             forAttribute:NSAccessibilityDescriptionAttribute];       \
+    [target setToolTip:desc];
+
+    setupButton(_saveButton,
+                _NS("Save log"),
+                _NS("Click to save the debug log to a file."));
+    setupButton(_refreshButton,
+                _NS("Refresh log"),
+                _NS("Click to frefresh the log output."));
+    setupButton(_clearButton,
+                _NS("Clear log"),
+                _NS("Click to clear the log output."));
+    setupButton(_toggleDetailsButton,
+                _NS("Toggle details"),
+                _NS("Click to show/hide details about a log message."));
+
+#undef setupButton
+}
+
+- (void)showWindow:(id)sender
+{
+    // Do nothing if window is already visible
+    if ([self.window isVisible]) {
+        return [super showWindow:sender];
+    }
+
+    // Subscribe to LibVLCCore's messages
+    vlc_LogSet(getIntf()->obj.libvlc, MsgCallback, (__bridge void*)self);
+    _refreshTimer = [NSTimer scheduledTimerWithTimeInterval:0.3
+                                                     target:self
+                                                   selector:@selector(appendMessageBuffer)
+                                                   userInfo:nil
+                                                    repeats:YES];
+    return [super showWindow:sender];
+}
+
+- (void)windowWillClose:(NSNotification *)notification
+{
+    // Unsubscribe from LibVLCCore's messages
+    vlc_LogSet( getIntf()->obj.libvlc, NULL, NULL );
+
+    // Remove all messages
+    [self clearMessageBuffer];
+    [self clearMessageTable];
+
+    // Invalidate timer
+    [_refreshTimer invalidate];
+    _refreshTimer = nil;
+}
+
+#pragma mark -
+#pragma mark Delegate methods
+
+/*
+ * Called when a row is added to the table
+ * We use this to set the correct background color for the row, depending on the
+ * message type.
+ */
+- (void)tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row
+{
+    // Initialize background colors
+    static NSDictionary *colors = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        colors = @{
+                   @"info"     : [NSColor colorWithCalibratedRed:0.65 green:0.91 blue:1.0 alpha:0.7],
+                   @"error"    : [NSColor colorWithCalibratedRed:1.0 green:0.49 blue:0.45 alpha:0.5],
+                   @"warning"  : [NSColor colorWithCalibratedRed:1.0 green:0.88 blue:0.45 alpha:0.7],
+                   @"debug"    : [NSColor colorWithCalibratedRed:0.96 green:0.96 blue:0.96 alpha:0.5]
+                   };
+    });
+
+    // Lookup color for message type
+    NSDictionary *message = [[_arrayController arrangedObjects] objectAtIndex:row];
+    rowView.backgroundColor = [colors objectForKey:[message objectForKey:@"type"]];
+}
+
+- (void)splitViewDidResizeSubviews:(NSNotification *)notification
+{
+    if ([_splitView isSubviewCollapsed:_detailView]) {
+        [_toggleDetailsButton setState:NSOffState];
+    } else {
+        [_toggleDetailsButton setState:NSOnState];
+    }
+}
+
+#pragma mark -
+#pragma mark UI actions
+
+/* Save debug log to file action
+ */
+- (IBAction)saveDebugLog:(id)sender
+{
+    NSSavePanel * saveFolderPanel = [[NSSavePanel alloc] init];
+
+    [saveFolderPanel setCanSelectHiddenExtension: NO];
+    [saveFolderPanel setCanCreateDirectories: YES];
+    [saveFolderPanel setAllowedFileTypes: [NSArray arrayWithObject:@"txt"]];
+    [saveFolderPanel setNameFieldStringValue:[NSString stringWithFormat: _NS("VLC Debug Log (%s).txt"), VERSION_MESSAGE]];
+    [saveFolderPanel beginSheetModalForWindow: self.window completionHandler:^(NSInteger returnCode) {
+        if (returnCode != NSOKButton) {
+            return;
+        }
+        NSMutableString *string = [[NSMutableString alloc] init];
+
+        for (NSDictionary *line in _messagesArray) {
+            NSString *message = [NSString stringWithFormat:@"%@ %@ %@\n",
+                                 [line objectForKey:@"component"],
+                                 [line objectForKey:@"type"],
+                                 [line objectForKey:@"message"]];
+            [string appendString:message];
+        }
+        NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
+        if ([data writeToFile: [[saveFolderPanel URL] path] atomically: YES] == NO)
+            msg_Warn(getIntf(), "Error while saving the debug log");
+    }];
+}
+
+/* Clear log action
+ */
+- (IBAction)clearLog:(id)sender
+{
+    // Unregister handler
+    vlc_LogSet(getIntf()->obj.libvlc, NULL, NULL);
+
+    // Remove all messages
+    [self clearMessageBuffer];
+    [self clearMessageTable];
+
+    // Reregister handler, to write new header to log
+    vlc_LogSet(getIntf()->obj.libvlc, MsgCallback, (__bridge void*)self);
+}
+
+/* Refresh log action
+ */
+- (IBAction)refreshLog:(id)sender
+{
+    [self appendMessageBuffer];
+    [_messageTable scrollToEndOfDocument:self];
+}
+
+/* Show/Hide details action
+ */
+- (IBAction)toggleDetails:(id)sender
+{
+    if ([_splitView isSubviewCollapsed:_detailView]) {
+        [_detailView setHidden:NO];
+    } else {
+        [_detailView setHidden:YES];
+    }
+}
+
+/* Called when the user hits CMD + C or copy is clicked in the edit menu
+ */
+- (void) copy:(id)sender {
+    NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
+    [pasteBoard clearContents];
+    for (NSDictionary *line in [_arrayController selectedObjects]) {
+        NSString *message = [NSString stringWithFormat:@"%@ %@ %@",
+                             [line objectForKey:@"component"],
+                             [line objectForKey:@"type"],
+                             [line objectForKey:@"message"]];
+        [pasteBoard writeObjects:@[message]];
+    }
+}
+
+#pragma mark -
+#pragma mark UI validation
+
+/* Validate the copy menu item
+ */
+- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem
+{
+    SEL theAction = [anItem action];
+
+    if (theAction == @selector(copy:)) {
+        if ([[_arrayController selectedObjects] count] > 0) {
+            return YES;
+        }
+        return NO;
+    }
+    /* Indicate that we handle the validation method,
+     * even if we don’t implement the action
+     */
+    return YES;
+}
+
+#pragma mark -
+#pragma mark Data handling
+
+/** 
+ Adds a message to the messageBuffer, it does not has to be called from the main thread, as
+ items are only added to the messageArray on refresh.
+ */
+- (void)addMessage:(NSDictionary *)messageDict
+{
+    @synchronized (_messageBuffer) {
+        [_messageBuffer addObject:messageDict];
+    }
+}
+
+/**
+ Clears the message buffer
+ */
+- (void)clearMessageBuffer
+{
+    @synchronized (_messageBuffer) {
+        [_messageBuffer removeAllObjects];
+    }
+}
+
+/**
+ Clears all messages in the message table by removing all items from the arrayController
+ */
+- (void)clearMessageTable
+{
+    NSRange range = NSMakeRange(0, [[_arrayController arrangedObjects] count]);
+    [_arrayController removeObjectsAtArrangedObjectIndexes:[NSIndexSet indexSetWithIndexesInRange:range]];
+}
+
+/**
+ Appends all messages from the buffer to the arrayController and clears the buffer
+ */
+- (void)appendMessageBuffer
+{
+    if ([_messagesArray count] > 1000000) {
+        [_messagesArray removeObjectsInRange:NSMakeRange(0, 2)];
+    }
+    @synchronized (_messageBuffer) {
+        [_arrayController addObjects:_messageBuffer];
+        [_messageBuffer removeAllObjects];
+    }
+}
+
+@end
index 4db72bd..5ffd2a5 100644 (file)
@@ -68,7 +68,7 @@ static NSString * VLCMediaKeySupportSettingChangedNotification = @"VLCMediaKeySu
 @class VLCCoreDialogProvider;
 @class VLCBookmarksWindowController;
 @class VLCOpenWindowController;
-@class VLCDebugMessageWindowController;
+@class VLCLogWindowController;
 @class VLCTrackSynchronizationWindowController;
 @class VLCAudioEffectsWindowController;
 @class VLCVideoEffectsWindowController;
@@ -99,7 +99,7 @@ static NSString * VLCMediaKeySupportSettingChangedNotification = @"VLCMediaKeySu
 - (VLCExtensionsManager *)extensionsManager;
 - (VLCStatusBarIcon *)statusBarIcon;
 
-- (VLCDebugMessageWindowController *)debugMsgPanel;
+- (VLCLogWindowController *)debugMsgPanel;
 
 - (VLCTrackSynchronizationWindowController *)trackSyncPanel;
 - (VLCAudioEffectsWindowController *)audioEffectsPanel;
index 43c8849..965cb02 100644 (file)
@@ -58,7 +58,7 @@
 #import "VLCTrackSynchronizationWindowController.h"
 #import "VLCExtensionsManager.h"
 #import "VLCResumeDialogController.h"
-#import "VLCDebugMessageWindowController.h"
+#import "VLCLogWindowController.h"
 #import "VLCConvertAndSaveWindowController.h"
 
 #import "VLCVideoEffectsWindowController.h"
@@ -174,7 +174,7 @@ static int ShowController(vlc_object_t *p_this, const char *psz_variable,
     VLCResumeDialogController *_resume_dialog;
     VLCInputManager *_input_manager;
     VLCPlaylist *_playlist;
-    VLCDebugMessageWindowController *_messagePanelController;
+    VLCLogWindowController *_messagePanelController;
     VLCStatusBarIcon *_statusBarIcon;
     VLCTrackSynchronizationWindowController *_trackSyncPanel;
     VLCAudioEffectsWindowController *_audioEffectsPanel;
@@ -498,10 +498,10 @@ static VLCMain *sharedInstance = nil;
     return _extensionsManager;
 }
 
-- (VLCDebugMessageWindowController *)debugMsgPanel
+- (VLCLogWindowController *)debugMsgPanel
 {
     if (!_messagePanelController)
-        _messagePanelController = [[VLCDebugMessageWindowController alloc] init];
+        _messagePanelController = [[VLCLogWindowController alloc] init];
 
     return _messagePanelController;
 }
index 67b6cb0..38b3291 100644 (file)
@@ -46,7 +46,7 @@
 #import "VLCMainWindowControlsBar.h"
 #import "VLCExtensionsManager.h"
 #import "VLCConvertAndSaveWindowController.h"
-#import "VLCDebugMessageWindowController.h"
+#import "VLCLogWindowController.h"
 #import "VLCAddonsWindowController.h"
 #import "VLCTimeSelectionPanelController.h"
 #import "NSScreen+VLCAdditions.h"