* 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
This commit is contained in:
@@ -54,6 +54,7 @@ ImportPLItemsCommand::ImportPLItemsCommand(Playlist* playlist,
|
|||||||
// init new entries
|
// init new entries
|
||||||
for (int32 i = 0; i < fNewCount; i++) {
|
for (int32 i = 0; i < fNewCount; i++) {
|
||||||
if (temp.GetRefAt(i, &fNewRefs[i]) < B_OK) {
|
if (temp.GetRefAt(i, &fNewRefs[i]) < B_OK) {
|
||||||
|
// indicate bad object init
|
||||||
delete[] fNewRefs;
|
delete[] fNewRefs;
|
||||||
fNewRefs = NULL;
|
fNewRefs = NULL;
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ Playlist::AdoptPlaylist(Playlist& other, int32 index)
|
|||||||
}
|
}
|
||||||
if (index <= fCurrentIndex)
|
if (index <= fCurrentIndex)
|
||||||
SetCurrentRefIndex(fCurrentIndex + count);
|
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();
|
other.fRefs.MakeEmpty();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -395,11 +395,31 @@ Playlist::AppendRefs(const BMessage* refsReceivedMessage, int32 appendIndex)
|
|||||||
|
|
||||||
Playlist temporaryPlaylist;
|
Playlist temporaryPlaylist;
|
||||||
Playlist* playlist = add ? &temporaryPlaylist : this;
|
Playlist* playlist = add ? &temporaryPlaylist : this;
|
||||||
|
bool sortPlaylist = true;
|
||||||
|
|
||||||
entry_ref ref;
|
entry_ref ref;
|
||||||
for (int i = 0; refsReceivedMessage->FindRef("refs", i, &ref) == B_OK; i++)
|
int32 subAppendIndex = CountItems();
|
||||||
AppendToPlaylistRecursive(ref, playlist);
|
for (int i = 0; refsReceivedMessage->FindRef("refs", i, &ref) == B_OK;
|
||||||
playlist->Sort();
|
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)
|
if (add)
|
||||||
AdoptPlaylist(temporaryPlaylist, appendIndex);
|
AdoptPlaylist(temporaryPlaylist, appendIndex);
|
||||||
@@ -416,16 +436,8 @@ Playlist::AppendToPlaylistRecursive(const entry_ref& ref, Playlist* playlist)
|
|||||||
{
|
{
|
||||||
// recursively append the ref (dive into folders)
|
// recursively append the ref (dive into folders)
|
||||||
BEntry entry(&ref, true);
|
BEntry entry(&ref, true);
|
||||||
if (entry.InitCheck() < B_OK) {
|
if (entry.InitCheck() < B_OK || !entry.Exists())
|
||||||
printf("Not OK\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (!entry.Exists()) {
|
|
||||||
BPath path = BPath(&ref);
|
|
||||||
//printf("Don't exist - %s\n", path.Path());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry.IsDirectory()) {
|
if (entry.IsDirectory()) {
|
||||||
BDirectory dir(&entry);
|
BDirectory dir(&entry);
|
||||||
@@ -441,39 +453,51 @@ Playlist::AppendToPlaylistRecursive(const entry_ref& ref, Playlist* playlist)
|
|||||||
if (_IsMediaFile(mimeString)) {
|
if (_IsMediaFile(mimeString)) {
|
||||||
//printf("Adding\n");
|
//printf("Adding\n");
|
||||||
playlist->AddRef(ref);
|
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
|
} else
|
||||||
printf("MIME Type = %s\n", mimeString.String());
|
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 -
|
// #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
|
/*static*/ BString
|
||||||
Playlist::_MIMEString(const entry_ref* ref)
|
Playlist::_MIMEString(const entry_ref* ref)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -91,13 +91,16 @@ public:
|
|||||||
int32 appendIndex = -1);
|
int32 appendIndex = -1);
|
||||||
static void AppendToPlaylistRecursive(const entry_ref& ref,
|
static void AppendToPlaylistRecursive(const entry_ref& ref,
|
||||||
Playlist* playlist);
|
Playlist* playlist);
|
||||||
|
static void AppendPlaylistToPlaylist(const entry_ref& ref,
|
||||||
|
Playlist* playlist);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int playlist_cmp(const void* p1, const void* p2);
|
static int playlist_cmp(const void* p1, const void* p2);
|
||||||
static bool _IsMediaFile(const BString& mimeString);
|
static bool _IsMediaFile(const BString& mimeString);
|
||||||
static bool _IsTextPlaylist(const BString& mimeString);
|
static bool _IsTextPlaylist(const BString& mimeString);
|
||||||
static bool _IsBinaryPlaylist(const BString& mimeString);
|
static bool _IsBinaryPlaylist(const BString& mimeString);
|
||||||
static BString _MIMEString(const entry_ref* entry);
|
static bool _IsPlaylist(const BString& mimeString);
|
||||||
|
static BString _MIMEString(const entry_ref* entry);
|
||||||
void _NotifyRefAdded(const entry_ref& ref,
|
void _NotifyRefAdded(const entry_ref& ref,
|
||||||
int32 index) const;
|
int32 index) const;
|
||||||
void _NotifyRefRemoved(int32 index) const;
|
void _NotifyRefRemoved(int32 index) const;
|
||||||
|
|||||||
@@ -34,12 +34,21 @@
|
|||||||
#include "PlaylistListView.h"
|
#include "PlaylistListView.h"
|
||||||
#include "RWLocker.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 {
|
enum {
|
||||||
// file
|
// file
|
||||||
M_PLAYLIST_OPEN = 'open',
|
M_PLAYLIST_OPEN = 'open',
|
||||||
M_PLAYLIST_SAVE = 'save',
|
M_PLAYLIST_SAVE = 'save',
|
||||||
|
M_PLAYLIST_SAVE_AS = 'svas',
|
||||||
M_PLAYLIST_SAVE_RESULT = 'psrs',
|
M_PLAYLIST_SAVE_RESULT = 'psrs',
|
||||||
|
|
||||||
// edit
|
// edit
|
||||||
@@ -153,6 +162,14 @@ PlaylistWindow::MessageReceived(BMessage* message)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case M_PLAYLIST_SAVE: {
|
case M_PLAYLIST_SAVE: {
|
||||||
|
if (fSavedPlaylistRef != entry_ref()) {
|
||||||
|
_SavePlaylist(fSavedPlaylistRef);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// FALL THROUGH
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case M_PLAYLIST_SAVE_AS: {
|
||||||
BMessenger target(this);
|
BMessenger target(this);
|
||||||
BMessage result(M_PLAYLIST_SAVE_RESULT);
|
BMessage result(M_PLAYLIST_SAVE_RESULT);
|
||||||
BMessage appMessage(M_SHOW_SAVE_PANEL);
|
BMessage appMessage(M_SHOW_SAVE_PANEL);
|
||||||
@@ -194,9 +211,13 @@ PlaylistWindow::_CreateMenu(BRect& frame)
|
|||||||
menuBar->AddItem(fileMenu);
|
menuBar->AddItem(fileMenu);
|
||||||
fileMenu->AddItem(new BMenuItem("Open"B_UTF8_ELLIPSIS,
|
fileMenu->AddItem(new BMenuItem("Open"B_UTF8_ELLIPSIS,
|
||||||
new BMessage(M_PLAYLIST_OPEN), 'O'));
|
new BMessage(M_PLAYLIST_OPEN), 'O'));
|
||||||
fileMenu->AddItem(new BMenuItem("Save"B_UTF8_ELLIPSIS,
|
fileMenu->AddItem(new BMenuItem("Save As"B_UTF8_ELLIPSIS,
|
||||||
new BMessage(M_PLAYLIST_SAVE), 'S'));
|
new BMessage(M_PLAYLIST_SAVE_AS), 'S', B_SHIFT_KEY));
|
||||||
|
// fileMenu->AddItem(new BMenuItem("Save",
|
||||||
|
// new BMessage(M_PLAYLIST_SAVE), 'S'));
|
||||||
|
|
||||||
fileMenu->AddSeparatorItem();
|
fileMenu->AddSeparatorItem();
|
||||||
|
|
||||||
fileMenu->AddItem(new BMenuItem("Close",
|
fileMenu->AddItem(new BMenuItem("Close",
|
||||||
new BMessage(B_QUIT_REQUESTED), 'W'));
|
new BMessage(B_QUIT_REQUESTED), 'W'));
|
||||||
|
|
||||||
@@ -296,6 +317,29 @@ PlaylistWindow::_SavePlaylist(const BMessage* message)
|
|||||||
return;
|
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 {
|
class TempEntryRemover {
|
||||||
public:
|
public:
|
||||||
TempEntryRemover(BEntry* entry)
|
TempEntryRemover(BEntry* entry)
|
||||||
@@ -342,7 +386,7 @@ PlaylistWindow::_SavePlaylist(const BMessage* message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// clobber original entry, if it exists
|
// clobber original entry, if it exists
|
||||||
tempEntry.Rename(name, true);
|
tempEntry.Rename(finalName, true);
|
||||||
remover.Detach();
|
remover.Detach();
|
||||||
|
|
||||||
BNodeInfo info(&file);
|
BNodeInfo info(&file);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#define PLAYLIST_WINDOW_H
|
#define PLAYLIST_WINDOW_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Entry.h>
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
|
|
||||||
#include "ListenerAdapter.h"
|
#include "ListenerAdapter.h"
|
||||||
@@ -27,7 +28,7 @@ class BButton;
|
|||||||
class BFilePanel;
|
class BFilePanel;
|
||||||
|
|
||||||
class PlaylistWindow : public BWindow {
|
class PlaylistWindow : public BWindow {
|
||||||
public:
|
public:
|
||||||
PlaylistWindow(BRect frame,
|
PlaylistWindow(BRect frame,
|
||||||
Playlist* playlist,
|
Playlist* playlist,
|
||||||
Controller* controller);
|
Controller* controller);
|
||||||
@@ -36,10 +37,14 @@ class PlaylistWindow : public BWindow {
|
|||||||
virtual bool QuitRequested();
|
virtual bool QuitRequested();
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _CreateMenu(BRect& frame);
|
void _CreateMenu(BRect& frame);
|
||||||
void _ObjectChanged(const Notifier* object);
|
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;
|
Playlist* fPlaylist;
|
||||||
PlaylistListView* fListView;
|
PlaylistListView* fListView;
|
||||||
@@ -47,10 +52,12 @@ class PlaylistWindow : public BWindow {
|
|||||||
BView* fTopView;
|
BView* fTopView;
|
||||||
BMenuItem* fUndoMI;
|
BMenuItem* fUndoMI;
|
||||||
BMenuItem* fRedoMI;
|
BMenuItem* fRedoMI;
|
||||||
|
|
||||||
RWLocker* fLocker;
|
RWLocker* fLocker;
|
||||||
CommandStack* fCommandStack;
|
CommandStack* fCommandStack;
|
||||||
ListenerAdapter fCommandStackListener;
|
ListenerAdapter fCommandStackListener;
|
||||||
|
|
||||||
|
entry_ref fSavedPlaylistRef;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PLAYLIST_WINDOW_H
|
#endif // PLAYLIST_WINDOW_H
|
||||||
|
|||||||
Reference in New Issue
Block a user