[vlc-commits] [Git][videolan/vlc][master] macosx: add playlist rename dialog

Steve Lhomme (@robUx4) gitlab at videolan.org
Sun Jul 26 13:20:10 UTC 2026



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
d1388fb6 by Serhii Bykov at 2026-07-26T13:08:52+00:00
macosx: add playlist rename dialog

- - - - -


5 changed files:

- 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/VLCLibraryMenuController.m


Changes:

=====================================
modules/gui/macosx/library/VLCLibraryController.h
=====================================
@@ -27,6 +27,7 @@
 @class VLCInputItem;
 @class VLCLibraryModel;
 @class VLCMediaLibraryMediaItem;
+ at class VLCMediaLibraryPlaylist;
 @class VLCPlayQueueItem;
 
 NS_ASSUME_NONNULL_BEGIN
@@ -53,6 +54,7 @@ NS_ASSUME_NONNULL_BEGIN
 - (void)showCreatePlaylistDialogForPlayQueue;
 - (void)showCreatePlaylistDialogForPlayQueueItems:(NSArray<VLCPlayQueueItem *> *)items;
 - (void)showCreatePlaylistDialogForMediaItems:(NSArray<VLCMediaLibraryMediaItem *> *)mediaItems;
+- (void)showRenamePlaylistDialogForPlaylist:(VLCMediaLibraryPlaylist *)playlist;
 
 /**
  * Sort the entire library representation based on:


=====================================
modules/gui/macosx/library/VLCLibraryController.m
=====================================
@@ -289,27 +289,69 @@ typedef int (*folder_action_f)(vlc_medialibrary_t*, const char*);
     }
 }
 
+- (void)showRenamePlaylistDialogForPlaylist:(VLCMediaLibraryPlaylist *)playlist
+{
+    if (playlist == nil || playlist.readOnly) {
+        return;
+    }
+
+    NSString * const playlistName = [self runRenamePlaylistDialogForPlaylist:playlist];
+    if (!playlistName) {
+        return;
+    }
+
+    [playlist renameTo:playlistName];
+}
+
 - (nullable NSString *)runCreatePlaylistDialog
+{
+    return [self runPlaylistNameDialogWithTitle:_NS("Create New Playlist")
+                                informativeText:_NS("Enter a name for the new playlist:")
+                             primaryButtonTitle:_NS("Create")
+                                    initialName:nil
+                             requireNameChange:NO];
+}
+
+- (nullable NSString *)runRenamePlaylistDialogForPlaylist:(VLCMediaLibraryPlaylist *)playlist
+{
+    return [self runPlaylistNameDialogWithTitle:_NS("Rename playlist")
+                                informativeText:_NS("Please enter the new playlist name:")
+                             primaryButtonTitle:_NS("Rename")
+                                    initialName:playlist.displayString
+                             requireNameChange:YES];
+}
+
+- (nullable NSString *)runPlaylistNameDialogWithTitle:(NSString *)title
+                                      informativeText:(NSString *)informativeText
+                                   primaryButtonTitle:(NSString *)primaryButtonTitle
+                                          initialName:(nullable NSString *)initialName
+                                   requireNameChange:(BOOL)requireNameChange
 {
     NSAlert * const alert = [[NSAlert alloc] init];
-    alert.messageText = _NS("Create New Playlist");
-    alert.informativeText = _NS("Enter a name for the new playlist:");
-    NSButton * const createButton = [alert addButtonWithTitle:_NS("Create")];
-    createButton.enabled = NO;
+    alert.messageText = title;
+    alert.informativeText = informativeText;
+    NSButton * const primaryButton = [alert addButtonWithTitle:primaryButtonTitle];
+    primaryButton.enabled = NO;
     [alert addButtonWithTitle:_NS("Cancel")];
 
     NSTextField * const input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 300, 24)];
+    input.stringValue = initialName ?: @"";
     input.placeholderString = _NS("Playlist Name");
     alert.accessoryView = input;
     alert.window.initialFirstResponder = input;
 
     NSCharacterSet * const whitespace = NSCharacterSet.whitespaceAndNewlineCharacterSet;
+    NSString * const currentName =
+        [(initialName ?: @"") stringByTrimmingCharactersInSet:whitespace];
     id observer = [NSNotificationCenter.defaultCenter
         addObserverForName:NSControlTextDidChangeNotification
                    object:input
                     queue:NSOperationQueue.mainQueue
-               usingBlock:^(NSNotification *note) {
-        createButton.enabled = [input.stringValue stringByTrimmingCharactersInSet:whitespace].length > 0;
+               usingBlock:^(NSNotification * __unused note) {
+        NSString * const newName =
+            [input.stringValue stringByTrimmingCharactersInSet:whitespace];
+        primaryButton.enabled = newName.length > 0 &&
+            (!requireNameChange || ![newName isEqualToString:currentName]);
     }];
 
     const NSModalResponse response = [alert runModal];
@@ -320,7 +362,10 @@ typedef int (*folder_action_f)(vlc_medialibrary_t*, const char*);
     }
 
     NSString * const name = [input.stringValue stringByTrimmingCharactersInSet:whitespace];
-    return name.length > 0 ? name : nil;
+    if (name.length == 0 || (requireNameChange && [name isEqualToString:currentName])) {
+        return nil;
+    }
+    return name;
 }
 
 - (BOOL)createPlaylistWithName:(NSString *)playlistName fromPlayQueueItems:(NSArray<VLCPlayQueueItem *> *)items


=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.h
=====================================
@@ -288,6 +288,7 @@ typedef NS_ENUM(NSUInteger, VLCMediaLibraryParentGroupType) {
 
 - (void)removeMediaItemsAtPositions:(NSArray<NSNumber *> *)positions;
 - (BOOL)appendMediaItems:(NSArray<VLCMediaLibraryMediaItem *> *)mediaItems;
+- (BOOL)renameTo:(NSString *)name;
 
 @end
 


=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.m
=====================================
@@ -1187,6 +1187,29 @@ static NSString *genreArrayDisplayString(NSArray<VLCMediaLibraryGenre *> * const
     return res;
 }
 
+- (BOOL)renameTo:(NSString *)name
+{
+    if (_readOnly || name.length == 0) {
+        return NO;
+    }
+
+    vlc_medialibrary_t * const p_mediaLibrary = getMediaLibrary();
+    if (p_mediaLibrary == NULL) {
+        return NO;
+    }
+
+    const int result =
+        vlc_ml_playlist_rename(p_mediaLibrary, self.libraryID, name.UTF8String);
+    if (result != VLC_SUCCESS) {
+        msg_Err(getIntf(), "Failed to rename playlist %s (ID %lld) to %s",
+                self.displayString.UTF8String, self.libraryID, name.UTF8String);
+        return NO;
+    }
+
+    self.displayString = name;
+    return YES;
+}
+
 - (BOOL)appendMediaItems:(NSArray<VLCMediaLibraryMediaItem *> *)mediaItems
 {
     if (_readOnly || mediaItems.count == 0) {


=====================================
modules/gui/macosx/library/VLCLibraryMenuController.m
=====================================
@@ -56,6 +56,7 @@
     NSMenuItem *_deleteItem;
     NSMenuItem *_removeFromPlaylistItem;
     NSMenuItem *_informationItem;
+    NSMenuItem *_renamePlaylistItem;
 
     VLCLibraryAddToPlaylistMenuController *_addToPlaylistMenuController;
     NSMenuItem *_addToPlaylistItem;
@@ -120,9 +121,15 @@
                                                   keyEquivalent:@""];
     _removeFromPlaylistItem.target = self;
 
+    _renamePlaylistItem = [[NSMenuItem alloc] initWithTitle:_NS("Rename playlist")
+                                                     action:@selector(renamePlaylist:)
+                                              keyEquivalent:@""];
+    _renamePlaylistItem.target = self;
+
     [playItem vlc_setActionImageWithSystemSymbolName:@"play.fill"];
     [appendItem vlc_setActionImageWithSystemSymbolName:@"text.line.last.and.arrowtriangle.forward"];
     [_removeFromPlaylistItem vlc_setActionImageWithSystemSymbolName:@"minus.circle"];
+    [_renamePlaylistItem vlc_setActionImageWithSystemSymbolName:@"pencil"];
     [self.favoriteItem vlc_setActionImageWithSystemSymbolName:@"heart"];
     [bookmarkItem vlc_setActionImageWithSystemSymbolName:@"bookmark"];
     [addToLibraryItem vlc_setActionImageWithSystemSymbolName:@"plus.rectangle.on.folder"];
@@ -137,6 +144,7 @@
         playItem,
         appendItem,
         _addToPlaylistItem,
+        _renamePlaylistItem,
         self.favoriteItem,
         bookmarkItem,
         addToLibraryItem,
@@ -199,6 +207,7 @@
     NSArray<VLCMediaLibraryMediaItem *> * const recents = libraryModel.listOfRecentMedia;
 
     _removeFromPlaylistItem.hidden = YES;
+    _renamePlaylistItem.hidden = YES;
 
     /* no represented items (right-click on empty space) - media actions are disabled */
     if (self.representedItems.count == 0 && self.representedInputItems.count == 0) {
@@ -227,6 +236,12 @@
             }
         }
         _removeFromPlaylistItem.hidden = !allInPlaylist;
+        if (self.representedItems.count == 1 &&
+            [self.representedItems.firstObject.item isKindOfClass:VLCMediaLibraryPlaylist.class]) {
+            VLCMediaLibraryPlaylist * const playlist =
+                (VLCMediaLibraryPlaylist *)self.representedItems.firstObject.item;
+            _renamePlaylistItem.hidden = playlist.readOnly;
+        }
 
         BOOL anyNonRecent = NO;
         for (VLCLibraryRepresentedItem * const item in self.representedItems) {
@@ -395,6 +410,21 @@
     [playlist removeMediaItemsAtPositions:positions];
 }
 
+- (void)renamePlaylist:(id)sender
+{
+    if (self.representedItems.count != 1) {
+        return;
+    }
+
+    id<VLCMediaLibraryItemProtocol> const item = self.representedItems.firstObject.item;
+    if (![item isKindOfClass:VLCMediaLibraryPlaylist.class]) {
+        return;
+    }
+
+    VLCMediaLibraryPlaylist * const playlist = (VLCMediaLibraryPlaylist *)item;
+    [VLCMain.sharedInstance.libraryController showRenamePlaylistDialogForPlaylist:playlist];
+}
+
 - (void)addMedia:(id)sender
 {
     NSOpenPanel *openPanel = [NSOpenPanel openPanel];



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/d1388fb6843e59d9551f8b6ba0f2a06fdc668ced

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/d1388fb6843e59d9551f8b6ba0f2a06fdc668ced
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list