/* * Copyright 2014 (c) Anna Schumaker. * * See the example at: * https://git.gnome.org/browse/gtkmm-documentation/tree/examples/others/treemodelcustom */ #include extern "C" { #include } #include #include QueueModel::QueueModel(queue *q) : Glib::ObjectBase( typeid(QueueModel) ), Glib::Object(), _stamp(1), _queue(q) { } void QueueModel::increment_stamp() { if (++_stamp == 0) ++_stamp; } bool QueueModel::check_iter_validity(const Gtk::TreeIter &iter) const { return _stamp == iter.get_stamp(); } void QueueModel::on_row_inserted(unsigned int row) { increment_stamp(); row_inserted(Gtk::TreePath(1, row), Gtk::TreeIter()); } void QueueModel::on_row_deleted(unsigned int row) { increment_stamp(); row_deleted(Gtk::TreePath(1, row)); } void QueueModel::on_cleared(unsigned int n) { increment_stamp(); for (unsigned int i = 1; i <= n; i++) row_deleted(Gtk::TreePath(1, n - i)); } void QueueModel::on_row_changed(unsigned int row) { increment_stamp(); row_changed(Gtk::TreePath(1, row), Gtk::TreeIter()); } void QueueModel::on_path_selected(const Gtk::TreePath &path) { audio_load(track_get(path_to_id(path))); queue_selected(_queue, path[0]); audio :: play(); } unsigned int QueueModel :: iter_to_id(const Gtk::TreeIter &iter) const { return GPOINTER_TO_UINT(iter.gobj()->user_data); } unsigned int QueueModel::path_to_id(const Gtk::TreePath &path) const { return queue_at(_queue, path[0])->tr_dbe.dbe_index; } Gtk::TreeModelFlags QueueModel::get_flags_vfunc() const { return Gtk::TREE_MODEL_LIST_ONLY; } int QueueModel::get_n_columns_vfunc() const { return 10; } GType QueueModel::get_column_type_vfunc(int index) const { if (index > 9) return 0; if (index == 0 || index == 5 || index == 7) return G_TYPE_UINT; return G_TYPE_STRING; } template static void set_val(const T &t, Glib::ValueBase &value) { Glib::Value specific; specific.init(Glib::Value::value_type()); specific.set(t); value.init(specific.gobj()); } void QueueModel::get_value_vfunc(const Gtk::TreeIter &iter, int column, Glib::ValueBase &value) const { struct track *track; std::string field; gchar *str; if (!check_iter_validity(iter) || column > get_n_columns_vfunc()) return; track = queue_at(_queue, iter_to_id(iter)); switch (column) { case 0: return set_val(track->tr_track, value); case 1: field = track->tr_title; return set_val(field, value); case 2: str = string_sec2str(track->tr_length); set_val(Glib::ustring(str), value); g_free(str); return; case 3: field = track->tr_artist->ar_name; return set_val(field, value); case 4: field = track->tr_album->al_name; return set_val(field, value); case 5: return set_val(track->tr_album->al_year, value); case 6: field = track->tr_genre->ge_name; return set_val(field, value); case 7: return set_val(track->tr_count, value); case 8: str = track_last_play(track); set_val(Glib::Markup::escape_text(str), value); g_free(str); return; case 9: str = track_path(track); set_val(Glib::Markup::escape_text(str), value); g_free(str); return; } } bool QueueModel::iter_next_vfunc(const Gtk::TreeIter &iter, Gtk::TreeIter &next) const { next = Gtk::TreeIter(); if (check_iter_validity(iter)) return iter_nth_root_child_vfunc(iter_to_id(iter) + 1, next); return false; } int QueueModel::iter_n_root_children_vfunc() const { return queue_size(_queue); } bool QueueModel::iter_nth_root_child_vfunc(int n, Gtk::TreeIter &iter) const { iter = Gtk::TreeIter(); if (n >= (int)queue_size(_queue)) return false; iter.set_stamp(_stamp); iter.gobj()->user_data = GUINT_TO_POINTER(n); return true; } Gtk::TreeModel::Path QueueModel::get_path_vfunc(const Gtk::TreeIter &iter) const { Gtk::TreeModel::Path path; if (check_iter_validity(iter)) path.push_back(iter_to_id(iter)); return path; } bool QueueModel::get_iter_vfunc(const Gtk::TreePath &path, Gtk::TreeIter &iter) const { iter = Gtk::TreeIter(); if (path.size() == 1) return iter_nth_root_child_vfunc(path[0], iter); return false; }