From 15452c9707e9e45a459988abd1db6403eea70610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Paul=20K=C3=BChne?= <felix@feepk.net> Date: Sat, 25 Jan 2020 13:41:51 +0100 Subject: [PATCH] macosx/library: add basic information panel This way, you can reveal the data about an individual item stored in the data base. The representation will be moved to a different place, so this is notably for debug purposes for now. --- .../macosx/VLC.xcodeproj/project.pbxproj | 8 ++ modules/gui/macosx/Makefile.am | 3 + .../macosx/UI/VLCLibraryInformationPanel.xib | 56 +++++++++ .../library/VLCLibraryInformationPanel.h | 38 +++++++ .../library/VLCLibraryInformationPanel.m | 107 ++++++++++++++++++ .../macosx/library/VLCLibraryMenuController.m | 16 ++- po/POTFILES.in | 2 + 7 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 modules/gui/macosx/UI/VLCLibraryInformationPanel.xib create mode 100644 modules/gui/macosx/library/VLCLibraryInformationPanel.h create mode 100644 modules/gui/macosx/library/VLCLibraryInformationPanel.m diff --git a/extras/package/macosx/VLC.xcodeproj/project.pbxproj b/extras/package/macosx/VLC.xcodeproj/project.pbxproj index 8f8702e14518..4534baf5cc25 100644 --- a/extras/package/macosx/VLC.xcodeproj/project.pbxproj +++ b/extras/package/macosx/VLC.xcodeproj/project.pbxproj @@ -98,6 +98,7 @@ 6BBBF9851F7B257100B404CD /* VLCLogMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BBBF9841F7B257100B404CD /* VLCLogMessage.m */; }; 6BF093F91EE0182B0049D8B0 /* VLCTimeField.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BF093F81EE0182B0049D8B0 /* VLCTimeField.m */; }; 6BF5C5041EFE66EF008A9C12 /* VLCHUDTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BF5C5031EFE66EF008A9C12 /* VLCHUDTableView.m */; }; + 7D03F97423DC5BBC0027A875 /* VLCLibraryInformationPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D03F97223DC5BBC0027A875 /* VLCLibraryInformationPanel.m */; }; 7D0F5A9B2264EB410009C48A /* VLCHotkeysController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D0F5A9A2264EB410009C48A /* VLCHotkeysController.m */; }; 7D0F63FF2201F63400FDB91F /* VLCPlaylistTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D0F63FE2201F63400FDB91F /* VLCPlaylistTableCellView.m */; }; 7D0F64062202047900FDB91F /* VLCLibraryCollectionViewItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D0F64042202047900FDB91F /* VLCLibraryCollectionViewItem.m */; }; @@ -437,6 +438,9 @@ 6BF56C3D1FCF00AF004A411A /* audiotoolbox_midi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = audiotoolbox_midi.c; path = ../../../modules/codec/audiotoolbox_midi.c; sourceTree = "<group>"; }; 6BF5C5021EFE66EF008A9C12 /* VLCHUDTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCHUDTableView.h; sourceTree = "<group>"; }; 6BF5C5031EFE66EF008A9C12 /* VLCHUDTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCHUDTableView.m; sourceTree = "<group>"; }; + 7D03F97123DC5BBC0027A875 /* VLCLibraryInformationPanel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryInformationPanel.h; sourceTree = "<group>"; }; + 7D03F97223DC5BBC0027A875 /* VLCLibraryInformationPanel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryInformationPanel.m; sourceTree = "<group>"; }; + 7D03F97323DC5BBC0027A875 /* VLCLibraryInformationPanel.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = VLCLibraryInformationPanel.xib; sourceTree = "<group>"; }; 7D0A387820CBCC4D00D4BF3B /* videotoolbox.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = videotoolbox.c; path = ../../../modules/codec/videotoolbox.c; sourceTree = "<group>"; }; 7D0F5A992264EB410009C48A /* VLCHotkeysController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCHotkeysController.h; sourceTree = "<group>"; }; 7D0F5A9A2264EB410009C48A /* VLCHotkeysController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCHotkeysController.m; sourceTree = "<group>"; }; @@ -1056,6 +1060,8 @@ 7DFBDCB0226A518400B700A5 /* VLCLibraryMenuController.m */, 7D22A8F222BC14F80063ECD2 /* VLCLibrarySortingMenuController.h */, 7D22A8F322BC14F80063ECD2 /* VLCLibrarySortingMenuController.m */, + 7D03F97123DC5BBC0027A875 /* VLCLibraryInformationPanel.h */, + 7D03F97223DC5BBC0027A875 /* VLCLibraryInformationPanel.m */, 7DFBDCBF226DC16200B700A5 /* VLCInputItem.h */, 7DFBDCC0226DC16200B700A5 /* VLCInputItem.m */, ); @@ -1569,6 +1575,7 @@ 7D0F64052202047900FDB91F /* VLCLibraryCollectionViewItem.xib */, 7DE2F0482282D7980040DD0A /* VLCLibraryTableCellView.xib */, 7DE82E7A228437AA002D341A /* VLCLibraryAlbumTableCellView.xib */, + 7D03F97323DC5BBC0027A875 /* VLCLibraryInformationPanel.xib */, 7D67318322C8F3F60000AD40 /* VLCMediaSourceCollectionViewItem.xib */, 7DF14FBC2270CB1C0008ABE4 /* VLCMediaSourceDeviceCollectionViewItem.xib */, 6B82241A1E4D2A9000833BE1 /* VLCStatusBarIconMainMenu.xib */, @@ -1740,6 +1747,7 @@ 1C31138E1E508C6900D4DD76 /* VLCAboutWindowController.m in Sources */, 1C3113901E508C6900D4DD76 /* VLCHelpWindowController.m in Sources */, 7D1BF28D22A192000027C50F /* VLCPlaylistSortingMenuController.m in Sources */, + 7D03F97423DC5BBC0027A875 /* VLCLibraryInformationPanel.m in Sources */, 1C3113921E508C6900D4DD76 /* VLCAddonListItem.m in Sources */, 7DFBDCB7226CDFD600B700A5 /* VLCImageView.m in Sources */, 7D404ABF2281892C00B28EF4 /* NSView+VLCAdditions.m in Sources */, diff --git a/modules/gui/macosx/Makefile.am b/modules/gui/macosx/Makefile.am index ba42cc88006b..53d36083f923 100644 --- a/modules/gui/macosx/Makefile.am +++ b/modules/gui/macosx/Makefile.am @@ -64,6 +64,8 @@ libmacosx_plugin_la_SOURCES = \ gui/macosx/library/VLCLibraryController.m \ gui/macosx/library/VLCLibraryDataTypes.h \ gui/macosx/library/VLCLibraryDataTypes.m \ + gui/macosx/library/VLCLibraryInformationPanel.h \ + gui/macosx/library/VLCLibraryInformationPanel.m \ gui/macosx/library/VLCLibraryMenuController.h \ gui/macosx/library/VLCLibraryMenuController.m \ gui/macosx/library/VLCLibraryModel.h \ @@ -278,6 +280,7 @@ libmacosx_plugin_la_XIB_SOURCES = \ gui/macosx/UI/VLCCustomCropARPanel.xib \ gui/macosx/UI/VLCDetachedAudioWindow.xib \ gui/macosx/UI/VLCLibraryAlbumTableCellView.xib \ + gui/macosx/UI/VLCLibraryInformationPanel.xib \ gui/macosx/UI/VLCLibraryWindow.xib \ gui/macosx/UI/VLCLibraryTableCellView.xib \ gui/macosx/UI/VLCPlaylistTableCellView.xib \ diff --git a/modules/gui/macosx/UI/VLCLibraryInformationPanel.xib b/modules/gui/macosx/UI/VLCLibraryInformationPanel.xib new file mode 100644 index 000000000000..230c6f0407ca --- /dev/null +++ b/modules/gui/macosx/UI/VLCLibraryInformationPanel.xib @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> + <dependencies> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <objects> + <customObject id="-2" userLabel="File's Owner" customClass="VLCLibraryInformationPanel"> + <connections> + <outlet property="imageView" destination="N4h-LP-IRY" id="Ned-Ju-hyu"/> + <outlet property="multiLineTextLabel" destination="OhC-hA-R2H" id="Q6T-Ol-Gdc"/> + <outlet property="window" destination="oPi-wT-0nK" id="ODs-Hv-85I"/> + </connections> + </customObject> + <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> + <customObject id="-3" userLabel="Application" customClass="NSObject"/> + <window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" frameAutosaveName="" animationBehavior="default" id="oPi-wT-0nK" customClass="NSPanel"> + <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" utility="YES" HUD="YES"/> + <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> + <rect key="contentRect" x="136" y="189" width="595" height="512"/> + <rect key="screenRect" x="0.0" y="0.0" width="1920" height="1177"/> + <value key="minSize" type="size" width="386" height="227"/> + <view key="contentView" misplaced="YES" id="Nfs-rF-cUN"> + <rect key="frame" x="0.0" y="0.0" width="595" height="403"/> + <autoresizingMask key="autoresizingMask"/> + <subviews> + <imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="N4h-LP-IRY"> + <rect key="frame" x="20" y="20" width="555" height="347"/> + <constraints> + <constraint firstAttribute="width" secondItem="N4h-LP-IRY" secondAttribute="height" multiplier="16:10" id="bqe-XE-yWC"/> + </constraints> + <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" id="8o3-U6-XgQ"/> + </imageView> + <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="OhC-hA-R2H"> + <rect key="frame" x="18" y="367" width="559" height="16"/> + <textFieldCell key="cell" selectable="YES" title="Multiline Label" id="caT-3r-bkd"> + <font key="font" metaFont="system"/> + <color key="textColor" name="selectedMenuItemTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + </subviews> + <constraints> + <constraint firstItem="OhC-hA-R2H" firstAttribute="leading" secondItem="Nfs-rF-cUN" secondAttribute="leading" constant="20" id="BVL-Xu-cDU"/> + <constraint firstAttribute="trailing" secondItem="N4h-LP-IRY" secondAttribute="trailing" constant="20" id="cEY-J9-usm"/> + <constraint firstItem="N4h-LP-IRY" firstAttribute="leading" secondItem="Nfs-rF-cUN" secondAttribute="leading" constant="20" id="kKf-aB-0vG"/> + <constraint firstItem="N4h-LP-IRY" firstAttribute="top" secondItem="OhC-hA-R2H" secondAttribute="bottom" id="mhR-pO-oDr"/> + <constraint firstItem="OhC-hA-R2H" firstAttribute="top" secondItem="Nfs-rF-cUN" secondAttribute="top" constant="20" id="ugM-Yv-u0C"/> + <constraint firstAttribute="trailing" secondItem="OhC-hA-R2H" secondAttribute="trailing" constant="20" id="yEE-lN-RaR"/> + <constraint firstAttribute="bottom" secondItem="N4h-LP-IRY" secondAttribute="bottom" constant="20" id="zc5-8x-CjC"/> + </constraints> + </view> + <point key="canvasLocation" x="209.5" y="121"/> + </window> + </objects> +</document> diff --git a/modules/gui/macosx/library/VLCLibraryInformationPanel.h b/modules/gui/macosx/library/VLCLibraryInformationPanel.h new file mode 100644 index 000000000000..0ae24efed75e --- /dev/null +++ b/modules/gui/macosx/library/VLCLibraryInformationPanel.h @@ -0,0 +1,38 @@ +/***************************************************************************** +* VLCLibraryInformationPanel.h: MacOS X interface module +***************************************************************************** +* Copyright (C) 2020 VLC authors and VideoLAN +* +* Authors: Felix Paul Kühne <fkuehne # videolan -dot- 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> + +NS_ASSUME_NONNULL_BEGIN + +@class VLCMediaLibraryMediaItem; + +@interface VLCLibraryInformationPanel : NSWindowController + +@property (readwrite, weak) IBOutlet NSTextField *multiLineTextLabel; +@property (readwrite, weak) IBOutlet NSImageView *imageView; + +- (void)setRepresentedMediaItem:(VLCMediaLibraryMediaItem *)representedMediaItem; + +@end + +NS_ASSUME_NONNULL_END diff --git a/modules/gui/macosx/library/VLCLibraryInformationPanel.m b/modules/gui/macosx/library/VLCLibraryInformationPanel.m new file mode 100644 index 000000000000..bed9cb05af09 --- /dev/null +++ b/modules/gui/macosx/library/VLCLibraryInformationPanel.m @@ -0,0 +1,107 @@ +/***************************************************************************** +* VLCLibraryInformationPanel.m: MacOS X interface module +***************************************************************************** +* Copyright (C) 2020 VLC authors and VideoLAN +* +* Authors: Felix Paul Kühne <fkuehne # videolan -dot- 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 "VLCLibraryInformationPanel.h" +#import "library/VLCLibraryDataTypes.h" +#import "library/VLCInputItem.h" +#import "extensions/NSString+Helpers.h" + +@interface VLCLibraryInformationPanel () +{ + VLCMediaLibraryMediaItem *_representedMediaItem; +} + +@end + +@implementation VLCLibraryInformationPanel + +- (void)windowDidLoad { + [super windowDidLoad]; + [self updateRepresentation]; +} + +- (void)setRepresentedMediaItem:(VLCMediaLibraryMediaItem *)representedMediaItem +{ + _representedMediaItem = representedMediaItem; + [self updateRepresentation]; +} + +- (void)updateRepresentation +{ + NSMutableString *textContent = [[NSMutableString alloc] initWithFormat:@"ID: %lli\n", _representedMediaItem.libraryID]; + [textContent appendFormat:@"Title: %@\n", _representedMediaItem.title]; + if (_representedMediaItem.mediaSubType != VLC_ML_MEDIA_SUBTYPE_UNKNOWN) { + [textContent appendFormat:@"Type: %@ — %@\n", _representedMediaItem.readableMediaType, _representedMediaItem.readableMediaSubType]; + } else { + [textContent appendFormat:@"Type: %@\n", _representedMediaItem.readableMediaType]; + } + [textContent appendFormat:@"Duration: %@\n", [NSString stringWithTime:_representedMediaItem.duration / VLCMediaLibraryMediaItemDurationDenominator]]; + [textContent appendFormat:@"Play count: %u\n", _representedMediaItem.playCount]; + [textContent appendFormat:@"Last played: %@\n", [NSDateFormatter localizedStringFromDate:[NSDate dateWithTimeIntervalSince1970:_representedMediaItem.lastPlayedDate] + dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterShortStyle]]; + [textContent appendFormat:@"Small artwork generated? %@\n", _representedMediaItem.smallArtworkGenerated == YES ? _NS("Yes") : _NS("No")]; + [textContent appendFormat:@"Favorited? %@\n", _representedMediaItem.smallArtworkGenerated == YES ? _NS("Yes") : _NS("No")]; + [textContent appendFormat:@"Playback progress: %2.f%%\n", _representedMediaItem.lastPlaybackPosition * 100.]; + + NSArray *array = _representedMediaItem.files; + NSUInteger count = array.count; + [textContent appendFormat:@"\nNumber of files: %lu\n", count]; + for (NSUInteger x = 0; x < count; x++) { + VLCMediaLibraryFile *file = array[x]; + [textContent appendFormat:@"URL: %@\n", file.fileURL]; + [textContent appendFormat:@"Type: %@\n", file.readableFileType]; + } + + array = _representedMediaItem.tracks; + count = array.count; + [textContent appendFormat:@"\nNumber of tracks: %lu\n", count]; + for (NSUInteger x = 0; x < count; x++) { + VLCMediaLibraryTrack *track = array[x]; + [textContent appendFormat:@"Type: %@\n", track.readableTrackType]; + [textContent appendFormat:@"Codec: %@\n", track.codec]; + [textContent appendFormat:@"Bitrate: %u\n", track.bitrate]; + if (track.language.length > 0) { + [textContent appendFormat:@"Language: %@\n", track.language]; + } + if (track.trackDescription.length > 0) { + [textContent appendFormat:@"Description: %@\n", track.trackDescription]; + } + + if (track.trackType == VLC_ML_TRACK_TYPE_AUDIO) { + [textContent appendFormat:@"Number of Channels: %u\n", track.numberOfAudioChannels]; + [textContent appendFormat:@"Sample rate: %u\n", track.audioSampleRate]; + } else if (track.trackType == VLC_ML_TRACK_TYPE_VIDEO) { + [textContent appendFormat:@"Dimensions: %ux%u px\n", track.videoWidth, track.videoHeight]; + [textContent appendFormat:@"Aspect-Ratio: %2.f\n", (float)track.sourceAspectRatio / track.sourceAspectRatioDenominator]; + [textContent appendFormat:@"Framerate: %2.f\n", (float)track.frameRate / track.frameRateDenominator];; + } + [textContent appendString:@"\n"]; + } + + self.multiLineTextLabel.stringValue = textContent; + self.window.title = _representedMediaItem.title; + if (_representedMediaItem.smallArtworkMRL) { + self.imageView.image = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:_representedMediaItem.smallArtworkMRL]]; + } +} + +@end diff --git a/modules/gui/macosx/library/VLCLibraryMenuController.m b/modules/gui/macosx/library/VLCLibraryMenuController.m index 4a8c50c73d85..9d45e5a2ef9e 100644 --- a/modules/gui/macosx/library/VLCLibraryMenuController.m +++ b/modules/gui/macosx/library/VLCLibraryMenuController.m @@ -25,12 +25,14 @@ #import "main/VLCMain.h" #import "library/VLCLibraryController.h" #import "library/VLCLibraryDataTypes.h" +#import "library/VLCLibraryInformationPanel.h" #import "extensions/NSString+Helpers.h" @interface VLCLibraryMenuController () { NSMenu *_libraryMenu; + VLCLibraryInformationPanel *_informationPanel; } @end @@ -57,9 +59,11 @@ revealItem.target = self; NSMenuItem *deleteItem = [[NSMenuItem alloc] initWithTitle:_NS("Delete from Library") action:@selector(moveToTrash:) keyEquivalent:@""]; deleteItem.target = self; + NSMenuItem *informationItem = [[NSMenuItem alloc] initWithTitle:_NS("Information...") action:@selector(showInformation:) keyEquivalent:@""]; + informationItem.target = self; _libraryMenu = [[NSMenu alloc] initWithTitle:@""]; - _libraryMenu.itemArray = @[playItem, appendItem, revealItem, deleteItem, [NSMenuItem separatorItem], addItem]; + _libraryMenu.itemArray = @[playItem, appendItem, revealItem, deleteItem, informationItem, [NSMenuItem separatorItem], addItem]; } - (void)popupMenuWithEvent:(NSEvent *)theEvent forView:(NSView *)theView @@ -116,4 +120,14 @@ } } +- (void)showInformation:(id)sender +{ + if (!_informationPanel) { + _informationPanel = [[VLCLibraryInformationPanel alloc] initWithWindowNibName:@"VLCLibraryInformationPanel"]; + } + + [_informationPanel setRepresentedMediaItem:self.representedMediaItem]; + [_informationPanel showWindow:self]; +} + @end diff --git a/po/POTFILES.in b/po/POTFILES.in index 0cc772061a5f..2ca218a6210d 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -471,6 +471,8 @@ modules/gui/macosx/library/VLCLibraryController.h modules/gui/macosx/library/VLCLibraryController.m modules/gui/macosx/library/VLCLibraryDataTypes.h modules/gui/macosx/library/VLCLibraryDataTypes.m +modules/gui/macosx/library/VLCLibraryInformationPanel.h +modules/gui/macosx/library/VLCLibraryInformationPanel.m modules/gui/macosx/library/VLCLibraryMenuController.h modules/gui/macosx/library/VLCLibraryMenuController.m modules/gui/macosx/library/VLCLibraryModel.h -- GitLab