* 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
|
PlaylistListView.cpp
|
||||||
PlaylistObserver.cpp
|
PlaylistObserver.cpp
|
||||||
PlaylistWindow.cpp
|
PlaylistWindow.cpp
|
||||||
|
RandomizePLItemsCommand.cpp
|
||||||
RemovePLItemsCommand.cpp
|
RemovePLItemsCommand.cpp
|
||||||
|
|
||||||
# settings
|
# settings
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <Roster.h>
|
#include <Roster.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "EventQueue.h"
|
#include "EventQueue.h"
|
||||||
@ -225,6 +226,8 @@ main()
|
|||||||
{
|
{
|
||||||
EventQueue::CreateDefault();
|
EventQueue::CreateDefault();
|
||||||
|
|
||||||
|
srand(system_time());
|
||||||
|
|
||||||
gMainApp = new MainApp;
|
gMainApp = new MainApp;
|
||||||
gMainApp->Run();
|
gMainApp->Run();
|
||||||
delete gMainApp;
|
delete gMainApp;
|
||||||
|
@ -43,6 +43,7 @@ MovePLItemsCommand::MovePLItemsCommand(Playlist* playlist,
|
|||||||
int32 itemsBeforeIndex = 0;
|
int32 itemsBeforeIndex = 0;
|
||||||
for (int32 i = 0; i < fCount; i++) {
|
for (int32 i = 0; i < fCount; i++) {
|
||||||
if (fPlaylist->GetRefAt(fIndices[i], &fRefs[i]) < B_OK) {
|
if (fPlaylist->GetRefAt(fIndices[i], &fRefs[i]) < B_OK) {
|
||||||
|
// indicate a bad object state
|
||||||
delete[] fRefs;
|
delete[] fRefs;
|
||||||
fRefs = NULL;
|
fRefs = NULL;
|
||||||
return;
|
return;
|
||||||
@ -64,7 +65,7 @@ MovePLItemsCommand::~MovePLItemsCommand()
|
|||||||
status_t
|
status_t
|
||||||
MovePLItemsCommand::InitCheck()
|
MovePLItemsCommand::InitCheck()
|
||||||
{
|
{
|
||||||
if (!fPlaylist || !fRefs || !fIndices)
|
if (!fRefs)
|
||||||
return B_NO_INIT;
|
return B_NO_INIT;
|
||||||
|
|
||||||
// analyse the move, don't return B_OK in case
|
// analyse the move, don't return B_OK in case
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "PlaybackState.h"
|
#include "PlaybackState.h"
|
||||||
#include "Playlist.h"
|
#include "Playlist.h"
|
||||||
#include "PlaylistObserver.h"
|
#include "PlaylistObserver.h"
|
||||||
|
#include "RandomizePLItemsCommand.h"
|
||||||
#include "RemovePLItemsCommand.h"
|
#include "RemovePLItemsCommand.h"
|
||||||
|
|
||||||
using std::nothrow;
|
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 -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,6 +44,8 @@ class PlaylistListView : public SimpleListView {
|
|||||||
void RefsReceived(BMessage* message,
|
void RefsReceived(BMessage* message,
|
||||||
int32 appendIndex);
|
int32 appendIndex);
|
||||||
|
|
||||||
|
void Randomize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _FullSync();
|
void _FullSync();
|
||||||
void _AddItem(const entry_ref& ref, int32 index);
|
void _AddItem(const entry_ref& ref, int32 index);
|
||||||
|
@ -31,9 +31,13 @@
|
|||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
// file
|
||||||
M_PLAYLIST_OPEN = 'open',
|
M_PLAYLIST_OPEN = 'open',
|
||||||
M_PLAYLIST_SAVE = 'save',
|
M_PLAYLIST_SAVE = 'save',
|
||||||
M_PLAYLIST_EMPTY = 'emty'
|
|
||||||
|
// edit
|
||||||
|
M_PLAYLIST_EMPTY = 'emty',
|
||||||
|
M_PLAYLIST_RANDOMIZE = 'rand'
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SPACE 5
|
#define SPACE 5
|
||||||
@ -144,9 +148,14 @@ PlaylistWindow::MessageReceived(BMessage* message)
|
|||||||
fOpenPanel = new BFilePanel(B_OPEN_PANEL);
|
fOpenPanel = new BFilePanel(B_OPEN_PANEL);
|
||||||
fOpenPanel->Show();
|
fOpenPanel->Show();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_PLAYLIST_EMPTY:
|
case M_PLAYLIST_EMPTY:
|
||||||
fListView->RemoveAll();
|
fListView->RemoveAll();
|
||||||
break;
|
break;
|
||||||
|
case M_PLAYLIST_RANDOMIZE:
|
||||||
|
fListView->Randomize();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BWindow::MessageReceived(message);
|
BWindow::MessageReceived(message);
|
||||||
break;
|
break;
|
||||||
@ -180,6 +189,8 @@ PlaylistWindow::_CreateMenu(BRect& frame)
|
|||||||
editMenu->AddSeparatorItem();
|
editMenu->AddSeparatorItem();
|
||||||
editMenu->AddItem(new BMenuItem("Make Empty",
|
editMenu->AddItem(new BMenuItem("Make Empty",
|
||||||
new BMessage(M_PLAYLIST_EMPTY), 'N'));
|
new BMessage(M_PLAYLIST_EMPTY), 'N'));
|
||||||
|
editMenu->AddItem(new BMenuItem("Randomize",
|
||||||
|
new BMessage(M_PLAYLIST_RANDOMIZE), 'R'));
|
||||||
menuBar->AddItem(editMenu);
|
menuBar->AddItem(editMenu);
|
||||||
|
|
||||||
AddChild(menuBar);
|
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