Mercurial > audlegacy
annotate audacious/playlist.c @ 2120:1d67cf383e32 trunk
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
author | nenolod |
---|---|
date | Fri, 15 Dec 2006 07:20:41 -0800 |
parents | f18a5b617c34 |
children | 185db04b815f |
rev | line source |
---|---|
0 | 1 /* BMP (C) GPL 2003 $top_src_dir/AUTHORS |
2 * | |
3 * based on: | |
4 * | |
5 * XMMS - Cross-platform multimedia player | |
6 * Copyright (C) 1998-2003 Peter Alm, Mikael Alm, Olle Hallnas, | |
7 * Thomas Nilsson and 4Front Technologies | |
8 * Copyright (C) 1999-2003 Haavard Kvaalen | |
9 * | |
10 * | |
11 * This program is free software; you can redistribute it and/or modify | |
12 * it under the terms of the GNU General Public License as published by | |
2105
f18a5b617c34
[svn] - move to GPLv2-only. Based on my interpretation of the license, we are
nenolod
parents:
2099
diff
changeset
|
13 * the Free Software Foundation; under version 2 of the License. |
0 | 14 * |
15 * This program is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU General Public License | |
21 * along with this program; if not, write to the Free Software | |
1459 | 22 * Foundation, Inc., 59 Tmple Place - Suite 330, Boston, MA 02110-1301, USA. |
0 | 23 */ |
24 | |
25 #ifdef HAVE_CONFIG_H | |
26 # include "config.h" | |
27 #endif | |
28 | |
29 #include "playlist.h" | |
30 | |
31 #include <glib.h> | |
32 #include <glib/gprintf.h> | |
33 #include <stdlib.h> | |
34 #include <string.h> | |
35 #include <time.h> | |
36 | |
37 #include <unistd.h> | |
38 #include <sys/types.h> | |
39 #include <sys/stat.h> | |
40 #include <sys/errno.h> | |
41 | |
42 #include "input.h" | |
43 #include "main.h" | |
1653 | 44 #include "mainwin.h" |
0 | 45 #include "libaudacious/util.h" |
46 #include "libaudacious/configdb.h" | |
47 #include "libaudacious/vfs.h" | |
2073 | 48 #include "libaudacious/urldecode.h" |
1653 | 49 #include "equalizer.h" |
538
e4e897d20791
[svn] remove libaudcore, we never did anything with it
nenolod
parents:
418
diff
changeset
|
50 #include "playback.h" |
0 | 51 #include "playlist.h" |
1550 | 52 #include "playlist_container.h" |
1653 | 53 #include "ui_playlist.h" |
0 | 54 #include "util.h" |
1269 | 55 #include "ui_fileinfo.h" |
0 | 56 |
57 #include "debug.h" | |
58 | |
1251 | 59 typedef gint (*PlaylistCompareFunc) (PlaylistEntry * a, PlaylistEntry * b); |
0 | 60 typedef void (*PlaylistSaveFunc) (FILE * file); |
61 | |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
62 /* If we manually change the song, p_p_b_j will show us where to go back to */ |
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
63 PlaylistEntry *playlist_position_before_jump = NULL; |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
64 G_LOCK_DEFINE(playlists); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
65 |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
66 static GList *playlists = NULL; |
2120
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
67 static GList *playlists_iter; |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
68 |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
69 static Playlist default_playlist = { |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
70 "Default", |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
71 #ifdef HAVE_XSPF |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
72 "playlist.xspf", |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
73 #else |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
74 "playlist.m3u", |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
75 #endif |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
76 0, |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
77 NULL, |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
78 NULL, |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
79 NULL, |
2097
75100f6b216a
[svn] - make sure &default_playlist (temporary construct) has full padding.
nenolod
parents:
2096
diff
changeset
|
80 NULL, |
75100f6b216a
[svn] - make sure &default_playlist (temporary construct) has full padding.
nenolod
parents:
2096
diff
changeset
|
81 0, |
75100f6b216a
[svn] - make sure &default_playlist (temporary construct) has full padding.
nenolod
parents:
2096
diff
changeset
|
82 0, |
75100f6b216a
[svn] - make sure &default_playlist (temporary construct) has full padding.
nenolod
parents:
2096
diff
changeset
|
83 0, |
75100f6b216a
[svn] - make sure &default_playlist (temporary construct) has full padding.
nenolod
parents:
2096
diff
changeset
|
84 0, |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
85 }; |
0 | 86 |
397
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
87 /* If this is set to TRUE, we do not probe upon playlist add. |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
88 * |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
89 * Under Audacious 0.1.x, this was not a big deal because we used |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
90 * file extension introspection instead of looking for file format magic |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
91 * strings. |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
92 * |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
93 * Because we use file magic strings, we have to fstat a file being added |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
94 * to a playlist up to 1 * <number of input plugins installed> times. |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
95 * |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
96 * This can get really slow now that we're looking for files to add to a |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
97 * playlist. (Up to 5 minutes for 5000 songs, etcetera.) |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
98 * |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
99 * So, we obviously don't want to probe while opening a large playlist |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
100 * up. Hince the boolean below. |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
101 * |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
102 * January 7, 2006, William Pitcock <nenolod@nenolod.net> |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
103 */ |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
104 static gboolean loading_playlist = FALSE; |
0 | 105 |
106 G_LOCK_DEFINE(playlist_get_info_going); | |
107 | |
108 static gchar *playlist_current_name = NULL; | |
109 | |
110 static gboolean playlist_get_info_scan_active = FALSE; | |
111 static gboolean playlist_get_info_going = FALSE; | |
112 static GThread *playlist_get_info_thread; | |
113 | |
114 static gint path_compare(const gchar * a, const gchar * b); | |
1251 | 115 static gint playlist_compare_path(PlaylistEntry * a, PlaylistEntry * b); |
116 static gint playlist_compare_filename(PlaylistEntry * a, PlaylistEntry * b); | |
117 static gint playlist_compare_title(PlaylistEntry * a, PlaylistEntry * b); | |
118 static gint playlist_compare_artist(PlaylistEntry * a, PlaylistEntry * b); | |
1588
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
119 static time_t playlist_get_mtime(const gchar *filename); |
1251 | 120 static gint playlist_compare_date(PlaylistEntry * a, PlaylistEntry * b); |
1415 | 121 static gint playlist_compare_track(PlaylistEntry * a, PlaylistEntry * b); |
1430
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
122 static gint playlist_compare_playlist(PlaylistEntry * a, PlaylistEntry * b); |
1251 | 123 |
124 static gint playlist_dupscmp_path(PlaylistEntry * a, PlaylistEntry * b); | |
125 static gint playlist_dupscmp_filename(PlaylistEntry * a, PlaylistEntry * b); | |
126 static gint playlist_dupscmp_title(PlaylistEntry * a, PlaylistEntry * b); | |
852
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
127 |
0 | 128 static PlaylistCompareFunc playlist_compare_func_table[] = { |
129 playlist_compare_path, | |
130 playlist_compare_filename, | |
131 playlist_compare_title, | |
1251 | 132 playlist_compare_artist, |
1415 | 133 playlist_compare_date, |
1430
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
134 playlist_compare_track, |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
135 playlist_compare_playlist |
0 | 136 }; |
137 | |
2083 | 138 static guint playlist_load_ins(Playlist * playlist, const gchar * filename, gint pos); |
0 | 139 |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
140 static void playlist_generate_shuffle_list(Playlist *); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
141 static void playlist_generate_shuffle_list_nolock(Playlist *); |
0 | 142 |
2085 | 143 static void playlist_recalc_total_time_nolock(Playlist *); |
144 static void playlist_recalc_total_time(Playlist *); | |
1825 | 145 static gboolean playlist_entry_get_info(PlaylistEntry * entry); |
0 | 146 |
2120
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
147 /* *********************** playlist entry code ********************** */ |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
148 |
0 | 149 PlaylistEntry * |
150 playlist_entry_new(const gchar * filename, | |
151 const gchar * title, | |
355
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
152 const gint length, |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
153 InputPlugin * dec) |
0 | 154 { |
155 PlaylistEntry *entry; | |
156 | |
157 entry = g_new0(PlaylistEntry, 1); | |
158 entry->filename = g_strdup(filename); | |
159 entry->title = str_to_utf8(title); | |
160 entry->length = length; | |
161 entry->selected = FALSE; | |
355
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
162 entry->decoder = dec; |
0 | 163 |
1825 | 164 /* only do this if we have a decoder, otherwise it just takes too long */ |
1824 | 165 if (entry->decoder) |
1825 | 166 playlist_entry_get_info(entry); |
1824 | 167 |
0 | 168 return entry; |
169 } | |
170 | |
171 void | |
172 playlist_entry_free(PlaylistEntry * entry) | |
173 { | |
174 if (!entry) | |
175 return; | |
176 | |
1588
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
177 if (entry->tuple != NULL) { |
1232 | 178 bmp_title_input_free(entry->tuple); |
1588
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
179 entry->tuple = NULL; |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
180 } |
1232 | 181 |
182 if (entry->filename != NULL) | |
183 g_free(entry->filename); | |
184 | |
185 if (entry->title != NULL) | |
186 g_free(entry->title); | |
187 | |
0 | 188 g_free(entry); |
189 } | |
190 | |
191 static gboolean | |
192 playlist_entry_get_info(PlaylistEntry * entry) | |
193 { | |
1232 | 194 TitleInput *tuple; |
1711
c7c1e346bb55
[svn] - no more busy loop if a file in playlist disappears.
yaz
parents:
1706
diff
changeset
|
195 time_t modtime; |
0 | 196 |
197 g_return_val_if_fail(entry != NULL, FALSE); | |
198 | |
1841
7d0cd3fab6a2
[svn] - mtime=-1 has been introduced to represent "uninitialized".
yaz
parents:
1834
diff
changeset
|
199 if (entry->tuple == NULL || entry->tuple->mtime > 0 || entry->tuple->mtime == -1) |
1824 | 200 modtime = playlist_get_mtime(entry->filename); |
201 else | |
202 modtime = 0; /* URI -nenolod */ | |
1711
c7c1e346bb55
[svn] - no more busy loop if a file in playlist disappears.
yaz
parents:
1706
diff
changeset
|
203 |
1690
bb1323938306
[svn] - fix for issue that was fixed in r1946 and then appeared again later :)
giacomo
parents:
1653
diff
changeset
|
204 if (entry->decoder == NULL) |
bb1323938306
[svn] - fix for issue that was fixed in r1946 and then appeared again later :)
giacomo
parents:
1653
diff
changeset
|
205 entry->decoder = input_check_file(entry->filename, FALSE); |
bb1323938306
[svn] - fix for issue that was fixed in r1946 and then appeared again later :)
giacomo
parents:
1653
diff
changeset
|
206 |
1588
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
207 /* renew tuple if file mtime is newer than tuple mtime. */ |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
208 if(entry->tuple){ |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
209 if(entry->tuple->mtime == modtime) |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
210 return TRUE; |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
211 else { |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
212 bmp_title_input_free(entry->tuple); |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
213 entry->tuple = NULL; |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
214 } |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
215 } |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
216 |
1232 | 217 if (entry->decoder == NULL || entry->decoder->get_song_tuple == NULL) |
218 tuple = input_get_song_tuple(entry->filename); | |
219 else | |
220 tuple = entry->decoder->get_song_tuple(entry->filename); | |
221 | |
222 if (tuple == NULL) | |
0 | 223 return FALSE; |
224 | |
1588
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
225 /* attach mtime */ |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
226 tuple->mtime = modtime; |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
227 |
0 | 228 /* entry is still around */ |
1356 | 229 entry->title = xmms_get_titlestring(tuple->formatter != NULL ? tuple->formatter : xmms_get_gentitle_format(), tuple); |
1232 | 230 entry->length = tuple->length; |
231 entry->tuple = tuple; | |
0 | 232 |
233 return TRUE; | |
234 } | |
235 | |
2120
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
236 /* *********************** playlist selector code ************************* */ |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
237 |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
238 void |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
239 playlist_init(void) |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
240 { |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
241 Playlist *initial_pl; |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
242 |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
243 REQUIRE_STATIC_LOCK(playlists); |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
244 |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
245 initial_pl = playlist_new(); |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
246 |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
247 playlist_add_playlist(initial_pl); |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
248 } |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
249 |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
250 void |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
251 playlist_add_playlist(Playlist *playlist) |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
252 { |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
253 playlists = g_list_append(playlists, playlist); |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
254 |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
255 if (playlists_iter == NULL) |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
256 playlists_iter = playlists; |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
257 } |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
258 |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
259 void |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
260 playlist_remove_playlist(Playlist *playlist) |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
261 { |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
262 playlists = g_list_remove(playlists, playlist); |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
263 |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
264 if (playlists_iter == NULL) |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
265 playlists_iter = playlists; |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
266 } |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
267 |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
268 /* *********************** playlist code ********************** */ |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
269 |
0 | 270 const gchar * |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
271 playlist_get_current_name(Playlist *playlist) |
0 | 272 { |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
273 return playlist->title; |
0 | 274 } |
275 | |
276 gboolean | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
277 playlist_set_current_name(Playlist *playlist, const gchar * filename) |
0 | 278 { |
2120
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
279 if (playlist->title) |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
280 g_free(playlist->title); |
0 | 281 |
282 if (!filename) { | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
283 playlist->title = NULL; |
0 | 284 return FALSE; |
285 } | |
286 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
287 playlist->title = g_strdup(filename); |
0 | 288 return TRUE; |
289 } | |
290 | |
291 static GList * | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
292 find_playlist_position_list(Playlist *playlist) |
0 | 293 { |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
294 REQUIRE_STATIC_LOCK(playlists); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
295 |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
296 if (!playlist->position) { |
0 | 297 if (cfg.shuffle) |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
298 return playlist->shuffle; |
0 | 299 else |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
300 return playlist->entries; |
0 | 301 } |
302 | |
303 if (cfg.shuffle) | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
304 return g_list_find(playlist->shuffle, playlist->position); |
0 | 305 else |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
306 return g_list_find(playlist->entries, playlist->position); |
0 | 307 } |
308 | |
309 static void | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
310 play_queued(Playlist *playlist) |
0 | 311 { |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
312 GList *tmp = playlist->queue; |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
313 |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
314 REQUIRE_STATIC_LOCK(playlists); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
315 |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
316 playlist->position = playlist->queue->data; |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
317 playlist->queue = g_list_remove_link(playlist->queue, playlist->queue); |
0 | 318 g_list_free_1(tmp); |
319 } | |
320 | |
321 void | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
322 playlist_clear(Playlist *playlist) |
0 | 323 { |
905 | 324 if (bmp_playback_get_playing()) { |
325 ip_data.stop = TRUE; | |
0 | 326 bmp_playback_stop(); |
905 | 327 ip_data.stop = FALSE; |
328 } | |
0 | 329 |
330 PLAYLIST_LOCK(); | |
331 | |
332 if (playlist) { | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
333 g_list_foreach(playlist->entries, (GFunc) playlist_entry_free, NULL); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
334 g_list_free(playlist->entries); |
2099
14f049193031
[svn] - when clearing a playlist's entries, make sure to reset the playlist's
nenolod
parents:
2098
diff
changeset
|
335 playlist->position = NULL; |
14f049193031
[svn] - when clearing a playlist's entries, make sure to reset the playlist's
nenolod
parents:
2098
diff
changeset
|
336 playlist->entries = NULL; |
0 | 337 } |
338 | |
339 PLAYLIST_UNLOCK(); | |
340 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
341 playlist_generate_shuffle_list(playlist); |
0 | 342 playlistwin_update_list(); |
2085 | 343 playlist_recalc_total_time(playlist); |
0 | 344 } |
345 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
346 static void |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
347 playlist_delete_node(Playlist * playlist, GList * node, gboolean * set_info_text, |
0 | 348 gboolean * restart_playing) |
349 { | |
350 PlaylistEntry *entry; | |
351 GList *playing_song = NULL; | |
352 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
353 REQUIRE_STATIC_LOCK(playlists); |
0 | 354 |
355 /* We call g_list_find manually here because we don't want an item | |
356 * in the shuffle_list */ | |
357 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
358 if (playlist->position) |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
359 playing_song = g_list_find(playlist->entries, playlist->position); |
0 | 360 |
361 entry = PLAYLIST_ENTRY(node->data); | |
362 | |
363 if (playing_song == node) { | |
364 *set_info_text = TRUE; | |
365 | |
366 if (bmp_playback_get_playing()) { | |
367 PLAYLIST_UNLOCK(); | |
905 | 368 ip_data.stop = TRUE; |
0 | 369 bmp_playback_stop(); |
905 | 370 ip_data.stop = FALSE; |
0 | 371 PLAYLIST_LOCK(); |
372 *restart_playing = TRUE; | |
373 } | |
374 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
375 playing_song = find_playlist_position_list(playlist); |
0 | 376 |
377 if (g_list_next(playing_song)) | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
378 playlist->position = g_list_next(playing_song)->data; |
0 | 379 else if (g_list_previous(playing_song)) |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
380 playlist->position = g_list_previous(playing_song)->data; |
0 | 381 else |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
382 playlist->position = NULL; |
0 | 383 |
384 /* Make sure the entry did not disappear under us */ | |
2081
b98891c9e155
[svn] - update playlist_delete_filenames() and friends
nenolod
parents:
2080
diff
changeset
|
385 if (g_list_index(playlist->entries, entry) == -1) |
0 | 386 return; |
387 | |
388 } | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
389 else if (g_list_position(playlist->entries, playing_song) > |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
390 g_list_position(playlist->entries, node)) { |
0 | 391 *set_info_text = TRUE; |
392 } | |
393 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
394 playlist->shuffle = g_list_remove(playlist->shuffle, entry); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
395 playlist->entries = g_list_remove_link(playlist->entries, node); |
0 | 396 playlist_entry_free(entry); |
397 g_list_free_1(node); | |
398 | |
2085 | 399 playlist_recalc_total_time_nolock(playlist); |
0 | 400 } |
401 | |
402 void | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
403 playlist_delete_index(Playlist *playlist, guint pos) |
0 | 404 { |
405 gboolean restart_playing = FALSE, set_info_text = FALSE; | |
406 GList *node; | |
407 | |
408 PLAYLIST_LOCK(); | |
409 | |
410 if (!playlist) { | |
411 PLAYLIST_UNLOCK(); | |
412 return; | |
413 } | |
414 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
415 node = g_list_nth(playlist->entries, pos); |
0 | 416 |
417 if (!node) { | |
418 PLAYLIST_UNLOCK(); | |
419 return; | |
420 } | |
421 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
422 playlist_delete_node(playlist, node, &set_info_text, &restart_playing); |
0 | 423 |
424 PLAYLIST_UNLOCK(); | |
425 | |
2085 | 426 playlist_recalc_total_time(playlist); |
0 | 427 |
428 playlistwin_update_list(); | |
429 if (restart_playing) { | |
2096 | 430 if (playlist->position) { |
0 | 431 bmp_playback_initiate(); |
432 } | |
433 else { | |
434 mainwin_clear_song_info(); | |
435 } | |
436 } | |
437 else if (set_info_text) { | |
438 mainwin_set_info_text(); | |
439 } | |
440 } | |
441 | |
442 void | |
2081
b98891c9e155
[svn] - update playlist_delete_filenames() and friends
nenolod
parents:
2080
diff
changeset
|
443 playlist_delete_filenames(Playlist * playlist, GList * filenames) |
0 | 444 { |
445 GList *node, *fnode; | |
446 gboolean set_info_text = FALSE, restart_playing = FALSE; | |
447 | |
448 PLAYLIST_LOCK(); | |
449 | |
450 for (fnode = filenames; fnode; fnode = g_list_next(fnode)) { | |
2082 | 451 node = playlist->entries; |
0 | 452 |
453 while (node) { | |
454 GList *next = g_list_next(node); | |
455 PlaylistEntry *entry = node->data; | |
456 | |
457 if (!strcmp(entry->filename, fnode->data)) | |
2081
b98891c9e155
[svn] - update playlist_delete_filenames() and friends
nenolod
parents:
2080
diff
changeset
|
458 playlist_delete_node(playlist, node, &set_info_text, &restart_playing); |
0 | 459 |
460 node = next; | |
461 } | |
462 } | |
463 | |
2085 | 464 playlist_recalc_total_time(playlist); |
0 | 465 PLAYLIST_UNLOCK(); |
466 | |
467 playlistwin_update_list(); | |
468 | |
469 if (restart_playing) { | |
2096 | 470 if (playlist->position) { |
0 | 471 bmp_playback_initiate(); |
472 } | |
473 else { | |
474 mainwin_clear_song_info(); | |
475 } | |
476 } | |
477 else if (set_info_text) { | |
478 mainwin_set_info_text(); | |
479 } | |
480 | |
481 } | |
482 | |
483 void | |
2081
b98891c9e155
[svn] - update playlist_delete_filenames() and friends
nenolod
parents:
2080
diff
changeset
|
484 playlist_delete(Playlist * playlist, gboolean crop) |
0 | 485 { |
486 gboolean restart_playing = FALSE, set_info_text = FALSE; | |
487 GList *node, *next_node; | |
488 PlaylistEntry *entry; | |
489 | |
2081
b98891c9e155
[svn] - update playlist_delete_filenames() and friends
nenolod
parents:
2080
diff
changeset
|
490 g_return_if_fail(playlist != NULL); |
b98891c9e155
[svn] - update playlist_delete_filenames() and friends
nenolod
parents:
2080
diff
changeset
|
491 |
0 | 492 PLAYLIST_LOCK(); |
493 | |
2081
b98891c9e155
[svn] - update playlist_delete_filenames() and friends
nenolod
parents:
2080
diff
changeset
|
494 node = playlist->entries; |
0 | 495 |
496 while (node) { | |
497 entry = PLAYLIST_ENTRY(node->data); | |
498 | |
499 next_node = g_list_next(node); | |
500 | |
501 if ((entry->selected && !crop) || (!entry->selected && crop)) { | |
2081
b98891c9e155
[svn] - update playlist_delete_filenames() and friends
nenolod
parents:
2080
diff
changeset
|
502 playlist_delete_node(playlist, node, &set_info_text, &restart_playing); |
0 | 503 } |
504 | |
505 node = next_node; | |
506 } | |
507 | |
508 PLAYLIST_UNLOCK(); | |
509 | |
2085 | 510 playlist_recalc_total_time(playlist); |
0 | 511 |
512 if (set_info_text) { | |
513 mainwin_set_info_text(); | |
514 } | |
515 | |
516 if (restart_playing) { | |
2096 | 517 if (playlist->position) { |
0 | 518 bmp_playback_initiate(); |
519 } | |
520 else { | |
521 mainwin_clear_song_info(); | |
522 } | |
523 } | |
524 | |
525 playlistwin_update_list(); | |
526 } | |
527 | |
528 static void | |
2082 | 529 __playlist_ins_with_info(Playlist * playlist, |
530 const gchar * filename, | |
0 | 531 gint pos, |
532 const gchar * title, | |
355
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
533 gint len, |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
534 InputPlugin * dec) |
0 | 535 { |
536 g_return_if_fail(filename != NULL); | |
537 | |
538 PLAYLIST_LOCK(); | |
2082 | 539 playlist->entries = g_list_insert(playlist->entries, |
355
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
540 playlist_entry_new(filename, title, len, dec), |
0 | 541 pos); |
542 PLAYLIST_UNLOCK(); | |
543 | |
2026 | 544 g_mutex_lock(mutex_scan); |
0 | 545 playlist_get_info_scan_active = TRUE; |
2026 | 546 g_mutex_unlock(mutex_scan); |
547 g_cond_signal(cond_scan); | |
0 | 548 } |
549 | |
550 static void | |
2082 | 551 __playlist_ins_with_info_tuple(Playlist * playlist, |
552 const gchar * filename, | |
1584 | 553 gint pos, |
554 TitleInput *tuple, | |
555 InputPlugin * dec) | |
556 { | |
557 GList *node; | |
558 PlaylistEntry *entry; | |
559 | |
2082 | 560 g_return_if_fail(playlist != NULL); |
1584 | 561 g_return_if_fail(filename != NULL); |
562 | |
563 PLAYLIST_LOCK(); | |
2082 | 564 playlist->entries = g_list_insert(playlist->entries, |
1584 | 565 playlist_entry_new(filename, tuple->track_name, tuple->length, dec), |
566 pos); | |
567 | |
2082 | 568 if (pos < 0) |
569 pos = g_list_length(playlist->entries) - 1; /* last element. */ | |
570 | |
571 node = g_list_nth(playlist->entries, pos); | |
1584 | 572 entry = PLAYLIST_ENTRY(node->data); |
573 | |
1587
c073fd82ded6
[svn] - Don't explode when loading http streams from xspf files.
nhjm449
parents:
1584
diff
changeset
|
574 if (tuple != NULL) { |
c073fd82ded6
[svn] - Don't explode when loading http streams from xspf files.
nhjm449
parents:
1584
diff
changeset
|
575 entry->title = xmms_get_titlestring(tuple->formatter != NULL ? tuple->formatter : xmms_get_gentitle_format(), tuple); |
c073fd82ded6
[svn] - Don't explode when loading http streams from xspf files.
nhjm449
parents:
1584
diff
changeset
|
576 entry->length = tuple->length; |
c073fd82ded6
[svn] - Don't explode when loading http streams from xspf files.
nhjm449
parents:
1584
diff
changeset
|
577 entry->tuple = tuple; |
c073fd82ded6
[svn] - Don't explode when loading http streams from xspf files.
nhjm449
parents:
1584
diff
changeset
|
578 } |
1584 | 579 |
580 PLAYLIST_UNLOCK(); | |
581 | |
2026 | 582 g_mutex_lock(mutex_scan); |
1584 | 583 playlist_get_info_scan_active = TRUE; |
2026 | 584 g_mutex_unlock(mutex_scan); |
585 g_cond_signal(cond_scan); | |
1584 | 586 } |
587 | |
588 static void | |
2082 | 589 __playlist_ins(Playlist * playlist, const gchar * filename, gint pos, InputPlugin *dec) |
0 | 590 { |
2082 | 591 __playlist_ins_with_info(playlist, filename, pos, NULL, -1, dec); |
2085 | 592 playlist_recalc_total_time(playlist); |
0 | 593 } |
594 | |
595 gboolean | |
2082 | 596 playlist_ins(Playlist * playlist, const gchar * filename, gint pos) |
0 | 597 { |
598 gchar buf[64], *p; | |
599 gint r; | |
600 VFSFile *file; | |
355
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
601 InputPlugin *dec; |
0 | 602 |
2082 | 603 g_return_val_if_fail(playlist != NULL, FALSE); |
604 g_return_val_if_fail(filename != NULL, FALSE); | |
605 | |
0 | 606 if (is_playlist_name(filename)) { |
1607
57676c0f2f33
[svn] - prevents input_check_file() working on loading playlist.
yaz
parents:
1588
diff
changeset
|
607 loading_playlist = TRUE; |
2083 | 608 playlist_load_ins(playlist, filename, pos); |
1607
57676c0f2f33
[svn] - prevents input_check_file() working on loading playlist.
yaz
parents:
1588
diff
changeset
|
609 loading_playlist = FALSE; |
0 | 610 return TRUE; |
611 } | |
612 | |
1165 | 613 if (loading_playlist == TRUE || cfg.playlist_detect == TRUE) |
397
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
614 dec = NULL; |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
615 else |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
616 dec = input_check_file(filename, TRUE); |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
617 |
1165 | 618 if (cfg.playlist_detect == TRUE || loading_playlist == TRUE || (loading_playlist == FALSE && dec != NULL)) |
397
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
619 { |
2082 | 620 __playlist_ins(playlist, filename, pos, dec); |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
621 playlist_generate_shuffle_list(playlist); |
397
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
622 playlistwin_update_list(); |
0 | 623 return TRUE; |
624 } | |
625 | |
626 /* Some files (typically produced by some cgi-scripts) don't have | |
627 * the correct extension. Try to recognize these files by looking | |
628 * at their content. We only check for http entries since it does | |
629 * not make sense to have file entries in a playlist fetched from | |
630 * the net. */ | |
631 | |
632 /* Some strange people put fifo's with the .mp3 extension, so we | |
633 * need to make sure it's a real file (otherwise fread() may block | |
634 * and stall the entire program) */ | |
635 | |
636 /* FIXME: bah, FIFOs actually pass this regular file test */ | |
637 if (!vfs_file_test(filename, G_FILE_TEST_IS_REGULAR)) | |
638 return FALSE; | |
639 | |
640 if (!(file = vfs_fopen(filename, "rb"))) | |
641 return FALSE; | |
642 | |
643 r = vfs_fread(buf, 1, sizeof(buf), file); | |
644 vfs_fclose(file); | |
645 | |
646 for (p = buf; r-- > 0 && (*p == '\r' || *p == '\n'); p++); | |
647 | |
648 if (r > 5 && str_has_prefix_nocase(p, "http:")) { | |
2083 | 649 playlist_load_ins(playlist, filename, pos); |
0 | 650 return TRUE; |
651 } | |
652 | |
653 return FALSE; | |
654 } | |
655 | |
656 /* FIXME: The next few functions are specific to Unix | |
657 * filesystems. Either abstract it away, or don't even bother checking | |
658 * at such low level */ | |
659 | |
660 typedef struct { | |
661 dev_t dev; | |
662 ino_t ino; | |
663 } DeviceInode; | |
664 | |
665 static DeviceInode * | |
666 devino_new(dev_t device, | |
667 ino_t inode) | |
668 { | |
669 DeviceInode *devino = g_new0(DeviceInode, 1); | |
670 | |
671 if (devino) | |
672 { | |
673 devino->dev = device; | |
674 devino->ino = inode; | |
675 } | |
676 | |
677 return devino; | |
678 } | |
679 | |
680 static guint | |
681 devino_hash(gconstpointer key) | |
682 { | |
683 const DeviceInode *d = key; | |
684 return d->ino; | |
685 } | |
686 | |
687 static gint | |
688 devino_compare(gconstpointer a, | |
689 gconstpointer b) | |
690 { | |
691 const DeviceInode *da = a, *db = b; | |
692 return (da->dev == db->dev && da->ino == db->ino); | |
693 } | |
694 | |
695 static gboolean | |
696 devino_destroy(gpointer key, | |
697 gpointer value, | |
698 gpointer data) | |
699 { | |
700 g_free(key); | |
701 return TRUE; | |
702 } | |
703 | |
704 static gboolean | |
705 file_is_hidden(const gchar * filename) | |
706 { | |
707 // FIXME: remove the const cast | |
708 g_return_val_if_fail(filename != NULL, FALSE); | |
709 return (g_basename((gchar *) filename)[0] == '.'); | |
710 } | |
711 | |
712 static GList * | |
713 playlist_dir_find_files(const gchar * path, | |
714 gboolean background, | |
715 GHashTable * htab) | |
716 { | |
717 GDir *dir; | |
718 GList *list = NULL, *ilist; | |
719 const gchar *dir_entry; | |
720 | |
721 struct stat statbuf; | |
722 DeviceInode *devino; | |
723 | |
724 if (!g_file_test(path, G_FILE_TEST_IS_DIR)) | |
725 return NULL; | |
726 | |
727 stat(path, &statbuf); | |
728 devino = devino_new(statbuf.st_dev, statbuf.st_ino); | |
729 | |
730 if (g_hash_table_lookup(htab, devino)) { | |
731 g_free(devino); | |
732 return NULL; | |
733 } | |
734 | |
735 g_hash_table_insert(htab, devino, GINT_TO_POINTER(1)); | |
736 | |
737 if ((ilist = input_scan_dir(path))) { | |
738 GList *node; | |
739 for (node = ilist; node; node = g_list_next(node)) { | |
740 gchar *name = g_build_filename(path, node->data, NULL); | |
741 list = g_list_prepend(list, name); | |
742 g_free(node->data); | |
743 } | |
744 g_list_free(ilist); | |
745 return list; | |
746 } | |
747 | |
748 if (!(dir = g_dir_open(path, 0, NULL))) | |
749 return NULL; | |
750 | |
751 while ((dir_entry = g_dir_read_name(dir))) { | |
752 gchar *filename; | |
753 | |
754 if (file_is_hidden(dir_entry)) | |
755 continue; | |
756 | |
757 filename = g_build_filename(path, dir_entry, NULL); | |
758 | |
759 if (g_file_test(filename, G_FILE_TEST_IS_DIR)) { | |
760 GList *sub; | |
761 sub = playlist_dir_find_files(filename, background, htab); | |
762 g_free(filename); | |
763 list = g_list_concat(list, sub); | |
764 } | |
1165 | 765 else if (cfg.playlist_detect == TRUE) |
766 list = g_list_prepend(list, filename); | |
0 | 767 else if (input_check_file(filename, TRUE)) |
768 list = g_list_prepend(list, filename); | |
769 else | |
770 g_free(filename); | |
771 | |
772 while (background && gtk_events_pending()) | |
773 gtk_main_iteration(); | |
774 } | |
775 g_dir_close(dir); | |
776 | |
777 return list; | |
778 } | |
779 | |
780 gboolean | |
2082 | 781 playlist_add(Playlist * playlist, const gchar * filename) |
0 | 782 { |
2082 | 783 return playlist_ins(playlist, filename, -1); |
0 | 784 } |
785 | |
786 guint | |
2083 | 787 playlist_add_dir(Playlist * playlist, const gchar * directory) |
0 | 788 { |
2083 | 789 return playlist_ins_dir(playlist, directory, -1, TRUE); |
0 | 790 } |
791 | |
792 guint | |
2083 | 793 playlist_add_url(Playlist * playlist, const gchar * url) |
0 | 794 { |
2083 | 795 return playlist_ins_url(playlist, url, -1); |
0 | 796 } |
797 | |
798 guint | |
2083 | 799 playlist_ins_dir(Playlist * playlist, const gchar * path, |
0 | 800 gint pos, |
801 gboolean background) | |
802 { | |
803 guint entries = 0; | |
804 GList *list, *node; | |
805 GHashTable *htab; | |
806 | |
807 htab = g_hash_table_new(devino_hash, devino_compare); | |
808 | |
809 list = playlist_dir_find_files(path, background, htab); | |
810 list = g_list_sort(list, (GCompareFunc) path_compare); | |
811 | |
812 g_hash_table_foreach_remove(htab, devino_destroy, NULL); | |
813 | |
814 for (node = list; node; node = g_list_next(node)) { | |
2083 | 815 __playlist_ins(playlist, node->data, pos, NULL); |
0 | 816 g_free(node->data); |
817 entries++; | |
818 if (pos >= 0) | |
819 pos++; | |
820 } | |
821 | |
822 g_list_free(list); | |
823 | |
2085 | 824 playlist_recalc_total_time(playlist); |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
825 playlist_generate_shuffle_list(playlist); |
0 | 826 playlistwin_update_list(); |
827 return entries; | |
828 } | |
829 | |
830 guint | |
2083 | 831 playlist_ins_url(Playlist * playlist, const gchar * string, |
0 | 832 gint pos) |
833 { | |
834 gchar *tmp; | |
835 gint i = 1, entries = 0; | |
836 gboolean first = TRUE; | |
837 guint firstpos = 0; | |
838 gboolean success = FALSE; | |
839 gchar *decoded = NULL; | |
840 | |
2083 | 841 g_return_val_if_fail(playlist != NULL, 0); |
0 | 842 g_return_val_if_fail(string != NULL, 0); |
843 | |
844 playlistwin_update_list(); | |
845 | |
846 while (*string) { | |
847 GList *node; | |
848 tmp = strchr(string, '\n'); | |
849 if (tmp) { | |
850 if (*(tmp - 1) == '\r') | |
851 *(tmp - 1) = '\0'; | |
852 *tmp = '\0'; | |
853 } | |
854 | |
2010
5f19843a038b
[svn] - xmms_urldecode_path() is no longer needed due to NewVFS layer.
nenolod
parents:
1991
diff
changeset
|
855 decoded = g_strdup(string); |
0 | 856 |
857 if (g_file_test(decoded, G_FILE_TEST_IS_DIR)) { | |
2083 | 858 i = playlist_ins_dir(playlist, decoded, pos, FALSE); |
0 | 859 } |
860 else { | |
861 if (is_playlist_name(decoded)) { | |
2083 | 862 i = playlist_load_ins(playlist, decoded, pos); |
0 | 863 } |
864 else { | |
2083 | 865 success = playlist_ins(playlist, decoded, pos); |
0 | 866 i = 1; |
867 } | |
868 } | |
869 | |
870 g_free(decoded); | |
871 | |
872 PLAYLIST_LOCK(); | |
873 node = g_list_nth(playlist_get(), pos); | |
874 PLAYLIST_UNLOCK(); | |
875 | |
876 entries += i; | |
877 | |
878 if (first) { | |
879 first = FALSE; | |
880 firstpos = pos; | |
881 } | |
882 | |
883 if (pos >= 0) | |
884 pos += i; | |
885 if (!tmp) | |
886 break; | |
887 | |
888 string = tmp + 1; | |
889 } | |
890 | |
2085 | 891 playlist_recalc_total_time(playlist); |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
892 playlist_generate_shuffle_list(playlist); |
0 | 893 playlistwin_update_list(); |
894 | |
895 return entries; | |
896 } | |
897 | |
898 void | |
2098
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
899 playlist_set_info_old_abi(const gchar * title, gint length, gint rate, |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
900 gint freq, gint nch) |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
901 { |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
902 Playlist *playlist = playlist_get_active(); |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
903 |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
904 PLAYLIST_LOCK(); |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
905 |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
906 g_return_if_fail(playlist != NULL); |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
907 |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
908 if (playlist->position) { |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
909 g_free(playlist->position->title); |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
910 playlist->position->title = g_strdup(title); |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
911 playlist->position->length = length; |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
912 } |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
913 |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
914 PLAYLIST_UNLOCK(); |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
915 |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
916 playlist_recalc_total_time(playlist); |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
917 |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
918 mainwin_set_song_info(rate, freq, nch); |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
919 } |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
920 |
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
921 void |
2083 | 922 playlist_set_info(Playlist * playlist, const gchar * title, gint length, gint rate, |
0 | 923 gint freq, gint nch) |
924 { | |
925 PLAYLIST_LOCK(); | |
926 | |
2083 | 927 g_return_if_fail(playlist != NULL); |
928 | |
929 if (playlist->position) { | |
2098
425963ded156
[svn] - provide the old ABI for plugins (intermediate layer).
nenolod
parents:
2097
diff
changeset
|
930 g_free(playlist->position->title); |
2083 | 931 playlist->position->title = g_strdup(title); |
932 playlist->position->length = length; | |
0 | 933 } |
934 | |
935 PLAYLIST_UNLOCK(); | |
936 | |
2085 | 937 playlist_recalc_total_time(playlist); |
0 | 938 |
1653 | 939 mainwin_set_song_info(rate, freq, nch); |
0 | 940 } |
941 | |
942 void | |
2084 | 943 playlist_check_pos_current(Playlist *playlist) |
0 | 944 { |
945 gint pos, row, bottom; | |
946 | |
947 PLAYLIST_LOCK(); | |
2084 | 948 if (!playlist || !playlist->position || !playlistwin_list) { |
0 | 949 PLAYLIST_UNLOCK(); |
950 return; | |
951 } | |
952 | |
2084 | 953 pos = g_list_index(playlist->entries, playlist->position); |
0 | 954 |
955 if (playlistwin_item_visible(pos)) { | |
956 PLAYLIST_UNLOCK(); | |
957 return; | |
958 } | |
959 | |
2084 | 960 bottom = MAX(0, playlist_get_length_nolock(playlist) - |
0 | 961 playlistwin_list->pl_num_visible); |
962 row = CLAMP(pos - playlistwin_list->pl_num_visible / 2, 0, bottom); | |
963 PLAYLIST_UNLOCK(); | |
964 playlistwin_set_toprow(row); | |
2026 | 965 g_cond_signal(cond_scan); |
0 | 966 } |
967 | |
968 void | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
969 playlist_next(Playlist *playlist) |
0 | 970 { |
971 GList *plist_pos_list; | |
972 gboolean restart_playing = FALSE; | |
973 | |
974 PLAYLIST_LOCK(); | |
975 if (!playlist) { | |
976 PLAYLIST_UNLOCK(); | |
977 return; | |
978 } | |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
979 |
2084 | 980 if ((playlist_position_before_jump != NULL) && playlist->queue == NULL) |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
981 { |
2084 | 982 playlist->position = playlist_position_before_jump; |
983 playlist_position_before_jump = NULL; | |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
984 } |
0 | 985 |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
986 plist_pos_list = find_playlist_position_list(playlist); |
0 | 987 |
2084 | 988 if (!cfg.repeat && !g_list_next(plist_pos_list) && playlist->queue == NULL) { |
0 | 989 PLAYLIST_UNLOCK(); |
990 return; | |
991 } | |
992 | |
993 if (bmp_playback_get_playing()) { | |
994 /* We need to stop before changing playlist_position */ | |
995 PLAYLIST_UNLOCK(); | |
895
1b919783797e
[svn] - should fix the ability to change songs while paused
nhjm449
parents:
853
diff
changeset
|
996 ip_data.stop = TRUE; |
0 | 997 bmp_playback_stop(); |
895
1b919783797e
[svn] - should fix the ability to change songs while paused
nhjm449
parents:
853
diff
changeset
|
998 ip_data.stop = FALSE; |
0 | 999 PLAYLIST_LOCK(); |
1000 restart_playing = TRUE; | |
1001 } | |
1002 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1003 plist_pos_list = find_playlist_position_list(playlist); |
2084 | 1004 if (playlist->queue != NULL) |
1005 play_queued(playlist); | |
0 | 1006 else if (g_list_next(plist_pos_list)) |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1007 playlist->position = g_list_next(plist_pos_list)->data; |
0 | 1008 else if (cfg.repeat) { |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1009 playlist->position = NULL; |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1010 playlist_generate_shuffle_list_nolock(playlist); |
0 | 1011 if (cfg.shuffle) |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1012 playlist->position = playlist->shuffle->data; |
0 | 1013 else |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1014 playlist->position = playlist->entries->data; |
0 | 1015 } |
1016 PLAYLIST_UNLOCK(); | |
2084 | 1017 playlist_check_pos_current(playlist); |
0 | 1018 |
1019 if (restart_playing) | |
1020 bmp_playback_initiate(); | |
1021 else { | |
1022 mainwin_set_info_text(); | |
1023 playlistwin_update_list(); | |
1024 } | |
1025 } | |
1026 | |
1027 void | |
2084 | 1028 playlist_prev(Playlist *playlist) |
0 | 1029 { |
1030 GList *plist_pos_list; | |
1031 gboolean restart_playing = FALSE; | |
1032 | |
1033 PLAYLIST_LOCK(); | |
1034 if (!playlist) { | |
1035 PLAYLIST_UNLOCK(); | |
1036 return; | |
1037 } | |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1038 |
2084 | 1039 if ((playlist_position_before_jump != NULL) && playlist->queue == NULL) |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1040 { |
2096 | 1041 playlist->position = playlist_position_before_jump; |
2084 | 1042 playlist_position_before_jump = NULL; |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1043 } |
0 | 1044 |
2084 | 1045 plist_pos_list = find_playlist_position_list(playlist); |
0 | 1046 |
1047 if (!cfg.repeat && !g_list_previous(plist_pos_list)) { | |
1048 PLAYLIST_UNLOCK(); | |
1049 return; | |
1050 } | |
1051 | |
1052 if (bmp_playback_get_playing()) { | |
1053 /* We need to stop before changing playlist_position */ | |
1054 PLAYLIST_UNLOCK(); | |
895
1b919783797e
[svn] - should fix the ability to change songs while paused
nhjm449
parents:
853
diff
changeset
|
1055 ip_data.stop = TRUE; |
0 | 1056 bmp_playback_stop(); |
895
1b919783797e
[svn] - should fix the ability to change songs while paused
nhjm449
parents:
853
diff
changeset
|
1057 ip_data.stop = FALSE; |
0 | 1058 PLAYLIST_LOCK(); |
1059 restart_playing = TRUE; | |
1060 } | |
1061 | |
2084 | 1062 plist_pos_list = find_playlist_position_list(playlist); |
0 | 1063 if (g_list_previous(plist_pos_list)) { |
2096 | 1064 playlist->position = g_list_previous(plist_pos_list)->data; |
0 | 1065 } |
1066 else if (cfg.repeat) { | |
1067 GList *node; | |
2096 | 1068 playlist->position = NULL; |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1069 playlist_generate_shuffle_list_nolock(playlist); |
0 | 1070 if (cfg.shuffle) |
2084 | 1071 node = g_list_last(playlist->shuffle); |
0 | 1072 else |
2084 | 1073 node = g_list_last(playlist->entries); |
0 | 1074 if (node) |
2096 | 1075 playlist->position = node->data; |
0 | 1076 } |
1077 | |
1078 PLAYLIST_UNLOCK(); | |
1079 | |
2084 | 1080 playlist_check_pos_current(playlist); |
0 | 1081 |
1082 if (restart_playing) | |
1083 bmp_playback_initiate(); | |
1084 else { | |
1085 mainwin_set_info_text(); | |
1086 playlistwin_update_list(); | |
1087 } | |
1088 } | |
1089 | |
1090 void | |
2084 | 1091 playlist_queue(Playlist *playlist) |
0 | 1092 { |
2084 | 1093 GList *list = playlist_get_selected(playlist); |
0 | 1094 GList *it = list; |
1095 | |
1096 PLAYLIST_LOCK(); | |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1097 |
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1098 if ((cfg.shuffle) && (playlist_position_before_jump == NULL)) |
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1099 { |
2084 | 1100 /* Shuffling and this is our first manual jump. */ |
1101 playlist_position_before_jump = playlist->position; | |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1102 } |
0 | 1103 |
1104 while (it) { | |
1105 GList *next = g_list_next(it); | |
1106 GList *tmp; | |
1107 | |
2084 | 1108 /* XXX: WTF? --nenolod */ |
1109 it->data = g_list_nth_data(playlist->entries, GPOINTER_TO_INT(it->data)); | |
1110 if ((tmp = g_list_find(playlist->queue, it->data))) { | |
1111 playlist->queue = g_list_remove_link(playlist->queue, tmp); | |
0 | 1112 g_list_free_1(tmp); |
1113 list = g_list_remove_link(list, it); | |
1114 g_list_free_1(it); | |
1115 } | |
1116 | |
1117 it = next; | |
1118 } | |
1119 | |
2084 | 1120 playlist->queue = g_list_concat(playlist->queue, list); |
0 | 1121 |
1122 PLAYLIST_UNLOCK(); | |
1123 | |
2085 | 1124 playlist_recalc_total_time(playlist); |
0 | 1125 playlistwin_update_list(); |
1126 } | |
1127 | |
1128 void | |
2084 | 1129 playlist_queue_position(Playlist *playlist, guint pos) |
0 | 1130 { |
1131 GList *tmp; | |
1132 PlaylistEntry *entry; | |
1133 | |
1134 PLAYLIST_LOCK(); | |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1135 |
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1136 if ((cfg.shuffle) && (playlist_position_before_jump == NULL)) |
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1137 { |
2084 | 1138 /* Shuffling and this is our first manual jump. */ |
1139 playlist_position_before_jump = playlist->position; | |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1140 } |
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1141 |
2084 | 1142 entry = g_list_nth_data(playlist->entries, pos); |
1143 if ((tmp = g_list_find(playlist->queue, entry))) { | |
1144 playlist->queue = g_list_remove_link(playlist->queue, tmp); | |
0 | 1145 g_list_free_1(tmp); |
1146 } | |
1147 else | |
2084 | 1148 playlist->queue = g_list_append(playlist->queue, entry); |
0 | 1149 PLAYLIST_UNLOCK(); |
1150 | |
2085 | 1151 playlist_recalc_total_time(playlist); |
0 | 1152 playlistwin_update_list(); |
1153 } | |
1154 | |
1155 gboolean | |
2084 | 1156 playlist_is_position_queued(Playlist *playlist, guint pos) |
0 | 1157 { |
1158 PlaylistEntry *entry; | |
1159 GList *tmp; | |
1160 | |
1161 PLAYLIST_LOCK(); | |
2084 | 1162 entry = g_list_nth_data(playlist->entries, pos); |
1163 tmp = g_list_find(playlist->queue, entry); | |
0 | 1164 PLAYLIST_UNLOCK(); |
1165 | |
1166 return tmp != NULL; | |
1167 } | |
1168 | |
984 | 1169 gint |
2084 | 1170 playlist_get_queue_position_number(Playlist *playlist, guint pos) |
984 | 1171 { |
1172 PlaylistEntry *entry; | |
1173 gint tmp; | |
1174 | |
1175 PLAYLIST_LOCK(); | |
2084 | 1176 entry = g_list_nth_data(playlist->entries, pos); |
1177 tmp = g_list_index(playlist->queue, entry); | |
984 | 1178 PLAYLIST_UNLOCK(); |
1179 | |
1180 return tmp; | |
1181 } | |
1182 | |
1183 gint | |
2084 | 1184 playlist_get_queue_qposition_number(Playlist *playlist, guint pos) |
984 | 1185 { |
1186 PlaylistEntry *entry; | |
1187 gint tmp; | |
1188 | |
1189 PLAYLIST_LOCK(); | |
2084 | 1190 entry = g_list_nth_data(playlist->queue, pos); |
1191 tmp = g_list_index(playlist->entries, entry); | |
984 | 1192 PLAYLIST_UNLOCK(); |
1193 | |
1194 return tmp; | |
1195 } | |
1196 | |
0 | 1197 void |
2084 | 1198 playlist_clear_queue(Playlist *playlist) |
0 | 1199 { |
1200 PLAYLIST_LOCK(); | |
2084 | 1201 g_list_free(playlist->queue); |
1202 playlist->queue = NULL; | |
0 | 1203 PLAYLIST_UNLOCK(); |
1204 | |
2085 | 1205 playlist_recalc_total_time(playlist); |
0 | 1206 playlistwin_update_list(); |
1207 } | |
1208 | |
1209 void | |
2084 | 1210 playlist_queue_remove(Playlist *playlist, guint pos) |
0 | 1211 { |
1212 void *entry; | |
1213 | |
1214 PLAYLIST_LOCK(); | |
2084 | 1215 entry = g_list_nth_data(playlist->entries, pos); |
1216 playlist->queue = g_list_remove(playlist->queue, entry); | |
0 | 1217 PLAYLIST_UNLOCK(); |
1218 | |
1219 playlistwin_update_list(); | |
1220 } | |
1221 | |
1222 gint | |
2084 | 1223 playlist_get_queue_position(Playlist *playlist, PlaylistEntry * entry) |
0 | 1224 { |
2084 | 1225 return g_list_index(playlist->queue, entry); |
0 | 1226 } |
1227 | |
1228 void | |
2084 | 1229 playlist_set_position(Playlist *playlist, guint pos) |
0 | 1230 { |
1231 GList *node; | |
1232 gboolean restart_playing = FALSE; | |
1233 | |
1234 PLAYLIST_LOCK(); | |
1235 if (!playlist) { | |
1236 PLAYLIST_UNLOCK(); | |
1237 return; | |
1238 } | |
1239 | |
2084 | 1240 node = g_list_nth(playlist->entries, pos); |
0 | 1241 if (!node) { |
1242 PLAYLIST_UNLOCK(); | |
1243 return; | |
1244 } | |
1245 | |
1246 if (bmp_playback_get_playing()) { | |
1247 /* We need to stop before changing playlist_position */ | |
1248 PLAYLIST_UNLOCK(); | |
923 | 1249 ip_data.stop = TRUE; |
0 | 1250 bmp_playback_stop(); |
923 | 1251 ip_data.stop = FALSE; |
0 | 1252 PLAYLIST_LOCK(); |
1253 restart_playing = TRUE; | |
1254 } | |
1255 | |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1256 if ((cfg.shuffle) && (playlist_position_before_jump == NULL)) |
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1257 { |
2084 | 1258 /* Shuffling and this is our first manual jump. */ |
1259 playlist_position_before_jump = playlist->position; | |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1260 } |
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1261 |
2084 | 1262 playlist->position = node->data; |
0 | 1263 PLAYLIST_UNLOCK(); |
2084 | 1264 playlist_check_pos_current(playlist); |
0 | 1265 |
1266 if (restart_playing) | |
1267 bmp_playback_initiate(); | |
1268 else { | |
1269 mainwin_set_info_text(); | |
1270 playlistwin_update_list(); | |
1271 } | |
1272 } | |
1273 | |
1274 void | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1275 playlist_eof_reached(Playlist *playlist) |
0 | 1276 { |
1277 GList *plist_pos_list; | |
1278 | |
904
2cb51ff37e8d
[svn] - stop the psuedo output plugin when using 'no playlist advance' or 'stop after current song'
nhjm449
parents:
898
diff
changeset
|
1279 if ((cfg.no_playlist_advance && !cfg.repeat) || cfg.stopaftersong) |
2cb51ff37e8d
[svn] - stop the psuedo output plugin when using 'no playlist advance' or 'stop after current song'
nhjm449
parents:
898
diff
changeset
|
1280 ip_data.stop = TRUE; |
0 | 1281 bmp_playback_stop(); |
904
2cb51ff37e8d
[svn] - stop the psuedo output plugin when using 'no playlist advance' or 'stop after current song'
nhjm449
parents:
898
diff
changeset
|
1282 if ((cfg.no_playlist_advance && !cfg.repeat) || cfg.stopaftersong) |
2cb51ff37e8d
[svn] - stop the psuedo output plugin when using 'no playlist advance' or 'stop after current song'
nhjm449
parents:
898
diff
changeset
|
1283 ip_data.stop = FALSE; |
0 | 1284 |
1285 PLAYLIST_LOCK(); | |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1286 |
2084 | 1287 if ((playlist_position_before_jump != NULL) && playlist->queue == NULL) |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1288 { |
2084 | 1289 playlist->position = playlist_position_before_jump; |
1290 playlist_position_before_jump = NULL; | |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1291 } |
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
1292 |
2084 | 1293 plist_pos_list = find_playlist_position_list(playlist); |
0 | 1294 |
1295 if (cfg.no_playlist_advance) { | |
1296 PLAYLIST_UNLOCK(); | |
1297 mainwin_clear_song_info(); | |
1298 if (cfg.repeat) | |
1299 bmp_playback_initiate(); | |
1300 return; | |
1301 } | |
1302 | |
898 | 1303 if (cfg.stopaftersong) { |
1304 PLAYLIST_UNLOCK(); | |
1305 mainwin_clear_song_info(); | |
1306 mainwin_set_stopaftersong(FALSE); | |
1307 return; | |
1308 } | |
1309 | |
2084 | 1310 if (playlist->queue != NULL) { |
1311 play_queued(playlist); | |
0 | 1312 } |
1313 else if (!g_list_next(plist_pos_list)) { | |
1314 if (cfg.shuffle) { | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1315 playlist->position = NULL; |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1316 playlist_generate_shuffle_list_nolock(playlist); |
0 | 1317 } |
1318 else | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1319 playlist->position = playlist->entries->data; |
0 | 1320 |
1321 if (!cfg.repeat) { | |
1322 PLAYLIST_UNLOCK(); | |
1323 mainwin_clear_song_info(); | |
1324 mainwin_set_info_text(); | |
1325 return; | |
1326 } | |
1327 } | |
1328 else | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1329 playlist->position = g_list_next(plist_pos_list)->data; |
0 | 1330 |
1331 PLAYLIST_UNLOCK(); | |
1332 | |
2084 | 1333 playlist_check_pos_current(playlist); |
0 | 1334 bmp_playback_initiate(); |
1335 mainwin_set_info_text(); | |
1336 playlistwin_update_list(); | |
1337 } | |
1338 | |
1339 gint | |
2084 | 1340 playlist_get_length(Playlist *playlist) |
0 | 1341 { |
1342 gint retval; | |
1343 | |
1344 PLAYLIST_LOCK(); | |
2084 | 1345 retval = playlist_get_length_nolock(playlist); |
0 | 1346 PLAYLIST_UNLOCK(); |
1347 | |
1348 return retval; | |
1349 } | |
1350 | |
1351 gint | |
2084 | 1352 playlist_queue_get_length(Playlist *playlist) |
0 | 1353 { |
1354 gint length; | |
1355 | |
1356 PLAYLIST_LOCK(); | |
2084 | 1357 length = g_list_length(playlist->queue); |
0 | 1358 PLAYLIST_UNLOCK(); |
1359 | |
1360 return length; | |
1361 } | |
1362 | |
1363 gint | |
2084 | 1364 playlist_get_length_nolock(Playlist *playlist) |
0 | 1365 { |
2084 | 1366 return g_list_length(playlist->entries); |
0 | 1367 } |
1368 | |
1369 gchar * | |
2084 | 1370 playlist_get_info_text(Playlist *playlist) |
0 | 1371 { |
1372 gchar *text, *title, *numbers, *length; | |
1373 | |
2084 | 1374 g_return_val_if_fail(playlist != NULL, NULL); |
1375 | |
0 | 1376 PLAYLIST_LOCK(); |
2084 | 1377 if (!playlist->position) { |
0 | 1378 PLAYLIST_UNLOCK(); |
1379 return NULL; | |
1380 } | |
1381 | |
1382 /* FIXME: there should not be a need to do additional conversion, | |
1383 * if playlist is properly maintained */ | |
2084 | 1384 if (playlist->position->title) { |
1385 title = str_to_utf8(playlist->position->title); | |
0 | 1386 } |
1387 else { | |
2084 | 1388 gchar *basename = g_path_get_basename(playlist->position->filename); |
0 | 1389 title = filename_to_utf8(basename); |
1390 g_free(basename); | |
1391 } | |
1392 | |
1393 /* | |
1394 * If the user don't want numbers in the playlist, don't | |
1395 * display them in other parts of XMMS | |
1396 */ | |
1397 | |
1398 if (cfg.show_numbers_in_pl) | |
2084 | 1399 numbers = g_strdup_printf("%d. ", playlist_get_position_nolock(playlist) + 1); |
0 | 1400 else |
1401 numbers = g_strdup(""); | |
1402 | |
2096 | 1403 if (playlist->position->length != -1) |
0 | 1404 length = g_strdup_printf(" (%d:%-2.2d)", |
2084 | 1405 playlist->position->length / 60000, |
1406 (playlist->position->length / 1000) % 60); | |
0 | 1407 else |
1408 length = g_strdup(""); | |
1409 | |
1410 PLAYLIST_UNLOCK(); | |
1411 | |
1412 text = convert_title_text(g_strconcat(numbers, title, length, NULL)); | |
1413 | |
1414 g_free(numbers); | |
1415 g_free(title); | |
1416 g_free(length); | |
1417 | |
1418 return text; | |
1419 } | |
1420 | |
1421 gint | |
2084 | 1422 playlist_get_current_length(Playlist * playlist) |
0 | 1423 { |
1424 gint len = 0; | |
1425 | |
1426 PLAYLIST_LOCK(); | |
2084 | 1427 if (playlist && playlist->position) |
1428 len = playlist->position->length; | |
0 | 1429 PLAYLIST_UNLOCK(); |
1430 | |
1431 return len; | |
1432 } | |
1433 | |
1434 gboolean | |
2083 | 1435 playlist_save(Playlist * playlist, const gchar * filename) |
0 | 1436 { |
1553 | 1437 PlaylistContainer *plc = NULL; |
1438 gchar *ext; | |
0 | 1439 |
2083 | 1440 g_return_val_if_fail(playlist != NULL, FALSE); |
0 | 1441 g_return_val_if_fail(filename != NULL, FALSE); |
1442 | |
1553 | 1443 ext = strrchr(filename, '.') + 1; |
1444 | |
2083 | 1445 playlist_set_current_name(playlist, filename); |
0 | 1446 |
1553 | 1447 if ((plc = playlist_container_find(ext)) == NULL) |
0 | 1448 return FALSE; |
1449 | |
1555 | 1450 if (plc->plc_write == NULL) |
1451 return FALSE; | |
1452 | |
1553 | 1453 plc->plc_write(filename, 0); |
1454 | |
1455 return TRUE; | |
0 | 1456 } |
1457 | |
1458 gboolean | |
2083 | 1459 playlist_load(Playlist * playlist, const gchar * filename) |
0 | 1460 { |
397
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1461 gboolean ret = FALSE; |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1462 |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1463 loading_playlist = TRUE; |
2084 | 1464 ret = playlist_load_ins(playlist, filename, -1); |
397
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1465 loading_playlist = FALSE; |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1466 |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1467 return ret; |
0 | 1468 } |
1469 | |
1554 | 1470 void |
2084 | 1471 playlist_load_ins_file(Playlist *playlist, |
1472 const gchar * filename_p, | |
0 | 1473 const gchar * playlist_name, gint pos, |
1474 const gchar * title, gint len) | |
1475 { | |
1476 gchar *filename; | |
1477 gchar *tmp, *path; | |
355
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
1478 InputPlugin *dec; /* for decoder cache */ |
0 | 1479 |
1480 g_return_if_fail(filename_p != NULL); | |
1481 g_return_if_fail(playlist_name != NULL); | |
1482 | |
633
bf9bc9a514ba
[svn] Use g_strchug instead of g_strstrip during playlist load. Trailing whitespace can be a valid occurance. Closes bug #282.
chainsaw
parents:
538
diff
changeset
|
1483 filename = g_strchug(g_strdup(filename_p)); |
0 | 1484 |
2019
d3a62e1075e2
[svn] Allow \ to / conversion to be switched on & off, by external contributor Chris Kehler <cbkehler@sympatico.ca>.
chainsaw
parents:
2010
diff
changeset
|
1485 if(cfg.convert_slash) |
944
03d141f44b4d
[svn] Convert \ path separators to /. Support was already present, but was not enabled before. Closes bug #461.
chainsaw
parents:
923
diff
changeset
|
1486 while ((tmp = strchr(filename, '\\')) != NULL) |
03d141f44b4d
[svn] Convert \ path separators to /. Support was already present, but was not enabled before. Closes bug #461.
chainsaw
parents:
923
diff
changeset
|
1487 *tmp = '/'; |
0 | 1488 |
1489 if (filename[0] != '/' && !strstr(filename, "://")) { | |
1490 path = g_strdup(playlist_name); | |
1491 if ((tmp = strrchr(path, '/'))) | |
1492 *tmp = '\0'; | |
1493 else { | |
1163
ff71f891265b
[svn] - Allow to do format detection on demand; instead of immediately on add
nenolod
parents:
1026
diff
changeset
|
1494 if (loading_playlist != TRUE || cfg.playlist_detect == FALSE) |
397
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1495 dec = input_check_file(filename, FALSE); |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1496 else |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1497 dec = NULL; |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1498 |
2084 | 1499 __playlist_ins_with_info(playlist, filename, pos, title, len, dec); |
0 | 1500 return; |
1501 } | |
1502 tmp = g_build_filename(path, filename, NULL); | |
397
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1503 |
1165 | 1504 if (loading_playlist != TRUE && cfg.playlist_detect != TRUE) |
397
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1505 dec = input_check_file(tmp, FALSE); |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1506 else |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1507 dec = NULL; |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1508 |
2084 | 1509 __playlist_ins_with_info(playlist, tmp, pos, title, len, dec); |
0 | 1510 g_free(tmp); |
1511 g_free(path); | |
1512 } | |
1513 else | |
355
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
1514 { |
1165 | 1515 if (loading_playlist != TRUE && cfg.playlist_detect != TRUE) |
397
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1516 dec = input_check_file(filename, FALSE); |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1517 else |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1518 dec = NULL; |
4fa1244ad483
[svn] Do not generate a cache when loading a playlist.
nenolod
parents:
383
diff
changeset
|
1519 |
2084 | 1520 __playlist_ins_with_info(playlist, filename, pos, title, len, dec); |
355
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
1521 } |
0 | 1522 |
1523 g_free(filename); | |
1524 } | |
1525 | |
1584 | 1526 void |
2084 | 1527 playlist_load_ins_file_tuple(Playlist * playlist, |
1528 const gchar * filename_p, | |
1584 | 1529 const gchar * playlist_name, |
1530 gint pos, | |
1531 TitleInput *tuple) | |
1532 { | |
1533 gchar *filename; | |
1534 gchar *tmp, *path; | |
1535 InputPlugin *dec; /* for decoder cache */ | |
1536 | |
1537 g_return_if_fail(filename_p != NULL); | |
1538 g_return_if_fail(playlist_name != NULL); | |
1539 | |
1540 filename = g_strchug(g_strdup(filename_p)); | |
1541 | |
1542 while ((tmp = strchr(filename, '\\')) != NULL) | |
1543 *tmp = '/'; | |
1544 | |
1545 if (filename[0] != '/' && !strstr(filename, "://")) { | |
1546 path = g_strdup(playlist_name); | |
1547 if ((tmp = strrchr(path, '/'))) | |
1548 *tmp = '\0'; | |
1549 else { | |
1550 if (loading_playlist != TRUE || cfg.playlist_detect == FALSE) | |
1551 dec = input_check_file(filename, FALSE); | |
1552 else | |
1553 dec = NULL; | |
1554 | |
2084 | 1555 __playlist_ins_with_info_tuple(playlist, filename, pos, tuple, dec); |
1584 | 1556 return; |
1557 } | |
1558 tmp = g_build_filename(path, filename, NULL); | |
1559 | |
1560 if (loading_playlist != TRUE && cfg.playlist_detect != TRUE) | |
1561 dec = input_check_file(tmp, FALSE); | |
1562 else | |
1563 dec = NULL; | |
1564 | |
2084 | 1565 __playlist_ins_with_info_tuple(playlist, tmp, pos, tuple, dec); |
1584 | 1566 g_free(tmp); |
1567 g_free(path); | |
1568 } | |
1569 else | |
1570 { | |
1571 if (loading_playlist != TRUE && cfg.playlist_detect != TRUE) | |
1572 dec = input_check_file(filename, FALSE); | |
1573 else | |
1574 dec = NULL; | |
1575 | |
2084 | 1576 __playlist_ins_with_info_tuple(playlist, filename, pos, tuple, dec); |
1584 | 1577 } |
1578 | |
1579 g_free(filename); | |
1580 } | |
1581 | |
0 | 1582 static guint |
2083 | 1583 playlist_load_ins(Playlist * playlist, const gchar * filename, gint pos) |
0 | 1584 { |
1554 | 1585 PlaylistContainer *plc; |
1586 gchar *ext; | |
0 | 1587 |
2083 | 1588 g_return_val_if_fail(playlist != NULL, 0); |
0 | 1589 g_return_val_if_fail(filename != NULL, 0); |
1590 | |
1554 | 1591 ext = strrchr(filename, '.') + 1; |
1592 plc = playlist_container_find(ext); | |
1593 | |
1594 g_return_val_if_fail(plc != NULL, 0); | |
1595 g_return_val_if_fail(plc->plc_read != NULL, 0); | |
1596 | |
1560
5840d797ea02
[svn] - hmm, calling plc->load() might be a good idea!
nenolod
parents:
1559
diff
changeset
|
1597 plc->plc_read(filename, pos); |
5840d797ea02
[svn] - hmm, calling plc->load() might be a good idea!
nenolod
parents:
1559
diff
changeset
|
1598 |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1599 playlist_generate_shuffle_list(playlist); |
1554 | 1600 playlistwin_update_list(); |
1601 | |
1602 return 1; | |
0 | 1603 } |
1604 | |
1605 GList * | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1606 get_playlist_nth(Playlist *playlist, guint nth) |
0 | 1607 { |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1608 REQUIRE_STATIC_LOCK(playlists); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1609 return g_list_nth(playlist->entries, nth); |
0 | 1610 } |
1611 | |
1612 | |
1613 GList * | |
1614 playlist_get(void) | |
1615 { | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1616 REQUIRE_STATIC_LOCK(playlists); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1617 return playlist_get_active()->entries; |
0 | 1618 } |
1619 | |
1620 gint | |
2084 | 1621 playlist_get_position_nolock(Playlist *playlist) |
0 | 1622 { |
2096 | 1623 if (playlist && playlist->position) |
2084 | 1624 return g_list_index(playlist->entries, playlist->position); |
0 | 1625 return 0; |
1626 } | |
1627 | |
1628 gint | |
2084 | 1629 playlist_get_position(Playlist *playlist) |
0 | 1630 { |
1631 gint pos; | |
1632 | |
1633 PLAYLIST_LOCK(); | |
2084 | 1634 pos = playlist_get_position_nolock(playlist); |
0 | 1635 PLAYLIST_UNLOCK(); |
1636 | |
1637 return pos; | |
1638 } | |
1639 | |
1640 gchar * | |
2084 | 1641 playlist_get_filename(Playlist *playlist, guint pos) |
0 | 1642 { |
1643 gchar *filename; | |
1644 PlaylistEntry *entry; | |
1645 GList *node; | |
1646 | |
1647 PLAYLIST_LOCK(); | |
1648 if (!playlist) { | |
1649 PLAYLIST_UNLOCK(); | |
1650 return NULL; | |
1651 } | |
2084 | 1652 node = g_list_nth(playlist->entries, pos); |
0 | 1653 if (!node) { |
1654 PLAYLIST_UNLOCK(); | |
1655 return NULL; | |
1656 } | |
1657 entry = node->data; | |
1658 | |
1659 filename = g_strdup(entry->filename); | |
1660 PLAYLIST_UNLOCK(); | |
1661 | |
1662 return filename; | |
1663 } | |
1664 | |
1665 gchar * | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1666 playlist_get_songtitle(Playlist *playlist, guint pos) |
0 | 1667 { |
1668 gchar *title = NULL; | |
1669 PlaylistEntry *entry; | |
1670 GList *node; | |
1671 | |
1672 PLAYLIST_LOCK(); | |
1673 | |
1674 if (!playlist) { | |
1675 PLAYLIST_UNLOCK(); | |
1676 return NULL; | |
1677 } | |
1678 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1679 if (!(node = g_list_nth(playlist->entries, pos))) { |
0 | 1680 PLAYLIST_UNLOCK(); |
1681 return NULL; | |
1682 } | |
1683 | |
1684 entry = node->data; | |
1685 | |
1686 /* FIXME: simplify this logic */ | |
1841
7d0cd3fab6a2
[svn] - mtime=-1 has been introduced to represent "uninitialized".
yaz
parents:
1834
diff
changeset
|
1687 if ((entry->title == NULL && entry->length == -1) || |
7d0cd3fab6a2
[svn] - mtime=-1 has been introduced to represent "uninitialized".
yaz
parents:
1834
diff
changeset
|
1688 (entry->tuple && entry->tuple->mtime != 0 && (entry->tuple->mtime == -1 || entry->tuple->mtime != playlist_get_mtime(entry->filename)))) |
7d0cd3fab6a2
[svn] - mtime=-1 has been introduced to represent "uninitialized".
yaz
parents:
1834
diff
changeset
|
1689 { |
0 | 1690 if (playlist_entry_get_info(entry)) |
1691 title = entry->title; | |
1692 } | |
1693 else { | |
1694 title = entry->title; | |
1695 } | |
1696 | |
1697 PLAYLIST_UNLOCK(); | |
1698 | |
1699 if (!title) { | |
1700 title = g_path_get_basename(entry->filename); | |
1701 return str_replace(title, filename_to_utf8(title)); | |
1702 } | |
1703 | |
1704 return str_to_utf8(title); | |
1705 } | |
1706 | |
1235 | 1707 TitleInput * |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1708 playlist_get_tuple(Playlist *playlist, guint pos) |
1235 | 1709 { |
1710 PlaylistEntry *entry; | |
1711 TitleInput *tuple = NULL; | |
1712 GList *node; | |
1713 | |
1714 PLAYLIST_LOCK(); | |
1715 | |
1716 if (!playlist) { | |
1717 PLAYLIST_UNLOCK(); | |
1718 return NULL; | |
1719 } | |
1720 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1721 if (!(node = g_list_nth(playlist->entries, pos))) { |
1235 | 1722 PLAYLIST_UNLOCK(); |
1723 return NULL; | |
1724 } | |
1725 | |
1726 entry = (PlaylistEntry *) node->data; | |
1727 | |
1728 tuple = entry->tuple; | |
1729 | |
1588
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1730 // if no tuple or tuple with old mtime, get new one. |
1841
7d0cd3fab6a2
[svn] - mtime=-1 has been introduced to represent "uninitialized".
yaz
parents:
1834
diff
changeset
|
1731 if (tuple == NULL || |
7d0cd3fab6a2
[svn] - mtime=-1 has been introduced to represent "uninitialized".
yaz
parents:
1834
diff
changeset
|
1732 (entry->tuple && entry->tuple->mtime != 0 && (entry->tuple->mtime == -1 || entry->tuple->mtime != playlist_get_mtime(entry->filename)))) |
7d0cd3fab6a2
[svn] - mtime=-1 has been introduced to represent "uninitialized".
yaz
parents:
1834
diff
changeset
|
1733 { |
1237
17630223d25b
[svn] - if a PlaylistEntry does not have a cached tuple, generate it on demand.
nenolod
parents:
1235
diff
changeset
|
1734 playlist_entry_get_info(entry); |
17630223d25b
[svn] - if a PlaylistEntry does not have a cached tuple, generate it on demand.
nenolod
parents:
1235
diff
changeset
|
1735 tuple = entry->tuple; |
17630223d25b
[svn] - if a PlaylistEntry does not have a cached tuple, generate it on demand.
nenolod
parents:
1235
diff
changeset
|
1736 } |
17630223d25b
[svn] - if a PlaylistEntry does not have a cached tuple, generate it on demand.
nenolod
parents:
1235
diff
changeset
|
1737 |
1235 | 1738 PLAYLIST_UNLOCK(); |
1739 | |
1740 return tuple; | |
1741 } | |
1742 | |
0 | 1743 gint |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1744 playlist_get_songtime(Playlist *playlist, guint pos) |
0 | 1745 { |
1746 gint song_time = -1; | |
1747 PlaylistEntry *entry; | |
1748 GList *node; | |
1749 | |
1750 PLAYLIST_LOCK(); | |
1751 | |
1752 if (!playlist) { | |
1753 PLAYLIST_UNLOCK(); | |
1754 return -1; | |
1755 } | |
1756 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1757 if (!(node = g_list_nth(playlist->entries, pos))) { |
0 | 1758 PLAYLIST_UNLOCK(); |
1759 return -1; | |
1760 } | |
1761 | |
1762 entry = node->data; | |
1841
7d0cd3fab6a2
[svn] - mtime=-1 has been introduced to represent "uninitialized".
yaz
parents:
1834
diff
changeset
|
1763 if (entry->tuple == NULL || |
7d0cd3fab6a2
[svn] - mtime=-1 has been introduced to represent "uninitialized".
yaz
parents:
1834
diff
changeset
|
1764 (entry->tuple->mtime != 0 && (entry->tuple->mtime == -1 || entry->tuple->mtime != playlist_get_mtime(entry->filename)))) { |
1588
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1765 |
0 | 1766 if (playlist_entry_get_info(entry)) |
1767 song_time = entry->length; | |
1768 | |
1769 PLAYLIST_UNLOCK(); | |
1770 } | |
1771 else { | |
1772 song_time = entry->length; | |
1773 PLAYLIST_UNLOCK(); | |
1774 } | |
1775 | |
1776 return song_time; | |
1777 } | |
1778 | |
1779 static gint | |
1415 | 1780 playlist_compare_track(PlaylistEntry * a, |
1781 PlaylistEntry * b) | |
1782 { | |
1783 g_return_val_if_fail(a != NULL, 0); | |
1784 g_return_val_if_fail(b != NULL, 0); | |
1785 | |
1786 g_return_val_if_fail(a->tuple != NULL, 0); | |
1787 g_return_val_if_fail(b->tuple != NULL, 0); | |
1788 | |
1789 return (a->tuple->track_number - b->tuple->track_number); | |
1790 } | |
1791 | |
1792 static gint | |
1430
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1793 playlist_compare_playlist(PlaylistEntry * a, |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1794 PlaylistEntry * b) |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1795 { |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1796 const gchar *a_title = NULL, *b_title = NULL; |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1797 |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1798 g_return_val_if_fail(a != NULL, 0); |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1799 g_return_val_if_fail(b != NULL, 0); |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1800 |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1801 if (a->title != NULL) |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1802 a_title = a->title; |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1803 else { |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1804 if (strrchr(a->filename, '/')) |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1805 a_title = strrchr(a->filename, '/') + 1; |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1806 else |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1807 a_title = a->filename; |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1808 } |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1809 |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1810 if (b->title != NULL) |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1811 b_title = b->title; |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1812 else { |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1813 if (strrchr(a->filename, '/')) |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1814 b_title = strrchr(b->filename, '/') + 1; |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1815 else |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1816 b_title = b->filename; |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1817 } |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1818 |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1819 return strcasecmp(a_title, b_title); |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1820 } |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1821 |
740c08db08d9
[svn] via Christian Birchinger <joker -at- netswarm.net>:
nenolod
parents:
1415
diff
changeset
|
1822 static gint |
1251 | 1823 playlist_compare_title(PlaylistEntry * a, |
1824 PlaylistEntry * b) | |
0 | 1825 { |
1250 | 1826 const gchar *a_title = NULL, *b_title = NULL; |
0 | 1827 |
1828 g_return_val_if_fail(a != NULL, 0); | |
1829 g_return_val_if_fail(b != NULL, 0); | |
1830 | |
1250 | 1831 if (a->tuple != NULL && a->tuple->track_name != NULL) |
1832 a_title = a->tuple->track_name; | |
1833 if (b->tuple != NULL && b->tuple->track_name != NULL) | |
1834 b_title = b->tuple->track_name; | |
1835 | |
1251 | 1836 if (a_title != NULL && b_title != NULL) |
1250 | 1837 return strcasecmp(a_title, b_title); |
1838 | |
1839 if (a->title != NULL) | |
0 | 1840 a_title = a->title; |
1841 else { | |
1842 if (strrchr(a->filename, '/')) | |
1843 a_title = strrchr(a->filename, '/') + 1; | |
1844 else | |
1845 a_title = a->filename; | |
1846 } | |
1847 | |
1250 | 1848 if (b->title != NULL) |
0 | 1849 b_title = b->title; |
1850 else { | |
1851 if (strrchr(a->filename, '/')) | |
1852 b_title = strrchr(b->filename, '/') + 1; | |
1853 else | |
1854 b_title = b->filename; | |
1855 } | |
1856 | |
1857 return strcasecmp(a_title, b_title); | |
1858 } | |
1859 | |
1860 static gint | |
1251 | 1861 playlist_compare_artist(PlaylistEntry * a, |
1862 PlaylistEntry * b) | |
1863 { | |
1864 const gchar *a_artist = NULL, *b_artist = NULL; | |
1865 | |
1866 g_return_val_if_fail(a != NULL, 0); | |
1867 g_return_val_if_fail(b != NULL, 0); | |
1868 | |
1869 if (a->tuple != NULL) | |
1870 playlist_entry_get_info(a); | |
1871 | |
1872 if (b->tuple != NULL) | |
1873 playlist_entry_get_info(b); | |
1874 | |
1253
665dfbf5e9a1
[svn] - playlist_compare_artist(): more sanity checking.
nenolod
parents:
1251
diff
changeset
|
1875 if (a->tuple != NULL && a->tuple->performer != NULL) |
1251 | 1876 a_artist = a->tuple->performer; |
1253
665dfbf5e9a1
[svn] - playlist_compare_artist(): more sanity checking.
nenolod
parents:
1251
diff
changeset
|
1877 if (b->tuple != NULL && b->tuple->performer != NULL) |
1251 | 1878 b_artist = b->tuple->performer; |
1879 | |
1880 if (a_artist != NULL && b_artist != NULL) | |
1881 return strcasecmp(a_artist, b_artist); | |
1882 | |
1253
665dfbf5e9a1
[svn] - playlist_compare_artist(): more sanity checking.
nenolod
parents:
1251
diff
changeset
|
1883 return 0; |
1251 | 1884 } |
1885 | |
1886 static gint | |
1887 playlist_compare_filename(PlaylistEntry * a, | |
1888 PlaylistEntry * b) | |
0 | 1889 { |
1890 gchar *a_filename, *b_filename; | |
1891 | |
1892 g_return_val_if_fail(a != NULL, 0); | |
1893 g_return_val_if_fail(b != NULL, 0); | |
1894 | |
1895 if (strrchr(a->filename, '/')) | |
1896 a_filename = strrchr(a->filename, '/') + 1; | |
1897 else | |
1898 a_filename = a->filename; | |
1899 | |
1900 if (strrchr(b->filename, '/')) | |
1901 b_filename = strrchr(b->filename, '/') + 1; | |
1902 else | |
1903 b_filename = b->filename; | |
1904 | |
1905 | |
1906 return strcasecmp(a_filename, b_filename); | |
1907 } | |
1908 | |
1909 static gint | |
1910 path_compare(const gchar * a, const gchar * b) | |
1911 { | |
1912 gchar *posa, *posb; | |
1913 gint len, ret; | |
1914 | |
1915 posa = strrchr(a, '/'); | |
1916 posb = strrchr(b, '/'); | |
1917 | |
1918 /* | |
1919 * Sort directories before files | |
1920 */ | |
1921 if (posa && posb && (posa - a != posb - b)) { | |
1922 if (posa - a > posb - b) { | |
1923 len = posb - b; | |
1924 ret = -1; | |
1925 } | |
1926 else { | |
1927 len = posa - a; | |
1928 ret = 1; | |
1929 } | |
1930 if (!strncasecmp(a, b, len)) | |
1931 return ret; | |
1932 } | |
1933 return strcasecmp(a, b); | |
1934 } | |
1935 | |
1936 static gint | |
1251 | 1937 playlist_compare_path(PlaylistEntry * a, |
1938 PlaylistEntry * b) | |
0 | 1939 { |
1940 return path_compare(a->filename, b->filename); | |
1941 } | |
1942 | |
1588
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1943 |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1944 static time_t |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1945 playlist_get_mtime(const gchar *filename) |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1946 { |
1706 | 1947 struct stat buf; |
1588
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1948 gint rv; |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1949 |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1950 rv = stat(filename, &buf); |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1951 |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1952 if (rv == 0) { |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1953 return buf.st_mtime; |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1954 } else { |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1955 return 0; //error |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1956 } |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1957 } |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1958 |
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
1959 |
0 | 1960 static gint |
1251 | 1961 playlist_compare_date(PlaylistEntry * a, |
1962 PlaylistEntry * b) | |
0 | 1963 { |
1964 struct stat buf; | |
1965 time_t modtime; | |
1966 | |
1967 gint rv; | |
1968 | |
1969 | |
1970 rv = stat(a->filename, &buf); | |
1971 | |
1972 if (rv == 0) { | |
1973 modtime = buf.st_mtime; | |
1974 rv = stat(b->filename, &buf); | |
1975 | |
1976 if (stat(b->filename, &buf) == 0) { | |
1977 if (buf.st_mtime == modtime) | |
1978 return 0; | |
1979 else | |
1980 return (buf.st_mtime - modtime) > 0 ? -1 : 1; | |
1981 } | |
1982 else | |
1983 return -1; | |
1984 } | |
1985 else if (!lstat(b->filename, &buf)) | |
1986 return 1; | |
1987 else | |
1988 return playlist_compare_filename(a, b); | |
1989 } | |
1990 | |
1991 | |
1992 void | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1993 playlist_sort(Playlist *playlist, PlaylistSortType type) |
0 | 1994 { |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1995 playlist_remove_dead_files(playlist); |
0 | 1996 PLAYLIST_LOCK(); |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1997 playlist->entries = |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
1998 g_list_sort(playlist->entries, |
0 | 1999 (GCompareFunc) playlist_compare_func_table[type]); |
2000 PLAYLIST_UNLOCK(); | |
2001 } | |
2002 | |
2003 static GList * | |
2004 playlist_sort_selected_generic(GList * list, GCompareFunc cmpfunc) | |
2005 { | |
2006 GList *list1, *list2; | |
2007 GList *tmp_list = NULL; | |
2008 GList *index_list = NULL; | |
2009 | |
2010 /* | |
2011 * We take all the selected entries out of the playlist, | |
2012 * sorts them, and then put them back in again. | |
2013 */ | |
2014 | |
2015 list1 = g_list_last(list); | |
2016 | |
2017 while (list1) { | |
2018 list2 = g_list_previous(list1); | |
2019 if (PLAYLIST_ENTRY(list1->data)->selected) { | |
2020 gpointer idx; | |
2021 idx = GINT_TO_POINTER(g_list_position(list, list1)); | |
2022 index_list = g_list_prepend(index_list, idx); | |
2023 list = g_list_remove_link(list, list1); | |
2024 tmp_list = g_list_concat(list1, tmp_list); | |
2025 } | |
2026 list1 = list2; | |
2027 } | |
2028 | |
2029 tmp_list = g_list_sort(tmp_list, cmpfunc); | |
2030 list1 = tmp_list; | |
2031 list2 = index_list; | |
2032 | |
2033 while (list2) { | |
2034 if (!list1) { | |
2035 g_critical(G_STRLOC ": Error during list sorting. " | |
2036 "Possibly dropped some playlist-entries."); | |
2037 break; | |
2038 } | |
2039 | |
2040 list = g_list_insert(list, list1->data, GPOINTER_TO_INT(list2->data)); | |
2041 | |
2042 list2 = g_list_next(list2); | |
2043 list1 = g_list_next(list1); | |
2044 } | |
2045 | |
2046 g_list_free(index_list); | |
2047 g_list_free(tmp_list); | |
2048 | |
2049 return list; | |
2050 } | |
2051 | |
2052 void | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2053 playlist_sort_selected(Playlist *playlist, PlaylistSortType type) |
0 | 2054 { |
2055 PLAYLIST_LOCK(); | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2056 playlist->entries = playlist_sort_selected_generic(playlist->entries, (GCompareFunc) |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2057 playlist_compare_func_table |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2058 [type]); |
0 | 2059 PLAYLIST_UNLOCK(); |
2060 } | |
2061 | |
2062 void | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2063 playlist_reverse(Playlist *playlist) |
0 | 2064 { |
2065 PLAYLIST_LOCK(); | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2066 playlist->entries = g_list_reverse(playlist->entries); |
0 | 2067 PLAYLIST_UNLOCK(); |
2068 } | |
2069 | |
2070 static GList * | |
2071 playlist_shuffle_list(GList * list) | |
2072 { | |
2073 /* | |
2074 * Note that this doesn't make a copy of the original list. | |
2075 * The pointer to the original list is not valid after this | |
2076 * fuction is run. | |
2077 */ | |
2078 gint len = g_list_length(list); | |
2079 gint i, j; | |
2080 GList *node, **ptrs; | |
2081 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2082 REQUIRE_STATIC_LOCK(playlists); |
0 | 2083 |
2084 if (!len) | |
2085 return NULL; | |
2086 | |
2087 ptrs = g_new(GList *, len); | |
2088 | |
2089 for (node = list, i = 0; i < len; node = g_list_next(node), i++) | |
2090 ptrs[i] = node; | |
2091 | |
2092 j = g_random_int_range(0, len); | |
2093 list = ptrs[j]; | |
2094 ptrs[j]->next = NULL; | |
2095 ptrs[j] = ptrs[0]; | |
2096 | |
2097 for (i = 1; i < len; i++) { | |
2098 j = g_random_int_range(0, len - i); | |
2099 list->prev = ptrs[i + j]; | |
2100 ptrs[i + j]->next = list; | |
2101 list = ptrs[i + j]; | |
2102 ptrs[i + j] = ptrs[i]; | |
2103 } | |
2104 list->prev = NULL; | |
2105 | |
2106 g_free(ptrs); | |
2107 | |
2108 return list; | |
2109 } | |
2110 | |
2111 void | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2112 playlist_random(Playlist *playlist) |
0 | 2113 { |
2114 PLAYLIST_LOCK(); | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2115 playlist->entries = playlist_shuffle_list(playlist->entries); |
0 | 2116 PLAYLIST_UNLOCK(); |
2117 } | |
2118 | |
2119 GList * | |
2085 | 2120 playlist_get_selected(Playlist *playlist) |
0 | 2121 { |
2122 GList *node, *list = NULL; | |
2123 gint i = 0; | |
2124 | |
2125 PLAYLIST_LOCK(); | |
2085 | 2126 for (node = playlist->entries; node; node = g_list_next(node), i++) { |
0 | 2127 PlaylistEntry *entry = node->data; |
2128 if (entry->selected) | |
2129 list = g_list_prepend(list, GINT_TO_POINTER(i)); | |
2130 } | |
2131 PLAYLIST_UNLOCK(); | |
2132 return g_list_reverse(list); | |
2133 } | |
2134 | |
2135 void | |
2085 | 2136 playlist_clear_selected(Playlist *playlist) |
0 | 2137 { |
2138 GList *node = NULL; | |
2139 gint i = 0; | |
2140 | |
2141 PLAYLIST_LOCK(); | |
2085 | 2142 for (node = playlist->entries; node; node = g_list_next(node), i++) { |
0 | 2143 PLAYLIST_ENTRY(node->data)->selected = FALSE; |
2144 } | |
2145 PLAYLIST_UNLOCK(); | |
2085 | 2146 playlist_recalc_total_time(playlist); |
0 | 2147 } |
2148 | |
2149 gint | |
2085 | 2150 playlist_get_num_selected(Playlist *playlist) |
0 | 2151 { |
2152 GList *node; | |
2153 gint num = 0; | |
2154 | |
2155 PLAYLIST_LOCK(); | |
2085 | 2156 for (node = playlist->entries; node; node = g_list_next(node)) { |
0 | 2157 PlaylistEntry *entry = node->data; |
2158 if (entry->selected) | |
2159 num++; | |
2160 } | |
2161 PLAYLIST_UNLOCK(); | |
2162 return num; | |
2163 } | |
2164 | |
2165 | |
2166 static void | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2167 playlist_generate_shuffle_list(Playlist *playlist) |
0 | 2168 { |
2169 PLAYLIST_LOCK(); | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2170 playlist_generate_shuffle_list_nolock(playlist); |
0 | 2171 PLAYLIST_UNLOCK(); |
2172 } | |
2173 | |
2174 static void | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2175 playlist_generate_shuffle_list_nolock(Playlist *playlist) |
0 | 2176 { |
2177 GList *node; | |
2178 gint numsongs; | |
2179 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2180 REQUIRE_STATIC_LOCK(playlists); |
0 | 2181 |
2182 if (!cfg.shuffle || !playlist) | |
2183 return; | |
2184 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2185 if (playlist->shuffle) { |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2186 g_list_free(playlist->shuffle); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2187 playlist->shuffle = NULL; |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2188 } |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2189 |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2190 playlist->shuffle = playlist_shuffle_list(g_list_copy(playlist->entries)); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2191 numsongs = g_list_length(playlist->shuffle); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2192 |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2193 if (playlist->position) { |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2194 gint i = g_list_index(playlist->shuffle, playlist->position); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2195 node = g_list_nth(playlist->shuffle, i); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2196 playlist->shuffle = g_list_remove_link(playlist->shuffle, node); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2197 playlist->shuffle = g_list_prepend(playlist->shuffle, node->data); |
0 | 2198 } |
2199 } | |
2200 | |
2201 void | |
2085 | 2202 playlist_fileinfo(Playlist *playlist, guint pos) |
0 | 2203 { |
2204 gchar *path = NULL; | |
2205 GList *node; | |
1269 | 2206 PlaylistEntry *entry = NULL; |
2207 TitleInput *tuple = NULL; | |
1818
e3e31a084b09
[svn] - try not to reject tuples that have an mtime of 0. (special tuples referring to URIs)
nenolod
parents:
1817
diff
changeset
|
2208 gint mtime; |
0 | 2209 |
2210 PLAYLIST_LOCK(); | |
1269 | 2211 |
2085 | 2212 if ((node = g_list_nth(playlist->entries, pos))) |
1269 | 2213 { |
2214 entry = node->data; | |
2215 tuple = entry->tuple; | |
1516
3483fb26b9fb
[svn] - when audacious is started and track detail on current song are requested, try to check if a decoder exists before falling back to the tuple display dialog
giacomo
parents:
1459
diff
changeset
|
2216 path = g_strdup(entry->filename); |
0 | 2217 } |
1269 | 2218 |
0 | 2219 PLAYLIST_UNLOCK(); |
1277
8c8d4841efae
[svn] - if entry->tuple == NULL, then probe the file for a decoder and build the appropriate tuple for that entry
nenolod
parents:
1270
diff
changeset
|
2220 |
8c8d4841efae
[svn] - if entry->tuple == NULL, then probe the file for a decoder and build the appropriate tuple for that entry
nenolod
parents:
1270
diff
changeset
|
2221 /* No tuple? Try to set this entry up properly. --nenolod */ |
1841
7d0cd3fab6a2
[svn] - mtime=-1 has been introduced to represent "uninitialized".
yaz
parents:
1834
diff
changeset
|
2222 if (entry->tuple == NULL || entry->tuple->mtime == -1 || |
7d0cd3fab6a2
[svn] - mtime=-1 has been introduced to represent "uninitialized".
yaz
parents:
1834
diff
changeset
|
2223 entry->tuple->mtime == 0 || entry->tuple->mtime != playlist_get_mtime(entry->filename)) |
1277
8c8d4841efae
[svn] - if entry->tuple == NULL, then probe the file for a decoder and build the appropriate tuple for that entry
nenolod
parents:
1270
diff
changeset
|
2224 { |
8c8d4841efae
[svn] - if entry->tuple == NULL, then probe the file for a decoder and build the appropriate tuple for that entry
nenolod
parents:
1270
diff
changeset
|
2225 playlist_entry_get_info(entry); |
8c8d4841efae
[svn] - if entry->tuple == NULL, then probe the file for a decoder and build the appropriate tuple for that entry
nenolod
parents:
1270
diff
changeset
|
2226 tuple = entry->tuple; |
8c8d4841efae
[svn] - if entry->tuple == NULL, then probe the file for a decoder and build the appropriate tuple for that entry
nenolod
parents:
1270
diff
changeset
|
2227 } |
8c8d4841efae
[svn] - if entry->tuple == NULL, then probe the file for a decoder and build the appropriate tuple for that entry
nenolod
parents:
1270
diff
changeset
|
2228 |
1269 | 2229 if (tuple != NULL) |
2230 { | |
2231 if (entry->decoder != NULL && entry->decoder->file_info_box == NULL) | |
2232 fileinfo_show_for_tuple(tuple); | |
1270 | 2233 else if (entry->decoder != NULL && entry->decoder->file_info_box != NULL) |
2234 entry->decoder->file_info_box(path); | |
1269 | 2235 else |
2236 fileinfo_show_for_path(path); | |
2237 g_free(path); | |
2238 } | |
2239 else if (path != NULL) | |
2240 { | |
1270 | 2241 if (entry != NULL && entry->decoder != NULL && entry->decoder->file_info_box != NULL) |
2242 entry->decoder->file_info_box(path); | |
2243 else | |
2244 fileinfo_show_for_path(path); | |
0 | 2245 g_free(path); |
2246 } | |
2247 } | |
2248 | |
2249 void | |
2085 | 2250 playlist_fileinfo_current(Playlist *playlist) |
0 | 2251 { |
2252 gchar *path = NULL; | |
1269 | 2253 TitleInput *tuple = NULL; |
0 | 2254 |
2255 PLAYLIST_LOCK(); | |
1269 | 2256 |
2085 | 2257 if (playlist->entries && playlist->position) |
1269 | 2258 { |
2085 | 2259 path = g_strdup(playlist->position->filename); |
2260 if (( playlist->position->tuple == NULL ) || ( playlist->position->decoder == NULL )) | |
2261 playlist_entry_get_info(playlist->position); | |
2262 tuple = playlist->position->tuple; | |
1269 | 2263 } |
2264 | |
0 | 2265 PLAYLIST_UNLOCK(); |
2266 | |
1269 | 2267 if (tuple != NULL) |
2268 { | |
2085 | 2269 if (playlist->position->decoder != NULL && playlist->position->decoder->file_info_box == NULL) |
1269 | 2270 fileinfo_show_for_tuple(tuple); |
2085 | 2271 else if (playlist->position->decoder != NULL && playlist->position->decoder->file_info_box != NULL) |
2272 playlist->position->decoder->file_info_box(path); | |
1269 | 2273 else |
2274 fileinfo_show_for_path(path); | |
2275 g_free(path); | |
2276 } | |
2277 else if (path != NULL) | |
2278 { | |
2085 | 2279 if (playlist->position != NULL && playlist->position->decoder != NULL && playlist->position->decoder->file_info_box != NULL) |
2280 playlist->position->decoder->file_info_box(path); | |
1270 | 2281 else |
2282 fileinfo_show_for_path(path); | |
0 | 2283 g_free(path); |
2284 } | |
2285 } | |
2286 | |
2287 | |
2288 static gboolean | |
2289 playlist_get_info_is_going(void) | |
2290 { | |
2291 gboolean result; | |
2292 | |
2293 G_LOCK(playlist_get_info_going); | |
2294 result = playlist_get_info_going; | |
2295 G_UNLOCK(playlist_get_info_going); | |
2296 | |
2297 return result; | |
2298 } | |
2299 | |
2300 static gpointer | |
2301 playlist_get_info_func(gpointer arg) | |
2302 { | |
2303 GList *node; | |
2304 gboolean update_playlistwin = FALSE; | |
2305 gboolean update_mainwin = FALSE; | |
2096 | 2306 Playlist *playlist = playlist_get_active(); |
0 | 2307 |
2308 while (playlist_get_info_is_going()) { | |
2309 PlaylistEntry *entry; | |
2310 | |
2026 | 2311 // on_load |
0 | 2312 if (cfg.use_pl_metadata && |
2313 cfg.get_info_on_load && | |
2314 playlist_get_info_scan_active) { | |
2315 | |
2316 PLAYLIST_LOCK(); | |
2317 for (node = playlist_get(); node; node = g_list_next(node)) { | |
2318 entry = node->data; | |
2319 | |
1826
d66712838e9f
[svn] - and finally special tuples are treated as they should be
nenolod
parents:
1825
diff
changeset
|
2320 if(entry->tuple && (entry->tuple->length > -1)) { |
2026 | 2321 update_playlistwin = TRUE; |
2322 continue; | |
1588
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
2323 } |
0 | 2324 |
2325 if (!playlist_entry_get_info(entry)) { | |
2326 if (g_list_index(playlist_get(), entry) == -1) | |
2327 /* Entry disappeared while we looked it up. | |
2328 Restart. */ | |
2329 node = playlist_get(); | |
2330 } | |
2026 | 2331 else if ((entry->tuple != NULL || entry->title != NULL) && entry->length != -1) { |
0 | 2332 update_playlistwin = TRUE; |
2096 | 2333 if (entry == playlist->position) |
0 | 2334 update_mainwin = TRUE; |
2335 break; | |
2336 } | |
2337 } | |
2338 PLAYLIST_UNLOCK(); | |
2026 | 2339 |
2340 if (!node) { | |
2341 g_mutex_lock(mutex_scan); | |
0 | 2342 playlist_get_info_scan_active = FALSE; |
2026 | 2343 g_mutex_unlock(mutex_scan); |
2344 } | |
2345 } // on_load | |
2346 | |
2347 // on_demand | |
0 | 2348 else if (!cfg.get_info_on_load && |
2349 cfg.get_info_on_demand && | |
2350 cfg.playlist_visible && | |
2351 !cfg.playlist_shaded && | |
2352 cfg.use_pl_metadata) { | |
2353 | |
2026 | 2354 g_mutex_lock(mutex_scan); |
2355 playlist_get_info_scan_active = FALSE; | |
2356 g_mutex_unlock(mutex_scan); | |
0 | 2357 |
2358 PLAYLIST_LOCK(); | |
2359 | |
2360 if (!playlist_get()) { | |
2361 PLAYLIST_UNLOCK(); | |
2362 } | |
2026 | 2363 else { |
2364 for (node = g_list_nth(playlist_get(), playlistwin_get_toprow()); | |
2365 node && playlistwin_item_visible(g_list_position(playlist_get(), node)); | |
2366 node = g_list_next(node)) { | |
2367 | |
2368 entry = node->data; | |
2369 | |
2370 if(entry->tuple && (entry->tuple->length > -1)) { | |
2371 update_playlistwin = TRUE; | |
2372 continue; | |
2373 } | |
2374 | |
2375 if (!playlist_entry_get_info(entry)) { | |
2376 if (g_list_index(playlist_get(), entry) == -1) | |
2377 /* Entry disapeared while we | |
2378 looked it up. Restart. */ | |
2379 node = | |
2380 g_list_nth(playlist_get(), | |
2381 playlistwin_get_toprow()); | |
2382 } | |
2383 else if ((entry->tuple != NULL || entry->title != NULL) && entry->length != -1) { | |
2384 update_playlistwin = TRUE; | |
2096 | 2385 if (entry == playlist->position) |
2026 | 2386 update_mainwin = TRUE; |
2027 | 2387 // no need for break here since this iteration is very short. |
2026 | 2388 } |
1706 | 2389 } |
2026 | 2390 PLAYLIST_UNLOCK(); |
0 | 2391 } |
2026 | 2392 } // on_demand |
2063
a3ad15fb0f34
[svn] - playlist_scan_thread_is_going should not be TRUE if the playlist is
nenolod
parents:
2040
diff
changeset
|
2393 else if (cfg.get_info_on_demand && |
a3ad15fb0f34
[svn] - playlist_scan_thread_is_going should not be TRUE if the playlist is
nenolod
parents:
2040
diff
changeset
|
2394 (!cfg.playlist_visible || cfg.playlist_shaded |
a3ad15fb0f34
[svn] - playlist_scan_thread_is_going should not be TRUE if the playlist is
nenolod
parents:
2040
diff
changeset
|
2395 || !cfg.use_pl_metadata)) |
a3ad15fb0f34
[svn] - playlist_scan_thread_is_going should not be TRUE if the playlist is
nenolod
parents:
2040
diff
changeset
|
2396 { |
a3ad15fb0f34
[svn] - playlist_scan_thread_is_going should not be TRUE if the playlist is
nenolod
parents:
2040
diff
changeset
|
2397 g_mutex_lock(mutex_scan); |
a3ad15fb0f34
[svn] - playlist_scan_thread_is_going should not be TRUE if the playlist is
nenolod
parents:
2040
diff
changeset
|
2398 playlist_get_info_scan_active = FALSE; |
a3ad15fb0f34
[svn] - playlist_scan_thread_is_going should not be TRUE if the playlist is
nenolod
parents:
2040
diff
changeset
|
2399 g_mutex_unlock(mutex_scan); |
a3ad15fb0f34
[svn] - playlist_scan_thread_is_going should not be TRUE if the playlist is
nenolod
parents:
2040
diff
changeset
|
2400 } |
0 | 2401 |
2402 if (update_playlistwin) { | |
2403 playlistwin_update_list(); | |
2404 update_playlistwin = FALSE; | |
2405 } | |
2406 | |
2407 if (update_mainwin) { | |
2408 mainwin_set_info_text(); | |
2409 update_mainwin = FALSE; | |
2410 } | |
2026 | 2411 |
2412 if (playlist_get_info_scan_active) { | |
2413 continue; | |
2414 } | |
2415 | |
2416 g_mutex_lock(mutex_scan); | |
2417 g_cond_wait(cond_scan, mutex_scan); | |
2418 g_mutex_unlock(mutex_scan); | |
2419 | |
2027 | 2420 } // while |
0 | 2421 |
2422 g_thread_exit(NULL); | |
2423 return NULL; | |
2424 } | |
2425 | |
2426 void | |
2427 playlist_start_get_info_thread(void) | |
2428 { | |
2027 | 2429 G_LOCK(playlist_get_info_going); |
0 | 2430 playlist_get_info_going = TRUE; |
2027 | 2431 G_UNLOCK(playlist_get_info_going); |
2432 | |
0 | 2433 playlist_get_info_thread = g_thread_create(playlist_get_info_func, |
2434 NULL, TRUE, NULL); | |
2435 } | |
2436 | |
2437 void | |
2438 playlist_stop_get_info_thread(void) | |
2439 { | |
2440 G_LOCK(playlist_get_info_going); | |
2441 playlist_get_info_going = FALSE; | |
2442 G_UNLOCK(playlist_get_info_going); | |
2026 | 2443 |
2444 g_cond_broadcast(cond_scan); | |
0 | 2445 g_thread_join(playlist_get_info_thread); |
2446 } | |
2447 | |
2448 void | |
2449 playlist_start_get_info_scan(void) | |
2450 { | |
2026 | 2451 g_mutex_lock(mutex_scan); |
0 | 2452 playlist_get_info_scan_active = TRUE; |
2026 | 2453 g_mutex_unlock(mutex_scan); |
2454 g_cond_signal(cond_scan); | |
0 | 2455 } |
2456 | |
2457 void | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2458 playlist_remove_dead_files(Playlist *playlist) |
0 | 2459 { |
2460 GList *node, *next_node; | |
2461 | |
2462 PLAYLIST_LOCK(); | |
2463 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2464 for (node = playlist->entries; node; node = next_node) { |
0 | 2465 PlaylistEntry *entry = PLAYLIST_ENTRY(node->data); |
2466 next_node = g_list_next(node); | |
2467 | |
2468 if (!entry || !entry->filename) { | |
2469 g_message(G_STRLOC ": Playlist entry is invalid!"); | |
2470 continue; | |
2471 } | |
2472 | |
2473 /* FIXME: What about 'file:///'? */ | |
2474 /* Don't kill URLs */ | |
2475 if (strstr(entry->filename, "://")) | |
2476 continue; | |
2477 | |
2478 /* FIXME: Should test for readability */ | |
2479 if (vfs_file_test(entry->filename, G_FILE_TEST_EXISTS)) | |
2480 continue; | |
2481 | |
2096 | 2482 if (entry == playlist->position) { |
0 | 2483 /* Don't remove the currently playing song */ |
2484 if (bmp_playback_get_playing()) | |
2485 continue; | |
2486 | |
2487 if (next_node) | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2488 playlist->position = PLAYLIST_ENTRY(next_node->data); |
0 | 2489 else |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2490 playlist->position = NULL; |
0 | 2491 } |
2492 | |
2493 playlist_entry_free(entry); | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2494 playlist->entries = g_list_delete_link(playlist->entries, node); |
0 | 2495 } |
2496 | |
2497 PLAYLIST_UNLOCK(); | |
2498 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2499 playlist_generate_shuffle_list(playlist); |
0 | 2500 playlistwin_update_list(); |
2085 | 2501 playlist_recalc_total_time(playlist); |
0 | 2502 } |
2503 | |
852
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2504 |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2505 static gint |
1251 | 2506 playlist_dupscmp_title(PlaylistEntry * a, |
2507 PlaylistEntry * b) | |
852
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2508 { |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2509 const gchar *a_title, *b_title; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2510 |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2511 g_return_val_if_fail(a != NULL, 0); |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2512 g_return_val_if_fail(b != NULL, 0); |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2513 |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2514 if (a->title) |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2515 a_title = a->title; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2516 else { |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2517 if (strrchr(a->filename, '/')) |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2518 a_title = strrchr(a->filename, '/') + 1; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2519 else |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2520 a_title = a->filename; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2521 } |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2522 |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2523 if (b->title) |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2524 b_title = b->title; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2525 else { |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2526 if (strrchr(a->filename, '/')) |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2527 b_title = strrchr(b->filename, '/') + 1; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2528 else |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2529 b_title = b->filename; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2530 } |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2531 |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2532 return strcmp(a_title, b_title); |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2533 } |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2534 |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2535 static gint |
1251 | 2536 playlist_dupscmp_filename(PlaylistEntry * a, |
2537 PlaylistEntry * b ) | |
852
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2538 { |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2539 gchar *a_filename, *b_filename; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2540 |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2541 g_return_val_if_fail(a != NULL, 0); |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2542 g_return_val_if_fail(b != NULL, 0); |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2543 |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2544 if (strrchr(a->filename, '/')) |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2545 a_filename = strrchr(a->filename, '/') + 1; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2546 else |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2547 a_filename = a->filename; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2548 |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2549 if (strrchr(b->filename, '/')) |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2550 b_filename = strrchr(b->filename, '/') + 1; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2551 else |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2552 b_filename = b->filename; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2553 |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2554 return strcmp(a_filename, b_filename); |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2555 } |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2556 |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2557 static gint |
1251 | 2558 playlist_dupscmp_path(PlaylistEntry * a, |
2559 PlaylistEntry * b) | |
852
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2560 { |
853 | 2561 /* simply compare the entire filename string */ |
2562 return strcmp(a->filename, b->filename); | |
852
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2563 } |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2564 |
840
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2565 void |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2566 playlist_remove_duplicates(Playlist *playlist, PlaylistDupsType type) |
840
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2567 { |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2568 GList *node, *next_node; |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2569 GList *node_cmp, *next_node_cmp; |
1251 | 2570 gint (*dups_compare_func)(PlaylistEntry * , PlaylistEntry *); |
852
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2571 |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2572 switch ( type ) |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2573 { |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2574 case PLAYLIST_DUPS_TITLE: |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2575 dups_compare_func = playlist_dupscmp_title; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2576 break; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2577 case PLAYLIST_DUPS_PATH: |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2578 dups_compare_func = playlist_dupscmp_path; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2579 break; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2580 case PLAYLIST_DUPS_FILENAME: |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2581 default: |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2582 dups_compare_func = playlist_dupscmp_filename; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2583 break; |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2584 } |
840
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2585 |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2586 PLAYLIST_LOCK(); |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2587 |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2588 for (node = playlist->entries; node; node = next_node) { |
840
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2589 PlaylistEntry *entry = PLAYLIST_ENTRY(node->data); |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2590 next_node = g_list_next(node); |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2591 |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2592 if (!entry || !entry->filename) { |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2593 g_message(G_STRLOC ": Playlist entry is invalid!"); |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2594 continue; |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2595 } |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2596 |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2597 for (node_cmp = next_node; node_cmp; node_cmp = next_node_cmp) { |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2598 PlaylistEntry *entry_cmp = PLAYLIST_ENTRY(node_cmp->data); |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2599 next_node_cmp = g_list_next(node_cmp); |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2600 |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2601 if (!entry_cmp || !entry_cmp->filename) { |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2602 g_message(G_STRLOC ": Playlist entry is invalid!"); |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2603 continue; |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2604 } |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2605 |
852
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2606 /* compare using the chosen dups_compare_func */ |
bcff46a2558d
[svn] added multiple 'remove duplicates' (by title, by filename, by path+filename)
giacomo
parents:
840
diff
changeset
|
2607 if ( !dups_compare_func( entry , entry_cmp ) ) { |
840
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2608 |
2096 | 2609 if (entry_cmp == playlist->position) { |
840
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2610 /* Don't remove the currently playing song */ |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2611 if (bmp_playback_get_playing()) |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2612 continue; |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2613 |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2614 if (next_node_cmp) |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2615 playlist->position = PLAYLIST_ENTRY(next_node_cmp->data); |
840
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2616 else |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2617 playlist->position = NULL; |
840
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2618 } |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2619 |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2620 /* check if this was the next item of the external |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2621 loop; if true, replace it with the next of the next*/ |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2622 if ( node_cmp == next_node ) |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2623 next_node = g_list_next(next_node); |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2624 |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2625 playlist_entry_free(entry_cmp); |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2626 playlist->entries = g_list_delete_link(playlist->entries, node_cmp); |
840
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2627 } |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2628 } |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2629 } |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2630 |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2631 PLAYLIST_UNLOCK(); |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2632 |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2633 playlistwin_update_list(); |
2085 | 2634 playlist_recalc_total_time(playlist); |
840
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2635 } |
ffc5ab7b4b2c
[svn] added a 'remove duplicates' option to the playlist removal menu
giacomo
parents:
633
diff
changeset
|
2636 |
0 | 2637 void |
2085 | 2638 playlist_get_total_time(Playlist * playlist, |
2639 gulong * total_time, | |
0 | 2640 gulong * selection_time, |
2641 gboolean * total_more, | |
2642 gboolean * selection_more) | |
2643 { | |
2644 PLAYLIST_LOCK(); | |
2085 | 2645 *total_time = playlist->pl_total_time; |
2646 *selection_time = playlist->pl_selection_time; | |
2647 *total_more = playlist->pl_total_more; | |
2648 *selection_more = playlist->pl_selection_more; | |
0 | 2649 PLAYLIST_UNLOCK(); |
2650 } | |
2651 | |
2652 | |
2653 static void | |
2085 | 2654 playlist_recalc_total_time_nolock(Playlist *playlist) |
0 | 2655 { |
2656 GList *list; | |
2657 PlaylistEntry *entry; | |
2658 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2659 REQUIRE_STATIC_LOCK(playlists); |
0 | 2660 |
2085 | 2661 playlist->pl_total_time = 0; |
2662 playlist->pl_selection_time = 0; | |
2663 playlist->pl_total_more = FALSE; | |
2664 playlist->pl_selection_more = FALSE; | |
0 | 2665 |
2120
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
2666 for (list = playlist->entries; list; list = g_list_next(list)) { |
0 | 2667 entry = list->data; |
2668 | |
2669 if (entry->length != -1) | |
2085 | 2670 playlist->pl_total_time += entry->length / 1000; |
0 | 2671 else |
2085 | 2672 playlist->pl_total_more = TRUE; |
0 | 2673 |
2674 if (entry->selected) { | |
2675 if (entry->length != -1) | |
2085 | 2676 playlist->pl_selection_time += entry->length / 1000; |
0 | 2677 else |
2085 | 2678 playlist->pl_selection_more = TRUE; |
0 | 2679 } |
2680 } | |
2681 } | |
2682 | |
2683 static void | |
2085 | 2684 playlist_recalc_total_time(Playlist *playlist) |
0 | 2685 { |
2686 PLAYLIST_LOCK(); | |
2085 | 2687 playlist_recalc_total_time_nolock(playlist); |
0 | 2688 PLAYLIST_UNLOCK(); |
2689 } | |
2690 | |
2691 | |
2692 void | |
2085 | 2693 playlist_select_all(Playlist *playlist, gboolean set) |
0 | 2694 { |
2695 GList *list; | |
2696 | |
2697 PLAYLIST_LOCK(); | |
2698 | |
2085 | 2699 for (list = playlist->entries; list; list = g_list_next(list)) { |
0 | 2700 PlaylistEntry *entry = list->data; |
2701 entry->selected = set; | |
2702 } | |
2703 | |
2704 PLAYLIST_UNLOCK(); | |
2085 | 2705 playlist_recalc_total_time(playlist); |
0 | 2706 } |
2707 | |
2708 void | |
2085 | 2709 playlist_select_invert_all(Playlist *playlist) |
0 | 2710 { |
2711 GList *list; | |
2712 | |
2713 PLAYLIST_LOCK(); | |
2714 | |
2085 | 2715 for (list = playlist->entries; list; list = g_list_next(list)) { |
0 | 2716 PlaylistEntry *entry = list->data; |
2717 entry->selected = !entry->selected; | |
2718 } | |
2719 | |
2720 PLAYLIST_UNLOCK(); | |
2085 | 2721 playlist_recalc_total_time(playlist); |
0 | 2722 } |
2723 | |
2724 gboolean | |
2085 | 2725 playlist_select_invert(Playlist *playlist, guint pos) |
0 | 2726 { |
2727 GList *list; | |
2728 gboolean invert_ok = FALSE; | |
2729 | |
2730 PLAYLIST_LOCK(); | |
2731 | |
2085 | 2732 if ((list = g_list_nth(playlist->entries, pos))) { |
0 | 2733 PlaylistEntry *entry = list->data; |
2734 entry->selected = !entry->selected; | |
2735 invert_ok = TRUE; | |
2736 } | |
2737 | |
2738 PLAYLIST_UNLOCK(); | |
2085 | 2739 playlist_recalc_total_time(playlist); |
0 | 2740 |
2741 return invert_ok; | |
2742 } | |
2743 | |
2744 | |
2745 void | |
2085 | 2746 playlist_select_range(Playlist *playlist, gint min_pos, gint max_pos, gboolean select) |
0 | 2747 { |
2748 GList *list; | |
2749 gint i; | |
2750 | |
2751 if (min_pos > max_pos) | |
2752 SWAP(min_pos, max_pos); | |
2753 | |
2754 PLAYLIST_LOCK(); | |
2755 | |
2085 | 2756 list = g_list_nth(playlist->entries, min_pos); |
0 | 2757 for (i = min_pos; i <= max_pos && list; i++) { |
2758 PlaylistEntry *entry = list->data; | |
2759 entry->selected = select; | |
2760 list = g_list_next(list); | |
2761 } | |
2762 | |
2763 PLAYLIST_UNLOCK(); | |
2764 | |
2085 | 2765 playlist_recalc_total_time(playlist); |
0 | 2766 } |
2767 | |
2768 gboolean | |
2085 | 2769 playlist_read_info_selection(Playlist *playlist) |
0 | 2770 { |
2771 GList *node; | |
2772 gboolean retval = FALSE; | |
2773 | |
2774 PLAYLIST_LOCK(); | |
2775 | |
2776 for (node = playlist_get(); node; node = g_list_next(node)) { | |
2777 PlaylistEntry *entry = node->data; | |
2778 if (!entry->selected) | |
2779 continue; | |
2780 | |
2781 retval = TRUE; | |
2782 | |
2783 str_replace_in(&entry->title, NULL); | |
2784 entry->length = -1; | |
2785 | |
1588
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
2786 /* invalidate mtime to reread */ |
1817 | 2787 if (entry->tuple != NULL) |
1841
7d0cd3fab6a2
[svn] - mtime=-1 has been introduced to represent "uninitialized".
yaz
parents:
1834
diff
changeset
|
2788 entry->tuple->mtime = -1; /* -1 denotes "non-initialized". now 0 is for stream etc. yaz */ |
1588
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1587
diff
changeset
|
2789 |
0 | 2790 if (!playlist_entry_get_info(entry)) { |
2791 if (g_list_index(playlist_get(), entry) == -1) | |
2792 /* Entry disappeared while we looked it up. Restart. */ | |
2793 node = playlist_get(); | |
2794 } | |
2795 } | |
2796 | |
2797 PLAYLIST_UNLOCK(); | |
2798 | |
2799 playlistwin_update_list(); | |
2085 | 2800 playlist_recalc_total_time(playlist); |
0 | 2801 |
2802 return retval; | |
2803 } | |
2804 | |
2805 void | |
2085 | 2806 playlist_read_info(Playlist *playlist, guint pos) |
0 | 2807 { |
2808 GList *node; | |
2809 | |
2810 PLAYLIST_LOCK(); | |
2811 | |
2812 if ((node = g_list_nth(playlist_get(), pos))) { | |
2813 PlaylistEntry *entry = node->data; | |
2814 str_replace_in(&entry->title, NULL); | |
2815 entry->length = -1; | |
2816 playlist_entry_get_info(entry); | |
2817 } | |
2818 | |
2819 PLAYLIST_UNLOCK(); | |
2820 | |
2821 playlistwin_update_list(); | |
2085 | 2822 playlist_recalc_total_time(playlist); |
0 | 2823 } |
2824 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2825 Playlist * |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2826 playlist_get_active(void) |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2827 { |
2120
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
2828 if (playlists_iter != NULL) |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
2829 return (Playlist *) playlists_iter->data; |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
2830 |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
2831 return (Playlist *) playlists->data; |
1d67cf383e32
[svn] - dynamically allocate the playlist at startup and fix some lingering improper uses of playlist_get()
nenolod
parents:
2105
diff
changeset
|
2832 } |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2833 |
0 | 2834 void |
2835 playlist_set_shuffle(gboolean shuffle) | |
2836 { | |
2837 PLAYLIST_LOCK(); | |
2838 | |
2040
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
2839 playlist_position_before_jump = NULL; |
dbe615def81f
[svn] Playlist shuffle behaviour should now be a little more consistant.
nazca
parents:
2027
diff
changeset
|
2840 |
0 | 2841 cfg.shuffle = shuffle; |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2842 playlist_generate_shuffle_list_nolock(playlist_get_active()); |
0 | 2843 |
2844 PLAYLIST_UNLOCK(); | |
2845 } | |
2846 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2847 Playlist * |
0 | 2848 playlist_new(void) |
2849 { | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2850 Playlist *playlist = g_new0(Playlist, 1); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2851 |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2852 playlist_set_current_name(playlist, NULL); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2853 playlist_clear(playlist); |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2854 |
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2855 return playlist; |
0 | 2856 } |
2857 | |
2858 | |
2859 const gchar * | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2860 playlist_get_filename_to_play(Playlist *playlist) |
0 | 2861 { |
2862 const gchar *filename = NULL; | |
2863 | |
2864 PLAYLIST_LOCK(); | |
2865 | |
2866 if (playlist) { | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2867 if (!playlist->position) { |
0 | 2868 if (cfg.shuffle) |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2869 playlist->position = playlist->shuffle->data; |
0 | 2870 else |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2871 playlist->position = playlist->entries->data; |
0 | 2872 } |
2873 | |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2874 filename = playlist->position->filename; |
0 | 2875 } |
2876 | |
2877 PLAYLIST_UNLOCK(); | |
2878 | |
2879 return filename; | |
2880 } | |
356
99928e1275a1
[svn] This commit reduces the amount of times we probe a source down to ONE
nenolod
parents:
355
diff
changeset
|
2881 |
398
f908bcd87c3d
[svn] Generate cache content on demand if it was not previously there.
nenolod
parents:
397
diff
changeset
|
2882 PlaylistEntry * |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2883 playlist_get_entry_to_play(Playlist *playlist) |
356
99928e1275a1
[svn] This commit reduces the amount of times we probe a source down to ONE
nenolod
parents:
355
diff
changeset
|
2884 { |
99928e1275a1
[svn] This commit reduces the amount of times we probe a source down to ONE
nenolod
parents:
355
diff
changeset
|
2885 PLAYLIST_LOCK(); |
99928e1275a1
[svn] This commit reduces the amount of times we probe a source down to ONE
nenolod
parents:
355
diff
changeset
|
2886 |
99928e1275a1
[svn] This commit reduces the amount of times we probe a source down to ONE
nenolod
parents:
355
diff
changeset
|
2887 if (playlist) { |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2888 if (!playlist->position) { |
356
99928e1275a1
[svn] This commit reduces the amount of times we probe a source down to ONE
nenolod
parents:
355
diff
changeset
|
2889 if (cfg.shuffle) |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2890 playlist->position = playlist->shuffle->data; |
356
99928e1275a1
[svn] This commit reduces the amount of times we probe a source down to ONE
nenolod
parents:
355
diff
changeset
|
2891 else |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2892 playlist->position = playlist->entries->data; |
356
99928e1275a1
[svn] This commit reduces the amount of times we probe a source down to ONE
nenolod
parents:
355
diff
changeset
|
2893 } |
99928e1275a1
[svn] This commit reduces the amount of times we probe a source down to ONE
nenolod
parents:
355
diff
changeset
|
2894 } |
99928e1275a1
[svn] This commit reduces the amount of times we probe a source down to ONE
nenolod
parents:
355
diff
changeset
|
2895 |
99928e1275a1
[svn] This commit reduces the amount of times we probe a source down to ONE
nenolod
parents:
355
diff
changeset
|
2896 PLAYLIST_UNLOCK(); |
99928e1275a1
[svn] This commit reduces the amount of times we probe a source down to ONE
nenolod
parents:
355
diff
changeset
|
2897 |
2080
df6cf9cb531e
[svn] - this commit breaks the API. I'm not done here, but hopefully the new API is
nenolod
parents:
2073
diff
changeset
|
2898 return playlist->position; |
356
99928e1275a1
[svn] This commit reduces the amount of times we probe a source down to ONE
nenolod
parents:
355
diff
changeset
|
2899 } |