/* * Copyright 2016 (c) Anna Schumaker. */ #include #include #include static const GTypeInfo queue_type_info; static const GInterfaceInfo queue_tree_model; static GObjectClass *parent_class = NULL; static GType queue_columns[Q_MODEL_N_COLUMNS] = { [Q_MODEL_TRACK_NR] = G_TYPE_UINT, [Q_MODEL_TITLE] = G_TYPE_STRING, [Q_MODEL_LENGTH] = G_TYPE_STRING, [Q_MODEL_ARTIST] = G_TYPE_STRING, [Q_MODEL_ALBUM] = G_TYPE_STRING, [Q_MODEL_YEAR] = G_TYPE_UINT, [Q_MODEL_GENRE] = G_TYPE_STRING, [Q_MODEL_COUNT] = G_TYPE_UINT, [Q_MODEL_LAST_PLAY] = G_TYPE_STRING, [Q_MODEL_FILE_PATH] = G_TYPE_STRING, }; static GtkTreeModelFlags _queue_model_get_flags(GtkTreeModel *model) { return GTK_TREE_MODEL_LIST_ONLY; } static gint _queue_model_get_n_columns(GtkTreeModel *model) { return Q_MODEL_N_COLUMNS; } static GType _queue_model_get_column_type(GtkTreeModel *model, gint index) { g_return_val_if_fail(index >= 0 && index < Q_MODEL_N_COLUMNS, G_TYPE_INVALID); return queue_columns[index]; } static gboolean _queue_model_get_iter(GtkTreeModel *model, GtkTreeIter *iter, GtkTreePath *path) { GuiQueueModel *gqm = GUI_QUEUE_MODEL(model); gint *indices, depth; g_assert(path != NULL); indices = gtk_tree_path_get_indices_with_depth(path, &depth); g_assert(depth == 1); if (indices[0] >= queue_size(gqm->gqm_queue)) return FALSE; _q_iter_set(&gqm->gqm_queue->q_tracks, &gqm->gqm_iter, indices[0]); iter->stamp = gqm->gqm_stamp; iter->user_data = &gqm->gqm_iter; iter->user_data2 = _q_iter_val(&gqm->gqm_iter); return TRUE; } static GtkTreePath *_queue_model_get_path(GtkTreeModel *model, GtkTreeIter *iter) { struct _q_iter *q_it; GtkTreePath *path; g_return_val_if_fail(iter != NULL, FALSE); g_return_val_if_fail(iter->user_data, FALSE); g_return_val_if_fail(iter->user_data2, FALSE); q_it = iter->user_data; path = gtk_tree_path_new(); gtk_tree_path_append_index(path, q_it->it_pos); return path; } static void _queue_model_get_value(GtkTreeModel *model, GtkTreeIter *iter, gint column, GValue *value) { struct track *track = iter->user_data2; gchar *str; g_return_if_fail(iter != NULL); g_return_if_fail(iter->user_data2 != NULL); g_return_if_fail(column < Q_MODEL_N_COLUMNS); g_value_init(value, queue_columns[column]); switch (column) { case Q_MODEL_TRACK_NR: g_value_set_uint(value, track->tr_track); break; case Q_MODEL_TITLE: g_value_set_static_string(value, track->tr_title); break; case Q_MODEL_LENGTH: g_value_take_string(value, string_sec2str(track->tr_length)); break; case Q_MODEL_ARTIST: g_value_set_static_string(value, track->tr_artist->ar_name); break; case Q_MODEL_ALBUM: g_value_set_static_string(value, track->tr_album->al_name); break; case Q_MODEL_YEAR: g_value_set_uint(value, track->tr_album->al_year); break; case Q_MODEL_GENRE: g_value_set_static_string(value, track->tr_genre->ge_name); break; case Q_MODEL_COUNT: g_value_set_uint(value, track->tr_count); break; case Q_MODEL_LAST_PLAY: g_value_take_string(value, track_last_play(track)); break; case Q_MODEL_FILE_PATH: str = track_path(track); g_value_take_string(value, g_markup_escape_text(str, -1)); g_free(str); break; } } static void _queue_model_init(GuiQueueModel *model) { model->gqm_stamp = g_random_int(); } static void _queue_model_finalize(GObject *object) { parent_class->finalize(object); } static void _queue_model_class_init(GuiQueueModelClass *class) { GObjectClass *object_class; parent_class = g_type_class_peek_parent(class); object_class = (GObjectClass *)class; object_class->finalize = _queue_model_finalize; } static void _queue_tree_model_init(GtkTreeModelIface *iface) { iface->get_flags = _queue_model_get_flags; iface->get_n_columns = _queue_model_get_n_columns; iface->get_column_type = _queue_model_get_column_type; iface->get_iter = _queue_model_get_iter; iface->get_path = _queue_model_get_path; iface->get_value = _queue_model_get_value; } GuiQueueModel *gui_queue_model_new(struct queue *queue) { GuiQueueModel *model = g_object_new(GUI_QUEUE_MODEL_TYPE, NULL); g_assert(model != NULL); model->gqm_queue = queue; return model; } GType gui_queue_model_get_type() { static GType queue_type = 0; if (queue_type == 0) { queue_type = g_type_register_static(G_TYPE_OBJECT, "GuiQueueModel", &queue_type_info, (GTypeFlags)0); g_type_add_interface_static(queue_type, GTK_TYPE_TREE_MODEL, &queue_tree_model); } return queue_type; } static const GTypeInfo queue_type_info = { .class_size = sizeof(GuiQueueModelClass), .base_init = NULL, .base_finalize = NULL, .class_init = (GClassInitFunc)_queue_model_class_init, .class_finalize = NULL, .class_data = NULL, .instance_size = sizeof(GuiQueueModel), .n_preallocs = 0, .instance_init = (GInstanceInitFunc)_queue_model_init, }; static const GInterfaceInfo queue_tree_model = { .interface_init = (GInterfaceInitFunc)_queue_tree_model_init, .interface_finalize = NULL, .interface_data = NULL, };