Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
15f914a7
Commit
15f914a7
authored
Feb 04, 2009
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
playlist: moved code to playlist_edit.c
Moved functions for playlist editing (append, delete, shuffle, move) to playlist_edit.c.
parent
f3d6d536
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
394 additions
and
369 deletions
+394
-369
Makefile.am
src/Makefile.am
+1
-0
playlist.c
src/playlist.c
+0
-369
playlist_edit.c
src/playlist_edit.c
+393
-0
No files found.
src/Makefile.am
View file @
15f914a7
...
...
@@ -185,6 +185,7 @@ mpd_SOURCES = \
playlist.c
\
playlist_global.c
\
playlist_control.c
\
playlist_edit.c
\
playlist_print.c
\
playlist_save.c
\
playlist_state.c
\
...
...
src/playlist.c
View file @
15f914a7
...
...
@@ -18,35 +18,17 @@
#include "playlist_internal.h"
#include "playlist_save.h"
#include "queue_print.h"
#include "locate.h"
#include "player_control.h"
#include "command.h"
#include "ls.h"
#include "tag.h"
#include "song.h"
#include "conf.h"
#include "database.h"
#include "mapper.h"
#include "stored_playlist.h"
#include "ack.h"
#include "idle.h"
#include <glib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
static
void
incrPlaylistVersion
(
struct
playlist
*
playlist
)
{
queue_increment_version
(
&
playlist
->
queue
);
idle_add
(
IDLE_PLAYLIST
);
}
void
playlistVersionChange
(
struct
playlist
*
playlist
)
{
...
...
@@ -83,25 +65,6 @@ playlist_finish(struct playlist *playlist)
queue_finish
(
&
playlist
->
queue
);
}
void
clearPlaylist
(
struct
playlist
*
playlist
)
{
stopPlaylist
(
playlist
);
/* make sure there are no references to allocated songs
anymore */
for
(
unsigned
i
=
0
;
i
<
queue_length
(
&
playlist
->
queue
);
i
++
)
{
const
struct
song
*
song
=
queue_get
(
&
playlist
->
queue
,
i
);
if
(
!
song_in_database
(
song
))
pc_song_deleted
(
song
);
}
queue_clear
(
&
playlist
->
queue
);
playlist
->
current
=
-
1
;
incrPlaylistVersion
(
playlist
);
}
/**
* Queue a song, addressed by its order number.
*/
...
...
@@ -203,231 +166,6 @@ playlist_update_queued_song(struct playlist *playlist, const struct song *prev)
}
}
#ifndef WIN32
enum
playlist_result
playlist_append_file
(
struct
playlist
*
playlist
,
const
char
*
path
,
int
uid
,
unsigned
*
added_id
)
{
int
ret
;
struct
stat
st
;
struct
song
*
song
;
if
(
uid
<=
0
)
/* unauthenticated client */
return
PLAYLIST_RESULT_DENIED
;
ret
=
stat
(
path
,
&
st
);
if
(
ret
<
0
)
return
PLAYLIST_RESULT_ERRNO
;
if
(
st
.
st_uid
!=
(
uid_t
)
uid
&&
(
st
.
st_mode
&
0444
)
!=
0444
)
/* client is not owner */
return
PLAYLIST_RESULT_DENIED
;
song
=
song_file_load
(
path
,
NULL
);
if
(
song
==
NULL
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
addSongToPlaylist
(
playlist
,
song
,
added_id
);
}
#endif
static
struct
song
*
song_by_url
(
const
char
*
url
)
{
struct
song
*
song
;
song
=
db_get_song
(
url
);
if
(
song
!=
NULL
)
return
song
;
if
(
uri_has_scheme
(
url
))
return
song_remote_new
(
url
);
return
NULL
;
}
enum
playlist_result
addToPlaylist
(
struct
playlist
*
playlist
,
const
char
*
url
,
unsigned
*
added_id
)
{
struct
song
*
song
;
g_debug
(
"add to playlist: %s"
,
url
);
song
=
song_by_url
(
url
);
if
(
song
==
NULL
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
addSongToPlaylist
(
playlist
,
song
,
added_id
);
}
enum
playlist_result
addSongToPlaylist
(
struct
playlist
*
playlist
,
struct
song
*
song
,
unsigned
*
added_id
)
{
const
struct
song
*
queued
;
unsigned
id
;
if
(
queue_is_full
(
&
playlist
->
queue
))
return
PLAYLIST_RESULT_TOO_LARGE
;
queued
=
playlist_get_queued_song
(
playlist
);
id
=
queue_append
(
&
playlist
->
queue
,
song
);
if
(
playlist
->
queue
.
random
)
{
/* shuffle the new song into the list of remaining
songs to play */
unsigned
start
;
if
(
playlist
->
queued
>=
0
)
start
=
playlist
->
queued
+
1
;
else
start
=
playlist
->
current
+
1
;
if
(
start
<
queue_length
(
&
playlist
->
queue
))
queue_shuffle_order_last
(
&
playlist
->
queue
,
start
,
queue_length
(
&
playlist
->
queue
));
}
incrPlaylistVersion
(
playlist
);
playlist_update_queued_song
(
playlist
,
queued
);
if
(
added_id
)
*
added_id
=
id
;
return
PLAYLIST_RESULT_SUCCESS
;
}
enum
playlist_result
swapSongsInPlaylist
(
struct
playlist
*
playlist
,
unsigned
song1
,
unsigned
song2
)
{
const
struct
song
*
queued
;
if
(
!
queue_valid_position
(
&
playlist
->
queue
,
song1
)
||
!
queue_valid_position
(
&
playlist
->
queue
,
song2
))
return
PLAYLIST_RESULT_BAD_RANGE
;
queued
=
playlist_get_queued_song
(
playlist
);
queue_swap
(
&
playlist
->
queue
,
song1
,
song2
);
if
(
playlist
->
queue
.
random
)
{
/* update the queue order, so that playlist->current
still points to the current song order */
queue_swap_order
(
&
playlist
->
queue
,
queue_position_to_order
(
&
playlist
->
queue
,
song1
),
queue_position_to_order
(
&
playlist
->
queue
,
song2
));
}
else
{
/* correct the "current" song order */
if
(
playlist
->
current
==
(
int
)
song1
)
playlist
->
current
=
song2
;
else
if
(
playlist
->
current
==
(
int
)
song2
)
playlist
->
current
=
song1
;
}
incrPlaylistVersion
(
playlist
);
playlist_update_queued_song
(
playlist
,
queued
);
return
PLAYLIST_RESULT_SUCCESS
;
}
enum
playlist_result
swapSongsInPlaylistById
(
struct
playlist
*
playlist
,
unsigned
id1
,
unsigned
id2
)
{
int
song1
=
queue_id_to_position
(
&
playlist
->
queue
,
id1
);
int
song2
=
queue_id_to_position
(
&
playlist
->
queue
,
id2
);
if
(
song1
<
0
||
song2
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
swapSongsInPlaylist
(
playlist
,
song1
,
song2
);
}
enum
playlist_result
deleteFromPlaylist
(
struct
playlist
*
playlist
,
unsigned
song
)
{
const
struct
song
*
queued
;
unsigned
songOrder
;
if
(
song
>=
queue_length
(
&
playlist
->
queue
))
return
PLAYLIST_RESULT_BAD_RANGE
;
queued
=
playlist_get_queued_song
(
playlist
);
songOrder
=
queue_position_to_order
(
&
playlist
->
queue
,
song
);
if
(
playlist
->
playing
&&
playlist
->
current
==
(
int
)
songOrder
)
{
bool
paused
=
getPlayerState
()
==
PLAYER_STATE_PAUSE
;
/* the current song is going to be deleted: stop the player */
playerWait
();
playlist
->
playing
=
false
;
/* see which song is going to be played instead */
playlist
->
current
=
queue_next_order
(
&
playlist
->
queue
,
playlist
->
current
);
if
(
playlist
->
current
==
(
int
)
songOrder
)
playlist
->
current
=
-
1
;
if
(
playlist
->
current
>=
0
&&
!
paused
)
/* play the song after the deleted one */
playPlaylistOrderNumber
(
playlist
,
playlist
->
current
);
else
/* no songs left to play, stop playback
completely */
stopPlaylist
(
playlist
);
queued
=
NULL
;
}
/* now do it: remove the song */
if
(
!
song_in_database
(
queue_get
(
&
playlist
->
queue
,
song
)))
pc_song_deleted
(
queue_get
(
&
playlist
->
queue
,
song
));
queue_delete
(
&
playlist
->
queue
,
song
);
incrPlaylistVersion
(
playlist
);
/* update the "current" and "queued" variables */
if
(
playlist
->
current
>
(
int
)
songOrder
)
{
playlist
->
current
--
;
}
playlist_update_queued_song
(
playlist
,
queued
);
return
PLAYLIST_RESULT_SUCCESS
;
}
enum
playlist_result
deleteFromPlaylistById
(
struct
playlist
*
playlist
,
unsigned
id
)
{
int
song
=
queue_id_to_position
(
&
playlist
->
queue
,
id
);
if
(
song
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
deleteFromPlaylist
(
playlist
,
song
);
}
void
deleteASongFromPlaylist
(
struct
playlist
*
playlist
,
const
struct
song
*
song
)
{
for
(
int
i
=
queue_length
(
&
playlist
->
queue
)
-
1
;
i
>=
0
;
--
i
)
if
(
song
==
queue_get
(
&
playlist
->
queue
,
i
))
deleteFromPlaylist
(
playlist
,
i
);
pc_song_deleted
(
song
);
}
void
playPlaylistOrderNumber
(
struct
playlist
*
playlist
,
int
orderNum
)
{
...
...
@@ -535,71 +273,6 @@ void setPlaylistRepeatStatus(struct playlist *playlist, bool status)
idle_add
(
IDLE_OPTIONS
);
}
enum
playlist_result
moveSongInPlaylist
(
struct
playlist
*
playlist
,
unsigned
from
,
int
to
)
{
const
struct
song
*
queued
;
int
currentSong
;
if
(
!
queue_valid_position
(
&
playlist
->
queue
,
from
))
return
PLAYLIST_RESULT_BAD_RANGE
;
if
((
to
>=
0
&&
to
>=
(
int
)
queue_length
(
&
playlist
->
queue
))
||
(
to
<
0
&&
abs
(
to
)
>
(
int
)
queue_length
(
&
playlist
->
queue
)))
return
PLAYLIST_RESULT_BAD_RANGE
;
if
((
int
)
from
==
to
)
/* no-op */
return
PLAYLIST_RESULT_SUCCESS
;
queued
=
playlist_get_queued_song
(
playlist
);
/*
* (to < 0) => move to offset from current song
* (-playlist.length == to) => move to position BEFORE current song
*/
currentSong
=
playlist
->
current
>=
0
?
(
int
)
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
)
:
-
1
;
if
(
to
<
0
&&
playlist
->
current
>=
0
)
{
if
((
unsigned
)
currentSong
==
from
)
/* no-op, can't be moved to offset of itself */
return
PLAYLIST_RESULT_SUCCESS
;
to
=
(
currentSong
+
abs
(
to
))
%
queue_length
(
&
playlist
->
queue
);
}
queue_move
(
&
playlist
->
queue
,
from
,
to
);
if
(
!
playlist
->
queue
.
random
)
{
/* update current/queued */
if
(
playlist
->
current
==
(
int
)
from
)
playlist
->
current
=
to
;
else
if
(
playlist
->
current
>
(
int
)
from
&&
playlist
->
current
<=
to
)
{
playlist
->
current
--
;
}
else
if
(
playlist
->
current
>=
to
&&
playlist
->
current
<
(
int
)
from
)
{
playlist
->
current
++
;
}
}
incrPlaylistVersion
(
playlist
);
playlist_update_queued_song
(
playlist
,
queued
);
return
PLAYLIST_RESULT_SUCCESS
;
}
enum
playlist_result
moveSongInPlaylistById
(
struct
playlist
*
playlist
,
unsigned
id1
,
int
to
)
{
int
song
=
queue_id_to_position
(
&
playlist
->
queue
,
id1
);
if
(
song
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
moveSongInPlaylist
(
playlist
,
song
,
to
);
}
static
void
orderPlaylist
(
struct
playlist
*
playlist
)
{
if
(
playlist
->
current
>=
0
)
...
...
@@ -650,48 +323,6 @@ void setPlaylistRandomStatus(struct playlist *playlist, bool status)
idle_add
(
IDLE_OPTIONS
);
}
void
shufflePlaylist
(
struct
playlist
*
playlist
)
{
const
struct
song
*
queued
;
unsigned
i
;
if
(
queue_length
(
&
playlist
->
queue
)
<=
1
)
return
;
queued
=
playlist_get_queued_song
(
playlist
);
if
(
playlist
->
playing
)
{
if
(
playlist
->
current
>=
0
)
/* put current playing song first */
queue_swap
(
&
playlist
->
queue
,
0
,
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
));
if
(
playlist
->
queue
.
random
)
{
playlist
->
current
=
queue_position_to_order
(
&
playlist
->
queue
,
0
);
}
else
playlist
->
current
=
0
;
/* start shuffle after the current song */
i
=
1
;
}
else
{
/* no playback currently: shuffle everything, and
reset playlist->current */
i
=
0
;
playlist
->
current
=
-
1
;
}
/* shuffle the rest of the list */
queue_shuffle_range
(
&
playlist
->
queue
,
i
,
queue_length
(
&
playlist
->
queue
));
incrPlaylistVersion
(
playlist
);
playlist_update_queued_song
(
playlist
,
queued
);
}
int
getPlaylistCurrentSong
(
struct
playlist
*
playlist
)
{
if
(
playlist
->
current
>=
0
)
...
...
src/playlist_edit.c
0 → 100644
View file @
15f914a7
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Functions for editing the playlist (adding, removing, reordering
* songs in the queue).
*
*/
#include "playlist_internal.h"
#include "player_control.h"
#include "database.h"
#include "ls.h"
#include "song.h"
#include "idle.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
static
void
incrPlaylistVersion
(
struct
playlist
*
playlist
)
{
queue_increment_version
(
&
playlist
->
queue
);
idle_add
(
IDLE_PLAYLIST
);
}
void
clearPlaylist
(
struct
playlist
*
playlist
)
{
stopPlaylist
(
playlist
);
/* make sure there are no references to allocated songs
anymore */
for
(
unsigned
i
=
0
;
i
<
queue_length
(
&
playlist
->
queue
);
i
++
)
{
const
struct
song
*
song
=
queue_get
(
&
playlist
->
queue
,
i
);
if
(
!
song_in_database
(
song
))
pc_song_deleted
(
song
);
}
queue_clear
(
&
playlist
->
queue
);
playlist
->
current
=
-
1
;
incrPlaylistVersion
(
playlist
);
}
#ifndef WIN32
enum
playlist_result
playlist_append_file
(
struct
playlist
*
playlist
,
const
char
*
path
,
int
uid
,
unsigned
*
added_id
)
{
int
ret
;
struct
stat
st
;
struct
song
*
song
;
if
(
uid
<=
0
)
/* unauthenticated client */
return
PLAYLIST_RESULT_DENIED
;
ret
=
stat
(
path
,
&
st
);
if
(
ret
<
0
)
return
PLAYLIST_RESULT_ERRNO
;
if
(
st
.
st_uid
!=
(
uid_t
)
uid
&&
(
st
.
st_mode
&
0444
)
!=
0444
)
/* client is not owner */
return
PLAYLIST_RESULT_DENIED
;
song
=
song_file_load
(
path
,
NULL
);
if
(
song
==
NULL
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
addSongToPlaylist
(
playlist
,
song
,
added_id
);
}
#endif
static
struct
song
*
song_by_url
(
const
char
*
url
)
{
struct
song
*
song
;
song
=
db_get_song
(
url
);
if
(
song
!=
NULL
)
return
song
;
if
(
uri_has_scheme
(
url
))
return
song_remote_new
(
url
);
return
NULL
;
}
enum
playlist_result
addToPlaylist
(
struct
playlist
*
playlist
,
const
char
*
url
,
unsigned
*
added_id
)
{
struct
song
*
song
;
g_debug
(
"add to playlist: %s"
,
url
);
song
=
song_by_url
(
url
);
if
(
song
==
NULL
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
addSongToPlaylist
(
playlist
,
song
,
added_id
);
}
enum
playlist_result
addSongToPlaylist
(
struct
playlist
*
playlist
,
struct
song
*
song
,
unsigned
*
added_id
)
{
const
struct
song
*
queued
;
unsigned
id
;
if
(
queue_is_full
(
&
playlist
->
queue
))
return
PLAYLIST_RESULT_TOO_LARGE
;
queued
=
playlist_get_queued_song
(
playlist
);
id
=
queue_append
(
&
playlist
->
queue
,
song
);
if
(
playlist
->
queue
.
random
)
{
/* shuffle the new song into the list of remaining
songs to play */
unsigned
start
;
if
(
playlist
->
queued
>=
0
)
start
=
playlist
->
queued
+
1
;
else
start
=
playlist
->
current
+
1
;
if
(
start
<
queue_length
(
&
playlist
->
queue
))
queue_shuffle_order_last
(
&
playlist
->
queue
,
start
,
queue_length
(
&
playlist
->
queue
));
}
incrPlaylistVersion
(
playlist
);
playlist_update_queued_song
(
playlist
,
queued
);
if
(
added_id
)
*
added_id
=
id
;
return
PLAYLIST_RESULT_SUCCESS
;
}
enum
playlist_result
swapSongsInPlaylist
(
struct
playlist
*
playlist
,
unsigned
song1
,
unsigned
song2
)
{
const
struct
song
*
queued
;
if
(
!
queue_valid_position
(
&
playlist
->
queue
,
song1
)
||
!
queue_valid_position
(
&
playlist
->
queue
,
song2
))
return
PLAYLIST_RESULT_BAD_RANGE
;
queued
=
playlist_get_queued_song
(
playlist
);
queue_swap
(
&
playlist
->
queue
,
song1
,
song2
);
if
(
playlist
->
queue
.
random
)
{
/* update the queue order, so that playlist->current
still points to the current song order */
queue_swap_order
(
&
playlist
->
queue
,
queue_position_to_order
(
&
playlist
->
queue
,
song1
),
queue_position_to_order
(
&
playlist
->
queue
,
song2
));
}
else
{
/* correct the "current" song order */
if
(
playlist
->
current
==
(
int
)
song1
)
playlist
->
current
=
song2
;
else
if
(
playlist
->
current
==
(
int
)
song2
)
playlist
->
current
=
song1
;
}
incrPlaylistVersion
(
playlist
);
playlist_update_queued_song
(
playlist
,
queued
);
return
PLAYLIST_RESULT_SUCCESS
;
}
enum
playlist_result
swapSongsInPlaylistById
(
struct
playlist
*
playlist
,
unsigned
id1
,
unsigned
id2
)
{
int
song1
=
queue_id_to_position
(
&
playlist
->
queue
,
id1
);
int
song2
=
queue_id_to_position
(
&
playlist
->
queue
,
id2
);
if
(
song1
<
0
||
song2
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
swapSongsInPlaylist
(
playlist
,
song1
,
song2
);
}
enum
playlist_result
deleteFromPlaylist
(
struct
playlist
*
playlist
,
unsigned
song
)
{
const
struct
song
*
queued
;
unsigned
songOrder
;
if
(
song
>=
queue_length
(
&
playlist
->
queue
))
return
PLAYLIST_RESULT_BAD_RANGE
;
queued
=
playlist_get_queued_song
(
playlist
);
songOrder
=
queue_position_to_order
(
&
playlist
->
queue
,
song
);
if
(
playlist
->
playing
&&
playlist
->
current
==
(
int
)
songOrder
)
{
bool
paused
=
getPlayerState
()
==
PLAYER_STATE_PAUSE
;
/* the current song is going to be deleted: stop the player */
playerWait
();
playlist
->
playing
=
false
;
/* see which song is going to be played instead */
playlist
->
current
=
queue_next_order
(
&
playlist
->
queue
,
playlist
->
current
);
if
(
playlist
->
current
==
(
int
)
songOrder
)
playlist
->
current
=
-
1
;
if
(
playlist
->
current
>=
0
&&
!
paused
)
/* play the song after the deleted one */
playPlaylistOrderNumber
(
playlist
,
playlist
->
current
);
else
/* no songs left to play, stop playback
completely */
stopPlaylist
(
playlist
);
queued
=
NULL
;
}
/* now do it: remove the song */
if
(
!
song_in_database
(
queue_get
(
&
playlist
->
queue
,
song
)))
pc_song_deleted
(
queue_get
(
&
playlist
->
queue
,
song
));
queue_delete
(
&
playlist
->
queue
,
song
);
incrPlaylistVersion
(
playlist
);
/* update the "current" and "queued" variables */
if
(
playlist
->
current
>
(
int
)
songOrder
)
{
playlist
->
current
--
;
}
playlist_update_queued_song
(
playlist
,
queued
);
return
PLAYLIST_RESULT_SUCCESS
;
}
enum
playlist_result
deleteFromPlaylistById
(
struct
playlist
*
playlist
,
unsigned
id
)
{
int
song
=
queue_id_to_position
(
&
playlist
->
queue
,
id
);
if
(
song
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
deleteFromPlaylist
(
playlist
,
song
);
}
void
deleteASongFromPlaylist
(
struct
playlist
*
playlist
,
const
struct
song
*
song
)
{
for
(
int
i
=
queue_length
(
&
playlist
->
queue
)
-
1
;
i
>=
0
;
--
i
)
if
(
song
==
queue_get
(
&
playlist
->
queue
,
i
))
deleteFromPlaylist
(
playlist
,
i
);
pc_song_deleted
(
song
);
}
enum
playlist_result
moveSongInPlaylist
(
struct
playlist
*
playlist
,
unsigned
from
,
int
to
)
{
const
struct
song
*
queued
;
int
currentSong
;
if
(
!
queue_valid_position
(
&
playlist
->
queue
,
from
))
return
PLAYLIST_RESULT_BAD_RANGE
;
if
((
to
>=
0
&&
to
>=
(
int
)
queue_length
(
&
playlist
->
queue
))
||
(
to
<
0
&&
abs
(
to
)
>
(
int
)
queue_length
(
&
playlist
->
queue
)))
return
PLAYLIST_RESULT_BAD_RANGE
;
if
((
int
)
from
==
to
)
/* no-op */
return
PLAYLIST_RESULT_SUCCESS
;
queued
=
playlist_get_queued_song
(
playlist
);
/*
* (to < 0) => move to offset from current song
* (-playlist.length == to) => move to position BEFORE current song
*/
currentSong
=
playlist
->
current
>=
0
?
(
int
)
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
)
:
-
1
;
if
(
to
<
0
&&
playlist
->
current
>=
0
)
{
if
((
unsigned
)
currentSong
==
from
)
/* no-op, can't be moved to offset of itself */
return
PLAYLIST_RESULT_SUCCESS
;
to
=
(
currentSong
+
abs
(
to
))
%
queue_length
(
&
playlist
->
queue
);
}
queue_move
(
&
playlist
->
queue
,
from
,
to
);
if
(
!
playlist
->
queue
.
random
)
{
/* update current/queued */
if
(
playlist
->
current
==
(
int
)
from
)
playlist
->
current
=
to
;
else
if
(
playlist
->
current
>
(
int
)
from
&&
playlist
->
current
<=
to
)
{
playlist
->
current
--
;
}
else
if
(
playlist
->
current
>=
to
&&
playlist
->
current
<
(
int
)
from
)
{
playlist
->
current
++
;
}
}
incrPlaylistVersion
(
playlist
);
playlist_update_queued_song
(
playlist
,
queued
);
return
PLAYLIST_RESULT_SUCCESS
;
}
enum
playlist_result
moveSongInPlaylistById
(
struct
playlist
*
playlist
,
unsigned
id1
,
int
to
)
{
int
song
=
queue_id_to_position
(
&
playlist
->
queue
,
id1
);
if
(
song
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
moveSongInPlaylist
(
playlist
,
song
,
to
);
}
void
shufflePlaylist
(
struct
playlist
*
playlist
)
{
const
struct
song
*
queued
;
unsigned
i
;
if
(
queue_length
(
&
playlist
->
queue
)
<=
1
)
return
;
queued
=
playlist_get_queued_song
(
playlist
);
if
(
playlist
->
playing
)
{
if
(
playlist
->
current
>=
0
)
/* put current playing song first */
queue_swap
(
&
playlist
->
queue
,
0
,
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
));
if
(
playlist
->
queue
.
random
)
{
playlist
->
current
=
queue_position_to_order
(
&
playlist
->
queue
,
0
);
}
else
playlist
->
current
=
0
;
/* start shuffle after the current song */
i
=
1
;
}
else
{
/* no playback currently: shuffle everything, and
reset playlist->current */
i
=
0
;
playlist
->
current
=
-
1
;
}
/* shuffle the rest of the list */
queue_shuffle_range
(
&
playlist
->
queue
,
i
,
queue_length
(
&
playlist
->
queue
));
incrPlaylistVersion
(
playlist
);
playlist_update_queued_song
(
playlist
,
queued
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment