17
17
* You should have received a copy of the GNU General Public License
18
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
133
133
RhythmDBQueryModel *playing_model;
134
134
RhythmDBEntry *playing_entry;
135
135
gboolean playing_entry_in_view;
136
guint selection_changed_id;
137
138
gboolean is_drag_source;
138
139
gboolean is_drag_dest;
141
GdkPixbuf *playing_col_pixbuf;
140
142
GdkPixbuf *playing_pixbuf;
141
143
GdkPixbuf *paused_pixbuf;
142
144
GdkPixbuf *error_pixbuf;
195
199
RhythmDBEntry *entry;
201
const gchar *entry_folded;
199
204
gtk_tree_model_get (model, iter, 0, &entry, -1);
200
205
folded = rb_search_fold (key);
201
res = (strstr (rb_refstring_get_folded (entry->title), folded) == NULL);
206
entry_folded = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE_FOLDED);
207
res = (strstr (entry_folded, folded) == NULL);
323
329
G_SIGNAL_RUN_LAST,
324
330
G_STRUCT_OFFSET (RBEntryViewClass, show_popup),
326
g_cclosure_marshal_VOID__VOID,
332
g_cclosure_marshal_VOID__BOOLEAN,
329
336
rb_entry_view_signals[HAVE_SEL_CHANGED] =
330
337
g_signal_new ("have_selection_changed",
331
338
G_OBJECT_CLASS_TYPE (object_class),
400
415
g_hash_table_destroy (view->priv->column_sort_data_map);
401
416
g_hash_table_destroy (view->priv->column_key_map);
403
g_object_unref (G_OBJECT (view->priv->playing_pixbuf));
404
g_object_unref (G_OBJECT (view->priv->paused_pixbuf));
405
g_object_unref (G_OBJECT (view->priv->error_pixbuf));
418
if (view->priv->playing_pixbuf)
419
g_object_unref (G_OBJECT (view->priv->playing_pixbuf));
420
if (view->priv->playing_col_pixbuf)
421
g_object_unref (G_OBJECT (view->priv->playing_col_pixbuf));
422
if (view->priv->paused_pixbuf)
423
g_object_unref (G_OBJECT (view->priv->paused_pixbuf));
424
if (view->priv->error_pixbuf)
425
g_object_unref (G_OBJECT (view->priv->error_pixbuf));
407
427
g_free (view->priv->sorting_key);
474
495
gtk_tree_view_set_model (GTK_TREE_VIEW (view->priv->treeview),
475
496
GTK_TREE_MODEL (new_model));
476
497
view->priv->have_selection = FALSE;
498
view->priv->have_complete_selection = FALSE;
478
500
g_signal_emit (G_OBJECT (view), rb_entry_view_signals[ENTRIES_REPLACED], 0);
575
597
RBEntryView *view)
577
599
RhythmDBEntry *entry;
600
GdkPixbuf *pixbuf = NULL;
580
602
entry = rhythmdb_query_model_iter_to_entry (view->priv->model, iter);
582
604
if (entry == view->priv->playing_entry) {
583
605
switch (view->priv->playing_state) {
584
case RB_ENTRY_VIEW_PLAYING:
606
case RB_ENTRY_VIEW_PLAYING:
585
607
pixbuf = view->priv->playing_pixbuf;
587
609
case RB_ENTRY_VIEW_PAUSED:
610
632
entry = rhythmdb_query_model_iter_to_entry (view->priv->model, iter);
612
g_object_set (G_OBJECT (renderer), "rating", entry->rating, NULL);
634
g_object_set (G_OBJECT (renderer),
635
"rating", rhythmdb_entry_get_double (entry, RHYTHMDB_PROP_RATING),
709
732
entry = rhythmdb_query_model_iter_to_entry (data->view->priv->model, iter);
711
bitrate = rhythmdb_entry_get_int (data->view->priv->db, entry,
734
bitrate = rhythmdb_entry_get_ulong (entry, data->propid);
737
char *s = g_strdup_printf (_("%u kbps"), (guint)bitrate);
738
g_object_set (G_OBJECT (renderer), "text", s, NULL);
715
741
g_object_set (G_OBJECT (renderer), "text", _("Unknown"), NULL);
716
} else if (bitrate <= 80) {
717
g_object_set (G_OBJECT (renderer), "text", _("Very Low"), NULL);
718
} else if (bitrate <= 112) {
719
g_object_set (G_OBJECT (renderer), "text", _("Low"), NULL);
720
} else if (bitrate <= 160) {
721
g_object_set (G_OBJECT (renderer), "text", _("Regular"), NULL);
722
} else if (bitrate <= 224) {
723
g_object_set (G_OBJECT (renderer), "text", _("High"), NULL);
724
} else if (bitrate <= 1410) {
725
g_object_set (G_OBJECT (renderer), "text", _("Very High"), NULL);
727
g_object_set (G_OBJECT (renderer), "text", _("Perfect"), NULL);
746
rb_entry_view_location_cell_data_func (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
747
GtkTreeModel *tree_model, GtkTreeIter *iter,
748
struct RBEntryViewCellDataFuncData *data)
750
RhythmDBEntry *entry;
751
const char *location;
754
entry = rhythmdb_query_model_iter_to_entry (data->view->priv->model, iter);
756
location = rhythmdb_entry_get_string (entry, data->propid);
757
str = gnome_vfs_unescape_string_for_display (location);
759
g_object_set (G_OBJECT (renderer), "text", str, NULL);
733
764
rb_entry_view_string_cell_data_func (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
1046
1076
strings[0] = title;
1047
1077
strings[1] = rb_entry_view_get_time_date_column_sample ();
1079
case RB_ENTRY_VIEW_COL_LAST_SEEN:
1080
propid = RHYTHMDB_PROP_LAST_SEEN;
1081
cell_data->propid = RHYTHMDB_PROP_LAST_SEEN_STR;
1082
cell_data_func = (GtkTreeCellDataFunc) rb_entry_view_string_cell_data_func;
1083
sort_propid = RHYTHMDB_PROP_LAST_SEEN;
1084
sort_func = (GCompareDataFunc) rhythmdb_query_model_ulong_sort_func;
1085
title = _("Last _Seen");
1088
strings[1] = rb_entry_view_get_time_date_column_sample ();
1090
case RB_ENTRY_VIEW_COL_LOCATION:
1091
propid = RHYTHMDB_PROP_LOCATION;
1092
cell_data->propid = RHYTHMDB_PROP_LOCATION;
1093
cell_data_func = (GtkTreeCellDataFunc) rb_entry_view_location_cell_data_func;
1094
sort_propid = RHYTHMDB_PROP_LOCATION;
1095
sort_func = (GCompareDataFunc) rhythmdb_query_model_location_sort_func;
1096
title = _("L_ocation");
1100
case RB_ENTRY_VIEW_COL_ERROR:
1101
propid = RHYTHMDB_PROP_PLAYBACK_ERROR;
1102
cell_data->propid = RHYTHMDB_PROP_PLAYBACK_ERROR;
1103
cell_data_func = (GtkTreeCellDataFunc) rb_entry_view_string_cell_data_func;
1050
1109
g_assert_not_reached ();
1082
1141
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
1083
1142
gtk_tree_view_column_set_clickable (column, TRUE);
1145
g_object_set_qdata (G_OBJECT (column),
1146
rb_entry_view_column_always_visible,
1147
GINT_TO_POINTER (1));
1085
1149
g_hash_table_insert (view->priv->propid_column_map, GINT_TO_POINTER (propid), column);
1086
rb_entry_view_append_column_custom (view, column, title, key, sort_func, sort_propid);
1151
rb_entry_view_append_column_custom (view, column, title, key, sort_func, GINT_TO_POINTER (sort_propid));
1113
1178
if (sort_func != NULL) {
1114
1179
sortdata = g_new (struct RBEntryViewColumnSortData, 1);
1115
1180
sortdata->func = (GCompareDataFunc) sort_func;
1116
sortdata->prop_id = sort_prop_id;
1181
sortdata->data = data;
1117
1182
g_hash_table_insert (view->priv->column_sort_data_map, column, sortdata);
1119
1184
g_hash_table_insert (view->priv->column_key_map, g_strdup (key), column);
1186
1251
GDK_BUTTON1_MASK,
1187
1252
rb_entry_view_drag_types,
1188
1253
G_N_ELEMENTS (rb_entry_view_drag_types),
1189
GDK_ACTION_COPY | GDK_ACTION_MOVE);
1190
1255
if (view->priv->is_drag_dest)
1191
1256
rb_tree_dnd_add_drag_dest_support (GTK_TREE_VIEW (view->priv->treeview),
1192
1257
RB_TREE_DEST_CAN_DROP_BETWEEN | RB_TREE_DEST_EMPTY_VIEW_DROP,
1300
1366
gtk_tree_path_free (path);
1302
if (entry->playback_error) {
1303
rb_error_dialog (NULL, _("Playback Error"),
1304
"%s", entry->playback_error);
1368
error = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_PLAYBACK_ERROR);
1370
rb_error_dialog (NULL, _("Playback Error"), "%s", error);
1316
1382
g_return_if_fail (RB_IS_ENTRY_VIEW (view));
1318
if (view->priv->playing_state == RB_ENTRY_VIEW_NOT_PLAYING)
1321
if (view->priv->playing_entry != NULL) {
1322
rb_entry_view_emit_row_changed (view, view->priv->playing_entry);
1323
g_object_unref (G_OBJECT (view->priv->playing_model));
1384
if (view->priv->playing_entry != NULL) {
1385
if (view->priv->playing_state != RB_ENTRY_VIEW_NOT_PLAYING)
1386
rb_entry_view_emit_row_changed (view, view->priv->playing_entry);
1387
g_object_unref (G_OBJECT (view->priv->playing_model));
1326
1390
view->priv->playing_entry = entry;
1327
1391
g_object_ref (G_OBJECT (view->priv->model));
1328
1392
view->priv->playing_model = view->priv->model;
1330
if (view->priv->playing_entry != NULL) {
1331
view->priv->playing_entry_in_view =
1332
rb_entry_view_emit_row_changed (view, view->priv->playing_entry);
1335
if (view->priv->playing_entry
1336
&& view->priv->playing_entry_in_view) {
1337
rb_entry_view_entry_is_visible (view, view->priv->playing_entry,
1338
&realized, &visible, &iter);
1339
if (realized && !visible)
1340
rb_entry_view_scroll_to_iter (view, &iter);
1394
if (view->priv->playing_state != RB_ENTRY_VIEW_NOT_PLAYING) {
1395
if (view->priv->playing_entry != NULL) {
1396
view->priv->playing_entry_in_view =
1397
rb_entry_view_emit_row_changed (view, view->priv->playing_entry);
1400
if (view->priv->playing_entry
1401
&& view->priv->playing_entry_in_view) {
1402
rb_entry_view_entry_is_visible (view, view->priv->playing_entry,
1403
&realized, &visible, &iter);
1404
if (realized && !visible)
1405
rb_entry_view_scroll_to_iter (view, &iter);
1344
1410
static gboolean
1413
rb_entry_view_selection_changed_cb (GtkTreeSelection *selection,
1480
rb_entry_view_emit_selection_changed (RBEntryView *view)
1416
1482
gboolean available;
1419
sel = rb_entry_view_get_selected_entries (view);
1420
available = (sel != NULL);
1485
sel_count = gtk_tree_selection_count_selected_rows (view->priv->selection);
1486
available = (sel_count > 0);
1423
1488
if (available != view->priv->have_selection) {
1491
entry_count = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (view->priv->model), NULL);
1492
view->priv->have_complete_selection = (sel_count == entry_count);
1424
1494
view->priv->have_selection = available;
1426
1496
g_signal_emit (G_OBJECT (view), rb_entry_view_signals[HAVE_SEL_CHANGED], 0, available);
1499
view->priv->selection_changed_id = 0;
1429
1500
g_signal_emit (G_OBJECT (view), rb_entry_view_signals[SELECTION_CHANGED], 0);
1505
rb_entry_view_selection_changed_cb (GtkTreeSelection *selection,
1508
if (view->priv->selection_changed_id == 0)
1509
view->priv->selection_changed_id = g_idle_add ((GSourceFunc)rb_entry_view_emit_selection_changed, view);
1506
1593
if (order[newindex] == index) {
1507
1594
newpath = gtk_tree_path_new_from_indices (newindex, -1);
1508
1595
gtk_tree_selection_select_path (view->priv->selection, newpath);
1597
GtkTreeViewColumn *col;
1598
GtkTreeView *treeview = GTK_TREE_VIEW (view->priv->treeview);
1600
col = gtk_tree_view_get_column (treeview, 0);
1601
gtk_tree_view_scroll_to_cell (treeview, newpath, col, TRUE, 0.5, 0.0);
1509
1604
gtk_tree_path_free (newpath);
1701
1798
gboolean visible;
1703
/* title is always visible */
1704
if (propid == RHYTHMDB_PROP_TITLE)
1800
if (g_object_get_qdata (G_OBJECT (column),
1801
rb_entry_view_column_always_visible) == GINT_TO_POINTER (1))
1804
visible = (g_list_find (visible_props, GINT_TO_POINTER (propid)) != NULL);
1707
visible = (g_list_find (visible_props, GINT_TO_POINTER (propid)) != NULL);
1708
1806
gtk_tree_view_column_set_visible (column, visible);
1842
1940
rhythmdb_query_model_set_sort_order (view->priv->model,
1843
1941
sort_data->func,
1845
1944
(view->priv->sorting_order == GTK_SORT_DESCENDING));
1947
/* This should really be standard. */
1948
#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
1951
rb_entry_view_column_get_type (void)
1953
static GType etype = 0;
1956
static const GEnumValue values[] = {
1957
ENUM_ENTRY (RB_ENTRY_VIEW_COL_TRACK_NUMBER, "Track Number"),
1958
ENUM_ENTRY (RB_ENTRY_VIEW_COL_TITLE, "Title"),
1959
ENUM_ENTRY (RB_ENTRY_VIEW_COL_ARTIST, "Artist"),
1960
ENUM_ENTRY (RB_ENTRY_VIEW_COL_ALBUM, "Album"),
1961
ENUM_ENTRY (RB_ENTRY_VIEW_COL_GENRE, "Genre"),
1962
ENUM_ENTRY (RB_ENTRY_VIEW_COL_DURATION, "Duration"),
1963
ENUM_ENTRY (RB_ENTRY_VIEW_COL_QUALITY, "Quality"),
1964
ENUM_ENTRY (RB_ENTRY_VIEW_COL_RATING, "Rating"),
1965
ENUM_ENTRY (RB_ENTRY_VIEW_COL_PLAY_COUNT, "Play Count"),
1966
ENUM_ENTRY (RB_ENTRY_VIEW_COL_YEAR, "Year"),
1967
ENUM_ENTRY (RB_ENTRY_VIEW_COL_LAST_PLAYED, "Last Played"),
1968
ENUM_ENTRY (RB_ENTRY_VIEW_COL_FIRST_SEEN, "First Seen"),
1969
ENUM_ENTRY (RB_ENTRY_VIEW_COL_LAST_SEEN, "Last Seen"),
1970
ENUM_ENTRY (RB_ENTRY_VIEW_COL_LOCATION, "Location"),
1971
ENUM_ENTRY (RB_ENTRY_VIEW_COL_ERROR, "Error"),
1975
etype = g_enum_register_static ("RBEntryViewColumn", values);
1982
rb_entry_view_state_get_type (void)
1984
static GType etype = 0;
1987
static const GEnumValue values[] = {
1988
ENUM_ENTRY (RB_ENTRY_VIEW_NOT_PLAYING, "Not Playing"),
1989
ENUM_ENTRY (RB_ENTRY_VIEW_PLAYING, "Playing"),
1990
ENUM_ENTRY (RB_ENTRY_VIEW_PAUSED, "Paused"),
1994
etype = g_enum_register_static ("RBEntryViewState", values);