From d6aa728ab53c8cfa338c6b6897c2daa8f369a0f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 12 Oct 2008 21:13:59 +0000 Subject: [PATCH] * Some work in progress towards supporting "Playlist->Save" versus "Playlist->Save As...". * Fixed loading of playlists. Sorting the list after loading it is not the idea of restoring a manually sorted playlist. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28006 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../playlist/ImportPLItemsCommand.cpp | 1 + src/apps/mediaplayer/playlist/Playlist.cpp | 111 +++++++++++------- src/apps/mediaplayer/playlist/Playlist.h | 13 +- .../mediaplayer/playlist/PlaylistWindow.cpp | 52 +++++++- .../mediaplayer/playlist/PlaylistWindow.h | 15 ++- 5 files changed, 139 insertions(+), 53 deletions(-) diff --git a/src/apps/mediaplayer/playlist/ImportPLItemsCommand.cpp b/src/apps/mediaplayer/playlist/ImportPLItemsCommand.cpp index b2fb21d28e..64c97ae65d 100644 --- a/src/apps/mediaplayer/playlist/ImportPLItemsCommand.cpp +++ b/src/apps/mediaplayer/playlist/ImportPLItemsCommand.cpp @@ -54,6 +54,7 @@ ImportPLItemsCommand::ImportPLItemsCommand(Playlist* playlist, // init new entries for (int32 i = 0; i < fNewCount; i++) { if (temp.GetRefAt(i, &fNewRefs[i]) < B_OK) { + // indicate bad object init delete[] fNewRefs; fNewRefs = NULL; return; diff --git a/src/apps/mediaplayer/playlist/Playlist.cpp b/src/apps/mediaplayer/playlist/Playlist.cpp index 2dd56a0cc1..2b8f2bb2c2 100644 --- a/src/apps/mediaplayer/playlist/Playlist.cpp +++ b/src/apps/mediaplayer/playlist/Playlist.cpp @@ -253,7 +253,7 @@ Playlist::AdoptPlaylist(Playlist& other, int32 index) } if (index <= fCurrentIndex) SetCurrentRefIndex(fCurrentIndex + count); - // empty the other list, so that the entry_refs are no ours + // empty the other list, so that the entry_refs are now ours other.fRefs.MakeEmpty(); return true; } @@ -395,11 +395,31 @@ Playlist::AppendRefs(const BMessage* refsReceivedMessage, int32 appendIndex) Playlist temporaryPlaylist; Playlist* playlist = add ? &temporaryPlaylist : this; + bool sortPlaylist = true; entry_ref ref; - for (int i = 0; refsReceivedMessage->FindRef("refs", i, &ref) == B_OK; i++) - AppendToPlaylistRecursive(ref, playlist); - playlist->Sort(); + int32 subAppendIndex = CountItems(); + for (int i = 0; refsReceivedMessage->FindRef("refs", i, &ref) == B_OK; + i++) { + Playlist subPlaylist; + if (_IsPlaylist(_MIMEString(&ref))) { + AppendPlaylistToPlaylist(ref, &subPlaylist); + // Do not sort the whole playlist anymore, as that + // will screw up the ordering in the saved playlist. + sortPlaylist = false; + } else { + AppendToPlaylistRecursive(ref, &subPlaylist); + // At least sort the this subsection of the playlist + // if the whole playlist is not sorted anymore. + if (!sortPlaylist) + subPlaylist.Sort(); + } + int32 subPlaylistCount = subPlaylist.CountItems(); + AdoptPlaylist(subPlaylist, subAppendIndex); + subAppendIndex += subPlaylistCount; + } + if (sortPlaylist) + playlist->Sort(); if (add) AdoptPlaylist(temporaryPlaylist, appendIndex); @@ -416,16 +436,8 @@ Playlist::AppendToPlaylistRecursive(const entry_ref& ref, Playlist* playlist) { // recursively append the ref (dive into folders) BEntry entry(&ref, true); - if (entry.InitCheck() < B_OK) { - printf("Not OK\n"); + if (entry.InitCheck() < B_OK || !entry.Exists()) return; - } - - if (!entry.Exists()) { - BPath path = BPath(&ref); - //printf("Don't exist - %s\n", path.Path()); - return; - } if (entry.IsDirectory()) { BDirectory dir(&entry); @@ -441,39 +453,51 @@ Playlist::AppendToPlaylistRecursive(const entry_ref& ref, Playlist* playlist) if (_IsMediaFile(mimeString)) { //printf("Adding\n"); playlist->AddRef(ref); - } else if (_IsTextPlaylist(mimeString)) { - //printf("RunPlaylist thing\n"); - BFile file(&ref, B_READ_ONLY); - FileReadWrite lineReader(&file); - - BString str; - entry_ref refPath; - status_t err; - BPath path; - while (lineReader.Next(str)) { - str = str.RemoveFirst("file://"); - str = str.RemoveLast(".."); - path = BPath(str.String()); - printf("Line %s\n", path.Path()); - if (path.Path() != NULL) { - if ((err = get_ref_for_path(path.Path(), &refPath)) == B_OK) { - playlist->AddRef(refPath); - } else - printf("Error - %s: [%lx]\n", strerror(err), (int32) err); - } else - printf("Error - No File Found in playlist\n"); - } - } else if (_IsBinaryPlaylist(mimeString)) { - BFile file(&ref, B_READ_ONLY); - Playlist temp; - if (temp.Unflatten(&file) == B_OK) - playlist->AdoptPlaylist(temp, playlist->CountItems()); } else printf("MIME Type = %s\n", mimeString.String()); } } +/*static*/ void +Playlist::AppendPlaylistToPlaylist(const entry_ref& ref, Playlist* playlist) +{ + BEntry entry(&ref, true); + if (entry.InitCheck() < B_OK || !entry.Exists()) + return; + + BString mimeString = _MIMEString(&ref); + if (_IsTextPlaylist(mimeString)) { + //printf("RunPlaylist thing\n"); + BFile file(&ref, B_READ_ONLY); + FileReadWrite lineReader(&file); + + BString str; + entry_ref refPath; + status_t err; + BPath path; + while (lineReader.Next(str)) { + str = str.RemoveFirst("file://"); + str = str.RemoveLast(".."); + path = BPath(str.String()); + printf("Line %s\n", path.Path()); + if (path.Path() != NULL) { + if ((err = get_ref_for_path(path.Path(), &refPath)) == B_OK) { + playlist->AddRef(refPath); + } else + printf("Error - %s: [%lx]\n", strerror(err), (int32) err); + } else + printf("Error - No File Found in playlist\n"); + } + } else if (_IsBinaryPlaylist(mimeString)) { + BFile file(&ref, B_READ_ONLY); + Playlist temp; + if (temp.Unflatten(&file) == B_OK) + playlist->AdoptPlaylist(temp, playlist->CountItems()); + } +} + + // #pragma mark - @@ -521,6 +545,13 @@ Playlist::_IsBinaryPlaylist(const BString& mimeString) } +/*static*/ bool +Playlist::_IsPlaylist(const BString& mimeString) +{ + return _IsTextPlaylist(mimeString) || _IsBinaryPlaylist(mimeString); +} + + /*static*/ BString Playlist::_MIMEString(const entry_ref* ref) { diff --git a/src/apps/mediaplayer/playlist/Playlist.h b/src/apps/mediaplayer/playlist/Playlist.h index 94b072cc71..42a1f9e4b9 100644 --- a/src/apps/mediaplayer/playlist/Playlist.h +++ b/src/apps/mediaplayer/playlist/Playlist.h @@ -91,13 +91,16 @@ public: int32 appendIndex = -1); static void AppendToPlaylistRecursive(const entry_ref& ref, Playlist* playlist); + static void AppendPlaylistToPlaylist(const entry_ref& ref, + Playlist* playlist); private: - static int playlist_cmp(const void* p1, const void* p2); - static bool _IsMediaFile(const BString& mimeString); - static bool _IsTextPlaylist(const BString& mimeString); - static bool _IsBinaryPlaylist(const BString& mimeString); - static BString _MIMEString(const entry_ref* entry); + static int playlist_cmp(const void* p1, const void* p2); + static bool _IsMediaFile(const BString& mimeString); + static bool _IsTextPlaylist(const BString& mimeString); + static bool _IsBinaryPlaylist(const BString& mimeString); + static bool _IsPlaylist(const BString& mimeString); + static BString _MIMEString(const entry_ref* entry); void _NotifyRefAdded(const entry_ref& ref, int32 index) const; void _NotifyRefRemoved(int32 index) const; diff --git a/src/apps/mediaplayer/playlist/PlaylistWindow.cpp b/src/apps/mediaplayer/playlist/PlaylistWindow.cpp index 0d42ff583c..ffbce0c246 100644 --- a/src/apps/mediaplayer/playlist/PlaylistWindow.cpp +++ b/src/apps/mediaplayer/playlist/PlaylistWindow.cpp @@ -34,12 +34,21 @@ #include "PlaylistListView.h" #include "RWLocker.h" -#define DEBUG 1 +// TODO: +// Maintaining a playlist file on disk is a bit tricky. The playlist ref should +// be discarded when the user +// * loads a new playlist via Open, +// * loads a new playlist via dropping it on the MainWindow, +// * loads a new playlist via dropping it into the ListView while replacing +// the contents, +// * replacing the contents by other stuff. + enum { // file M_PLAYLIST_OPEN = 'open', M_PLAYLIST_SAVE = 'save', + M_PLAYLIST_SAVE_AS = 'svas', M_PLAYLIST_SAVE_RESULT = 'psrs', // edit @@ -153,6 +162,14 @@ PlaylistWindow::MessageReceived(BMessage* message) break; } case M_PLAYLIST_SAVE: { + if (fSavedPlaylistRef != entry_ref()) { + _SavePlaylist(fSavedPlaylistRef); + break; + } else { + // FALL THROUGH + } + } + case M_PLAYLIST_SAVE_AS: { BMessenger target(this); BMessage result(M_PLAYLIST_SAVE_RESULT); BMessage appMessage(M_SHOW_SAVE_PANEL); @@ -194,9 +211,13 @@ PlaylistWindow::_CreateMenu(BRect& frame) menuBar->AddItem(fileMenu); fileMenu->AddItem(new BMenuItem("Open"B_UTF8_ELLIPSIS, new BMessage(M_PLAYLIST_OPEN), 'O')); - fileMenu->AddItem(new BMenuItem("Save"B_UTF8_ELLIPSIS, - new BMessage(M_PLAYLIST_SAVE), 'S')); + fileMenu->AddItem(new BMenuItem("Save As"B_UTF8_ELLIPSIS, + new BMessage(M_PLAYLIST_SAVE_AS), 'S', B_SHIFT_KEY)); +// fileMenu->AddItem(new BMenuItem("Save", +// new BMessage(M_PLAYLIST_SAVE), 'S')); + fileMenu->AddSeparatorItem(); + fileMenu->AddItem(new BMenuItem("Close", new BMessage(B_QUIT_REQUESTED), 'W')); @@ -296,6 +317,29 @@ PlaylistWindow::_SavePlaylist(const BMessage* message) return; } + _SavePlaylist(origEntry, tempEntry, name); +} + + +void +PlaylistWindow::_SavePlaylist(const entry_ref& ref) +{ + BString tempName(ref.name); + tempName << system_time(); + entry_ref tempRef(ref); + tempRef.set_name(tempName.String()); + + BEntry origEntry(&ref); + BEntry tempEntry(&tempRef); + + _SavePlaylist(origEntry, tempEntry, ref.name); +} + + +void +PlaylistWindow::_SavePlaylist(BEntry& origEntry, BEntry& tempEntry, + const char* finalName) +{ class TempEntryRemover { public: TempEntryRemover(BEntry* entry) @@ -342,7 +386,7 @@ PlaylistWindow::_SavePlaylist(const BMessage* message) } // clobber original entry, if it exists - tempEntry.Rename(name, true); + tempEntry.Rename(finalName, true); remover.Detach(); BNodeInfo info(&file); diff --git a/src/apps/mediaplayer/playlist/PlaylistWindow.h b/src/apps/mediaplayer/playlist/PlaylistWindow.h index bd20534c05..233cae60d0 100644 --- a/src/apps/mediaplayer/playlist/PlaylistWindow.h +++ b/src/apps/mediaplayer/playlist/PlaylistWindow.h @@ -11,6 +11,7 @@ #define PLAYLIST_WINDOW_H +#include #include #include "ListenerAdapter.h" @@ -27,7 +28,7 @@ class BButton; class BFilePanel; class PlaylistWindow : public BWindow { - public: +public: PlaylistWindow(BRect frame, Playlist* playlist, Controller* controller); @@ -36,10 +37,14 @@ class PlaylistWindow : public BWindow { virtual bool QuitRequested(); virtual void MessageReceived(BMessage* message); - private: +private: void _CreateMenu(BRect& frame); void _ObjectChanged(const Notifier* object); - void _SavePlaylist(const BMessage* message); + + void _SavePlaylist(const BMessage* filePanelMessage); + void _SavePlaylist(const entry_ref& ref); + void _SavePlaylist(BEntry& origEntry, + BEntry& tempEntry, const char* finalName); Playlist* fPlaylist; PlaylistListView* fListView; @@ -47,10 +52,12 @@ class PlaylistWindow : public BWindow { BView* fTopView; BMenuItem* fUndoMI; BMenuItem* fRedoMI; - + RWLocker* fLocker; CommandStack* fCommandStack; ListenerAdapter fCommandStackListener; + + entry_ref fSavedPlaylistRef; }; #endif // PLAYLIST_WINDOW_H