207
213
if(gtk_tree_model_get_iter (model, &iter_d, path))
209
gtk_tree_model_get (model, &iter_d, 0, &pl_d, -1);
215
gtk_tree_model_get (model, &iter_d, PM_COLUMN_PLAYLIST, &pl_d, -1);
211
217
g_return_val_if_fail (pl_d, FALSE);
219
g_return_val_if_fail (itdb, FALSE);
220
eitdb = itdb->userdata;
221
g_return_val_if_fail (eitdb, FALSE);
213
223
target = gtk_drag_dest_find_target (widget, dc, NULL);
225
/* no drop possible if repository is not loaded */
226
if (!eitdb->itdb_imported)
228
gtk_tree_path_free (path);
229
gdk_drag_status (dc, 0, time);
215
233
/* no drop possible if no valid target can be found */
216
234
if (target == GDK_NONE)
236
gtk_tree_path_free (path);
218
237
gdk_drag_status (dc, 0, time);
219
gtk_tree_path_free (path);
614
632
g_object_set_data (G_OBJECT (widget), "drag_data_by_motion_pos", NULL);
615
633
if(gtk_tree_model_get_iter (model, &iter_d, path_m))
617
gtk_tree_model_get (model, &iter_d, 0, &pl, -1);
635
gtk_tree_model_get (model, &iter_d, PM_COLUMN_PLAYLIST, &pl, -1);
619
637
gtk_tree_path_free (path_m);
674
692
g_return_if_fail (path_d);
676
if(gtk_tree_model_get_iter(model, &iter_d, path_d))
678
gtk_tree_model_get(model, &iter_d, 0, &pl, -1);
680
g_return_if_fail (pl);
682
/* get position of current path */
683
if (gtk_tree_path_get_depth (path_d) == 1)
689
gint *indices = gtk_tree_path_get_indices (path_d);
690
/* need to add 1 because MPL is one level higher and not
692
position = indices[1] + 1;
694
if(gtk_tree_model_get_iter (model, &iter_d, path_d))
696
gtk_tree_model_get (model, &iter_d, PM_COLUMN_PLAYLIST, &pl, -1);
694
698
gtk_tree_path_free (path_d);
701
g_return_if_fail (pl);
703
position = pm_get_position_for_playlist (pl);
697
705
/* printf("position: %d\n", position); */
846
854
gtk_drag_finish (dc, TRUE, FALSE, time);
848
856
case GDK_ACTION_MOVE:
849
if (prefs_get_int("pm_sort") != SORT_NONE)
851
gtkpod_statusbar_message (_("Can't reorder sorted treeview."));
852
gtk_drag_finish (dc, FALSE, FALSE, time);
855
path_s = pm_get_path (pl_s);
856
g_return_if_fail (path_s);
857
g_return_if_fail (gtk_tree_model_get_iter (
858
model, &iter_s, path_s));
859
gtk_tree_path_free (path_s);
857
pm_get_iter_for_playlist (pl_s, &iter_s);
862
860
case GTK_TREE_VIEW_DROP_BEFORE:
861
if (prefs_get_int("pm_sort") != SORT_NONE)
863
gtkpod_statusbar_message (_("Can't reorder sorted treeview."));
864
gtk_drag_finish (dc, FALSE, FALSE, time);
863
867
gtk_tree_store_move_before (GTK_TREE_STORE (model),
864
868
&iter_s, &iter_d);
865
869
pm_rows_reordered ();
866
870
gtk_drag_finish (dc, TRUE, FALSE, time);
868
872
case GTK_TREE_VIEW_DROP_AFTER:
873
if (prefs_get_int("pm_sort") != SORT_NONE)
875
gtkpod_statusbar_message (_("Can't reorder sorted treeview."));
876
gtk_drag_finish (dc, FALSE, FALSE, time);
869
879
gtk_tree_store_move_after (GTK_TREE_STORE (model),
870
880
&iter_s, &iter_d);
871
881
pm_rows_reordered ();
994
1005
/* ---------------------------------------------------------------- */
1006
/* Section for playlist display helper functions */
1007
/* ---------------------------------------------------------------- */
1010
/* Find the iter that represents the repository @itdb
1012
* Return TRUE if the repository could be found. In that case @itdb_iter
1013
* will be set to the corresponding iter. The value of @itdb_iter is
1014
* undefined when the repository couldn't be found, in which case FALSE
1016
static gboolean pm_get_iter_for_itdb (iTunesDB *itdb, GtkTreeIter *itdb_iter)
1018
GtkTreeModel *model;
1020
g_return_val_if_fail (playlist_treeview, FALSE);
1021
g_return_val_if_fail (itdb, FALSE);
1022
g_return_val_if_fail (itdb_iter, FALSE);
1024
model = GTK_TREE_MODEL (gtk_tree_view_get_model (playlist_treeview));
1026
if (gtk_tree_model_get_iter_first (model, itdb_iter))
1030
iTunesDB *itdb_model;
1031
gtk_tree_model_get (model, itdb_iter,
1032
PM_COLUMN_ITDB, &itdb_model,
1034
g_return_val_if_fail (itdb_model, FALSE);
1035
if (itdb == itdb_model)
1039
} while (gtk_tree_model_iter_next (model, itdb_iter));
1045
/* Find the iter that contains Playlist @playlist
1047
* Return TRUE if the playlist could be found. In that case @pl_iter
1048
* will be set to the corresponding iter. The value of @pl_iter is
1049
* undefined when the playlist couldn't be found, in which case FALSE
1051
static gboolean pm_get_iter_for_playlist (Playlist *playlist, GtkTreeIter *pl_iter)
1053
GtkTreeIter itdb_iter;
1055
g_return_val_if_fail (playlist_treeview, FALSE);
1056
g_return_val_if_fail (playlist, FALSE);
1057
g_return_val_if_fail (pl_iter, FALSE);
1059
/* First get the iter with the itdb in it */
1061
if (pm_get_iter_for_itdb (playlist->itdb, &itdb_iter))
1063
GtkTreeModel *model;
1066
model = GTK_TREE_MODEL (gtk_tree_view_get_model (playlist_treeview));
1068
/* Check if this is already the right iter */
1069
gtk_tree_model_get (model, &itdb_iter,
1070
PM_COLUMN_PLAYLIST, &pl,
1072
g_return_val_if_fail (pl, FALSE);
1075
*pl_iter = itdb_iter;
1079
/* no -- go down one hierarchy and try all other iters */
1080
if (!gtk_tree_model_iter_children (model, pl_iter, &itdb_iter))
1081
{ /* This indicates screwed up programming so we better cry
1083
g_return_val_if_reached (FALSE);
1088
gtk_tree_model_get (model, pl_iter,
1089
PM_COLUMN_PLAYLIST, &pl,
1091
g_return_val_if_fail (pl, FALSE);
1096
} while (gtk_tree_model_iter_next (model, pl_iter));
1104
/* ---------------------------------------------------------------- */
995
1105
/* Section for playlist display */
996
1106
/* ---------------------------------------------------------------- */
1024
1138
if (playlist == current_playlist)
1026
1140
st_add_track (track, TRUE, display, 0); /* Add to first sort tab */
1142
/* As with add_track above, only add to the playlist if it is the current one */
1143
if (prefs_get_int (KEY_DISPLAY_COVERART))
1145
coverart_track_changed (track, COVERART_CREATE_SIGNAL);
1030
/* Used by pm_name_changed() to find the playlist that
1031
changed name. If found, emit a "row changed" signal to display the change */
1032
static gboolean sr_model_playlist_name_changed (GtkTreeModel *model,
1037
Playlist *playlist=NULL;
1039
gtk_tree_model_get (model, iter, PM_COLUMN_PLAYLIST, &playlist, -1);
1040
if(playlist == (Playlist *)data) {
1041
gtk_tree_model_row_changed (model, path, iter);
1048
1150
/* One of the playlist names has changed (this happens when the
1049
1151
iTunesDB is read */
1050
void pm_name_changed (Playlist *pl)
1152
void pm_itdb_name_changed (iTunesDB *itdb)
1052
GtkTreeModel *model = gtk_tree_view_get_model (playlist_treeview);
1054
g_return_if_fail (pl);
1055
g_return_if_fail (model);
1057
gtk_tree_model_foreach (model, sr_model_playlist_name_changed, pl);
1156
g_return_if_fail (itdb);
1158
if (pm_get_iter_for_itdb (itdb, &iter))
1160
GtkTreeModel *model;
1162
model = GTK_TREE_MODEL (gtk_tree_view_get_model (playlist_treeview));
1163
path = gtk_tree_model_get_path (model, &iter);
1164
gtk_tree_model_row_changed (model, path, &iter);
1165
gtk_tree_path_free (path);
1064
1173
void pm_track_changed (Track *track)
1066
1175
if (!current_playlist) return;
1177
if (prefs_get_int (KEY_DISPLAY_COVERART))
1178
coverart_track_changed (track, COVERART_CHANGE_SIGNAL);
1067
1180
/* Check if track is member of current playlist */
1068
1181
if (g_list_find (current_playlist->members, track))
1069
1182
st_track_changed (track, FALSE, 0);
1073
1185
/* Add playlist to the playlist model */
1074
1186
/* If @position = -1: append to end */
1075
1187
/* If @position >=0: insert at that position (count starts with MPL as
1091
1204
if (itdb_playlist_is_mpl (playlist))
1092
1205
{ /* MPLs are always added top-level */
1207
itdb = playlist->itdb;
1096
1210
{ /* We need to find the iter with the mpl in it */
1097
if (gtk_tree_model_get_iter_first (model, &mpl_iter))
1211
if (pm_get_iter_for_itdb (playlist->itdb, &mpl_iter))
1102
gtk_tree_model_get (model, &mpl_iter,
1103
PM_COLUMN_PLAYLIST, &pl, -1);
1104
g_return_if_fail (pl);
1105
if (pl->itdb == playlist->itdb)
1109
} while ((mpl == NULL) &&
1110
gtk_tree_model_iter_next (model, &mpl_iter));
1114
1217
g_warning ("Programming error: need to add mpl before adding normal playlists.\n");
1116
1219
/* reduce position by one because the MPL is not included in the
1117
1220
tree model's count */
1121
1225
gtk_tree_store_insert (GTK_TREE_STORE (model), &iter, mpl, pos);
1123
1227
gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
1228
PM_COLUMN_ITDB, itdb,
1124
1229
PM_COLUMN_PLAYLIST, playlist,
1149
/* former inline function: used by pm_remove_playlist() */
1150
static gboolean pm_delete_playlist_fe (GtkTreeModel *model,
1155
Playlist *playlist=NULL;
1157
gtk_tree_model_get (model, iter, PM_COLUMN_PLAYLIST, &playlist, -1);
1158
if(playlist == (Playlist *)data) {
1159
gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
1165
1254
/* Remove "playlist" from the display model.
1166
1255
"select": TRUE: a new playlist is selected
1167
1256
FALSE: no selection is taking place
1192
1281
if (select && (current_playlist == playlist))
1193
1282
{ /* We are about to delete the currently selected
1194
1283
playlist. Try to select the next. */
1195
if (gtk_tree_selection_get_selected (ts, NULL, &i))
1284
if (gtk_tree_selection_get_selected (ts, NULL, &select_iter))
1197
GtkTreePath *path = gtk_tree_model_get_path (model, &i);
1198
if(gtk_tree_model_iter_next (model, &i))
1286
GtkTreePath *path = gtk_tree_model_get_path (model, &select_iter);
1287
if(gtk_tree_model_iter_next (model, &select_iter))
1200
1289
have_iter = TRUE;
1214
/* find the pl and delete it */
1215
gtk_tree_model_foreach (model, pm_delete_playlist_fe, playlist);
1303
if (pm_get_iter_for_playlist (playlist, &delete_iter))
1305
gtk_tree_store_remove (GTK_TREE_STORE (model), &delete_iter);
1216
1308
/* select our new iter !!! */
1217
if (have_iter && select) gtk_tree_selection_select_iter(ts, &i);
1309
if (have_iter && select) gtk_tree_selection_select_iter(ts, &select_iter);
1252
/* former inline function: used by pm_select_playlist */
1253
static gboolean pm_select_playlist_fe (GtkTreeModel *model,
1258
Playlist *playlist=NULL;
1260
gtk_tree_model_get (model, iter,
1261
PM_COLUMN_PLAYLIST, &playlist, -1);
1262
if(playlist == data)
1264
GtkTreeSelection *ts = gtk_tree_view_get_selection (
1266
gtk_tree_selection_select_iter (ts, iter);
1272
1344
/* Select specified playlist */
1273
1345
void pm_select_playlist (Playlist *playlist)
1275
GtkTreeModel *model;
1277
1349
g_return_if_fail (playlist_treeview);
1278
1350
g_return_if_fail (playlist);
1279
model = gtk_tree_view_get_model (playlist_treeview);
1280
g_return_if_fail (model);
1282
/* find the pl and select it */
1283
gtk_tree_model_foreach (model, pm_select_playlist_fe,
1352
if (pm_get_iter_for_playlist (playlist, &iter))
1354
GtkTreeSelection *ts;
1355
ts = gtk_tree_view_get_selection (playlist_treeview);
1356
gtk_tree_selection_select_iter (ts, &iter);
1288
/* former inline function: used by pm_unselect_playlist */
1289
static gboolean pm_unselect_playlist_fe (GtkTreeModel *model,
1294
Playlist *playlist=NULL;
1296
gtk_tree_model_get (model, iter,
1297
PM_COLUMN_PLAYLIST, &playlist, -1);
1298
if(playlist == data)
1300
GtkTreeSelection *ts = gtk_tree_view_get_selection (
1302
gtk_tree_selection_unselect_iter (ts, iter);
1308
1361
/* Unselect specified playlist */
1309
1362
void pm_unselect_playlist (Playlist *playlist)
1311
GtkTreeModel *model;
1313
1366
g_return_if_fail (playlist_treeview);
1314
1367
g_return_if_fail (playlist);
1315
model = gtk_tree_view_get_model (playlist_treeview);
1316
g_return_if_fail (model);
1318
/* find the pl and unselect it */
1319
gtk_tree_model_foreach (model, pm_unselect_playlist_fe,
1369
if (pm_get_iter_for_playlist (playlist, &iter))
1371
GtkTreeSelection *ts;
1372
ts = gtk_tree_view_get_selection (playlist_treeview);
1373
gtk_tree_selection_unselect_iter (ts, &iter);
1324
static void pm_selection_changed_cb (gpointer user_data1, gpointer user_data2)
1378
static void pm_selection_changed_cb (GtkTreeSelection *selection,
1379
gpointer user_data2)
1326
GtkTreeSelection *selection = (GtkTreeSelection *)user_data1;
1327
1381
GtkTreeModel *model;
1328
1382
GtkTreeIter iter;
1329
1383
Playlist *new_playlist = NULL;
1365
1424
itdb_spl_update (new_playlist);
1366
1425
if (new_playlist->members)
1369
float max_count = REFRESH_INIT_COUNT;
1370
gint count = max_count - 1;
1374
if (!prefs_get_int("block_display"))
1376
block_selection (-1);
1377
g_get_current_time (&time);
1379
1429
st_enable_disable_view_sort (0, FALSE);
1380
1430
for (gl=new_playlist->members; gl; gl=gl->next)
1381
1431
{ /* add all tracks to sort tab 0 */
1382
1432
Track *track = gl->data;
1383
if (stop_add == -1) break;
1384
1433
st_add_track (track, FALSE, TRUE, 0);
1386
if ((count < 0) && !prefs_get_int("block_display"))
1388
gtkpod_tracks_statusbar_update();
1389
while (gtk_events_pending ()) gtk_main_iteration ();
1390
ms = get_ms_since (&time, TRUE);
1391
/* first time takes significantly longer, so we adjust
1393
if (max_count == REFRESH_INIT_COUNT) max_count *= 2.5;
1394
/* average the new and the old max_count */
1395
max_count *= (1 + 2 * REFRESH_MS / ms) / 3;
1396
count = max_count - 1;
1398
printf("pm_s_c ms: %f mc: %f\n", ms, max_count);
1402
1435
st_enable_disable_view_sort (0, TRUE);
1403
if (stop_add != -1) st_add_track (NULL, TRUE, TRUE, 0);
1404
if (!prefs_get_int("block_display"))
1406
while (gtk_events_pending ()) gtk_main_iteration ();
1407
release_selection (-1);
1436
st_add_track (NULL, TRUE, TRUE, 0);
1410
1438
gtkpod_tracks_statusbar_update();
1441
/* Reallow the coverart selection update */
1442
coverart_block_change (FALSE);
1443
/* Set the coverart display based on the selected playlist */
1444
coverart_set_images(TRUE);
1446
space_data_update ();
1412
1448
#if DEBUG_TIMING
1413
1449
g_get_current_time (&time);
1414
1450
printf ("pm_selection_changed_cb exit: %ld.%06ld sec\n",
1421
1457
/* Callback function called when the selection
1422
1458
of the playlist view has changed */
1423
/* Instead of handling the selection directly, we add a
1424
"callback". Currently running display updates will be stopped
1425
before the pm_selection_changed_cb is actually called */
1426
1459
static void pm_selection_changed (GtkTreeSelection *selection,
1427
1460
gpointer user_data)
1429
space_data_update ();
1430
1462
if (!pm_selection_blocked)
1431
add_selection_callback (-1, pm_selection_changed_cb,
1432
(gpointer)selection, user_data);
1463
pm_selection_changed_cb (selection, user_data);
1477
1508
for (gl_pl=itdb->playlists; gl_pl; gl_pl=gl_pl->next)
1479
Playlist *pl = gl_pl->data;
1480
g_return_if_fail (pl);
1481
if (itdb_playlist_is_mpl (pl)) pm_add_playlist (pl, pos);
1482
else pm_add_playlist (pl, -1);
1510
Playlist *pl = gl_pl->data;
1511
g_return_if_fail (pl);
1512
if (itdb_playlist_is_mpl (pl)) pm_add_playlist (pl, pos);
1513
else pm_add_playlist (pl, -1);
1487
1518
/* Helper function: add all playlists to playlist model */
1488
void pm_add_all_playlists (void)
1519
void pm_add_all_itdbs (void)
1490
1521
GList *gl_itdb;
1491
1522
struct itdbs_head *itdbs_head;
1506
/* Return path of playlist @pl. After use the return value must be
1507
* freed by calling gtk_tree_path_free() */
1508
GtkTreePath *pm_get_path (Playlist *pl)
1515
GtkTreeModel *model;
1516
struct userdata userdata;
1517
gboolean pm_get_path_fe (GtkTreeModel *model,
1522
struct userdata *ud = data;
1525
gtk_tree_model_get (model, iter,
1526
PM_COLUMN_PLAYLIST, &pl, -1);
1529
ud->path = gtk_tree_model_get_path (model, iter);
1534
g_return_val_if_fail (playlist_treeview, NULL);
1535
g_return_val_if_fail (pl, NULL);
1536
model = gtk_tree_view_get_model (playlist_treeview);
1537
g_return_val_if_fail (model, NULL);
1540
userdata.path = NULL;
1542
/* find the pl and fill in path */
1543
gtk_tree_model_foreach (model, pm_get_path_fe, &userdata);
1545
return userdata.path;
1537
/* Return GtkTreePath for playlist @playlist. The returned path must be
1538
freed using gtk_tree_path_free() after it is no needed any more */
1539
static GtkTreePath *pm_get_path_for_playlist (Playlist *playlist)
1543
g_return_val_if_fail (playlist_treeview, NULL);
1544
g_return_val_if_fail (playlist, NULL);
1546
if (pm_get_iter_for_playlist (playlist, &iter))
1548
GtkTreeModel *model;
1549
model = gtk_tree_view_get_model (playlist_treeview);
1550
return gtk_tree_model_get_path (model, &iter);
1556
/* Return GtkTreePath for repository @itdb. The returned path must be
1557
freed using gtk_tree_path_free() after it is no needed any more */
1558
GtkTreePath *pm_get_path_for_itdb (iTunesDB *itdb)
1562
g_return_val_if_fail (playlist_treeview, NULL);
1563
g_return_val_if_fail (itdb, NULL);
1565
if (pm_get_iter_for_itdb (itdb, &iter))
1567
GtkTreeModel *model;
1568
model = gtk_tree_view_get_model (playlist_treeview);
1569
return gtk_tree_model_get_path (model, &iter);
1575
/* Return position of repository @itdb */
1576
gint pm_get_position_for_itdb (iTunesDB *itdb)
1581
g_return_val_if_fail (playlist_treeview, -1);
1582
g_return_val_if_fail (itdb, -1);
1584
path = pm_get_path_for_itdb (itdb);
1588
gint *indices = gtk_tree_path_get_indices (path);
1591
position = indices[0];
1593
gtk_tree_path_free (path);
1599
/* Return position of repository @itdb */
1600
static gint pm_get_position_for_playlist (Playlist *playlist)
1605
g_return_val_if_fail (playlist_treeview, -1);
1606
g_return_val_if_fail (playlist, -1);
1608
path = pm_get_path_for_playlist (playlist);
1612
/* get position of current path */
1613
if (gtk_tree_path_get_depth (path) == 1)
1619
gint *indices = gtk_tree_path_get_indices (path);
1620
/* need to add 1 because MPL is one level higher and not
1622
position = indices[1] + 1;
1624
gtk_tree_path_free (path);
1550
1630
/* "unsort" the playlist view without causing the sort tabs to be
2184
2268
pm_drag_types, TGNR (pm_drag_types),
2185
2269
GDK_ACTION_COPY|GDK_ACTION_MOVE);
2186
2270
gtk_drag_dest_set (GTK_WIDGET (playlist_treeview),
2187
GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT,
2271
GTK_DEST_DEFAULT_HIGHLIGHT,
2188
2272
pm_drop_types, TGNR (pm_drop_types),
2189
2273
GDK_ACTION_COPY|GDK_ACTION_MOVE);