* Added "Randomize" feature to Playlist window (Edit menu). It randomizes
either the selected items, or the entire list if nothing is selected. * Small cleanups here and there. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26264 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
0ff21997d1
commit
34ff70da4f
@ -61,6 +61,7 @@ Application MediaPlayer :
|
||||
PlaylistListView.cpp
|
||||
PlaylistObserver.cpp
|
||||
PlaylistWindow.cpp
|
||||
RandomizePLItemsCommand.cpp
|
||||
RemovePLItemsCommand.cpp
|
||||
|
||||
# settings
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <Roster.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "EventQueue.h"
|
||||
@ -225,6 +226,8 @@ main()
|
||||
{
|
||||
EventQueue::CreateDefault();
|
||||
|
||||
srand(system_time());
|
||||
|
||||
gMainApp = new MainApp;
|
||||
gMainApp->Run();
|
||||
delete gMainApp;
|
||||
|
@ -43,6 +43,7 @@ MovePLItemsCommand::MovePLItemsCommand(Playlist* playlist,
|
||||
int32 itemsBeforeIndex = 0;
|
||||
for (int32 i = 0; i < fCount; i++) {
|
||||
if (fPlaylist->GetRefAt(fIndices[i], &fRefs[i]) < B_OK) {
|
||||
// indicate a bad object state
|
||||
delete[] fRefs;
|
||||
fRefs = NULL;
|
||||
return;
|
||||
@ -64,7 +65,7 @@ MovePLItemsCommand::~MovePLItemsCommand()
|
||||
status_t
|
||||
MovePLItemsCommand::InitCheck()
|
||||
{
|
||||
if (!fPlaylist || !fRefs || !fIndices)
|
||||
if (!fRefs)
|
||||
return B_NO_INIT;
|
||||
|
||||
// analyse the move, don't return B_OK in case
|
||||
|
@ -52,7 +52,7 @@ public:
|
||||
// list functionality
|
||||
void MakeEmpty();
|
||||
int32 CountItems() const;
|
||||
|
||||
|
||||
void Sort();
|
||||
|
||||
bool AddRef(const entry_ref& ref);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "PlaybackState.h"
|
||||
#include "Playlist.h"
|
||||
#include "PlaylistObserver.h"
|
||||
#include "RandomizePLItemsCommand.h"
|
||||
#include "RemovePLItemsCommand.h"
|
||||
|
||||
using std::nothrow;
|
||||
@ -375,6 +376,41 @@ PlaylistListView::RefsReceived(BMessage* message, int32 appendIndex)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistListView::Randomize()
|
||||
{
|
||||
int32 count = CountItems();
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
BList indices;
|
||||
|
||||
// add current selection
|
||||
count = 0;
|
||||
while (true) {
|
||||
int32 index = CurrentSelection(count);
|
||||
if (index < 0)
|
||||
break;
|
||||
if (!indices.AddItem((void*)index))
|
||||
return;
|
||||
count++;
|
||||
}
|
||||
|
||||
// was anything selected?
|
||||
if (count == 0) {
|
||||
// no selection, simply add all items
|
||||
count = CountItems();
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
if (!indices.AddItem((void*)i))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fCommandStack->Perform(new (nothrow) RandomizePLItemsCommand(fPlaylist,
|
||||
(int32*)indices.Items(), indices.CountItems()));
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
|
@ -44,6 +44,8 @@ class PlaylistListView : public SimpleListView {
|
||||
void RefsReceived(BMessage* message,
|
||||
int32 appendIndex);
|
||||
|
||||
void Randomize();
|
||||
|
||||
private:
|
||||
void _FullSync();
|
||||
void _AddItem(const entry_ref& ref, int32 index);
|
||||
|
@ -31,9 +31,13 @@
|
||||
#define DEBUG 1
|
||||
|
||||
enum {
|
||||
M_PLAYLIST_OPEN = 'open',
|
||||
M_PLAYLIST_SAVE = 'save',
|
||||
M_PLAYLIST_EMPTY = 'emty'
|
||||
// file
|
||||
M_PLAYLIST_OPEN = 'open',
|
||||
M_PLAYLIST_SAVE = 'save',
|
||||
|
||||
// edit
|
||||
M_PLAYLIST_EMPTY = 'emty',
|
||||
M_PLAYLIST_RANDOMIZE = 'rand'
|
||||
};
|
||||
|
||||
#define SPACE 5
|
||||
@ -144,9 +148,14 @@ PlaylistWindow::MessageReceived(BMessage* message)
|
||||
fOpenPanel = new BFilePanel(B_OPEN_PANEL);
|
||||
fOpenPanel->Show();
|
||||
break;
|
||||
|
||||
case M_PLAYLIST_EMPTY:
|
||||
fListView->RemoveAll();
|
||||
break;
|
||||
break;
|
||||
case M_PLAYLIST_RANDOMIZE:
|
||||
fListView->Randomize();
|
||||
break;
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
break;
|
||||
@ -180,6 +189,8 @@ PlaylistWindow::_CreateMenu(BRect& frame)
|
||||
editMenu->AddSeparatorItem();
|
||||
editMenu->AddItem(new BMenuItem("Make Empty",
|
||||
new BMessage(M_PLAYLIST_EMPTY), 'N'));
|
||||
editMenu->AddItem(new BMenuItem("Randomize",
|
||||
new BMessage(M_PLAYLIST_RANDOMIZE), 'R'));
|
||||
menuBar->AddItem(editMenu);
|
||||
|
||||
AddChild(menuBar);
|
||||
|
135
src/apps/mediaplayer/playlist/RandomizePLItemsCommand.cpp
Normal file
135
src/apps/mediaplayer/playlist/RandomizePLItemsCommand.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright © 2008 Stephan Aßmus. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "RandomizePLItemsCommand.h"
|
||||
|
||||
#include <new>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <Autolock.h>
|
||||
|
||||
#include "Playlist.h"
|
||||
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
|
||||
RandomizePLItemsCommand::RandomizePLItemsCommand(Playlist* playlist,
|
||||
const int32* indices, int32 count)
|
||||
: Command()
|
||||
, fPlaylist(playlist)
|
||||
, fRefs(count > 0 ? new (nothrow) entry_ref[count] : NULL)
|
||||
, fListIndices(count > 0 ? new (nothrow) int32[count] : NULL)
|
||||
, fRandomInternalIndices(count > 0 ? new (nothrow) int32[count] : NULL)
|
||||
, fCount(count)
|
||||
{
|
||||
if (!indices || !fPlaylist || !fRefs || !fListIndices
|
||||
|| !fRandomInternalIndices) {
|
||||
// indicate a bad object state
|
||||
delete[] fRefs;
|
||||
fRefs = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(fListIndices, indices, fCount * sizeof(int32));
|
||||
|
||||
// put the available indices into a "set"
|
||||
BList indexSet;
|
||||
for (int32 i = 0; i < fCount; i++) {
|
||||
if (fPlaylist->GetRefAt(fListIndices[i], &fRefs[i]) < B_OK
|
||||
|| !indexSet.AddItem((void*)i)) {
|
||||
// indicate a bad object state
|
||||
delete[] fRefs;
|
||||
fRefs = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// remove the indices from the set in random order
|
||||
for (int32 i = 0; i < fCount; i++) {
|
||||
int32 randomSetIndex = rand() % indexSet.CountItems();
|
||||
fRandomInternalIndices[i] = (int32)indexSet.RemoveItem(randomSetIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RandomizePLItemsCommand::~RandomizePLItemsCommand()
|
||||
{
|
||||
delete[] fRefs;
|
||||
delete[] fListIndices;
|
||||
delete[] fRandomInternalIndices;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RandomizePLItemsCommand::InitCheck()
|
||||
{
|
||||
if (!fRefs)
|
||||
return B_NO_INIT;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RandomizePLItemsCommand::Perform()
|
||||
{
|
||||
return _Sort(true);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RandomizePLItemsCommand::Undo()
|
||||
{
|
||||
return _Sort(false);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RandomizePLItemsCommand::GetName(BString& name)
|
||||
{
|
||||
name << "Randomize Entries";
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RandomizePLItemsCommand::_Sort(bool random)
|
||||
{
|
||||
BAutolock _(fPlaylist);
|
||||
|
||||
// remember currently playling ref in case we move it
|
||||
entry_ref currentRef;
|
||||
bool adjustCurrentRef = fPlaylist->GetRefAt(fPlaylist->CurrentRefIndex(),
|
||||
¤tRef) == B_OK;
|
||||
|
||||
// remove refs from playlist
|
||||
for (int32 i = 0; i < fCount; i++) {
|
||||
// "- i" to account for the items already removed
|
||||
fPlaylist->RemoveRef(fListIndices[i] - i, false);
|
||||
}
|
||||
|
||||
// add refs to playlist at the randomized indices
|
||||
if (random) {
|
||||
for (int32 i = 0; i < fCount; i++) {
|
||||
if (!fPlaylist->AddRef(fRefs[fRandomInternalIndices[i]],
|
||||
fListIndices[i])) {
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int32 i = 0; i < fCount; i++) {
|
||||
if (!fPlaylist->AddRef(fRefs[i], fListIndices[i])) {
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// take care about currently played ref
|
||||
if (adjustCurrentRef)
|
||||
fPlaylist->SetCurrentRefIndex(fPlaylist->IndexOf(currentRef));
|
||||
|
||||
return B_OK;
|
||||
}
|
39
src/apps/mediaplayer/playlist/RandomizePLItemsCommand.h
Normal file
39
src/apps/mediaplayer/playlist/RandomizePLItemsCommand.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright © 2008 Stephan Aßmus. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef RANDOMIZE_PL_ITEMS_COMMAND_H
|
||||
#define RANDOMIZE_PL_ITEMS_COMMAND_H
|
||||
|
||||
|
||||
#include "Command.h"
|
||||
|
||||
class Playlist;
|
||||
struct entry_ref;
|
||||
|
||||
class RandomizePLItemsCommand : public Command {
|
||||
public:
|
||||
RandomizePLItemsCommand(
|
||||
Playlist* playlist,
|
||||
const int32* indices,
|
||||
int32 count);
|
||||
virtual ~RandomizePLItemsCommand();
|
||||
|
||||
virtual status_t InitCheck();
|
||||
|
||||
virtual status_t Perform();
|
||||
virtual status_t Undo();
|
||||
|
||||
virtual void GetName(BString& name);
|
||||
|
||||
private:
|
||||
status_t _Sort(bool random);
|
||||
|
||||
Playlist* fPlaylist;
|
||||
entry_ref* fRefs;
|
||||
int32* fListIndices;
|
||||
int32* fRandomInternalIndices;
|
||||
int32 fCount;
|
||||
};
|
||||
|
||||
#endif // RANDOMIZE_PL_ITEMS_COMMAND_H
|
Loading…
Reference in New Issue
Block a user