ocarina/gui/model.cpp

285 lines
5.3 KiB
C++

/*
* Copyright 2014 (c) Anna Schumaker.
*
* See the example at:
* https://git.gnome.org/browse/gtkmm-documentation/tree/examples/others/treemodelcustom
*/
#include <core/audio.h>
#include <gui/ocarina.h>
#include <stdlib.h>
#include <sstream>
QueueModel::QueueModel(Queue *q)
: Glib::ObjectBase( typeid(QueueModel) ),
Glib::Object(), queue(q)
{
do {
stamp = rand();
} while (stamp == 0);
}
void QueueModel::increment_stamp()
{
do {
stamp++;
} while (stamp == 0);
}
void QueueModel::on_row_inserted(unsigned int row)
{
Gtk::TreePath path;
Gtk::TreeIter iter;
path.push_back(row);
increment_stamp();
row_inserted(path, iter);
}
void QueueModel::on_row_deleted(unsigned int row)
{
Gtk::TreePath path;
path.push_back(row);
increment_stamp();
row_deleted(path);
}
void QueueModel::on_row_changed(unsigned int row)
{
Gtk::TreePath path;
Gtk::TreeIter iter;
path.push_back(row);
increment_stamp();
row_changed(path, iter);
}
void QueueModel::on_path_selected(const Gtk::TreePath &path)
{
audio :: load_track(tagdb :: lookup(path_to_id(path)));
queue->track_selected(path[0]);
audio :: play();
}
unsigned int QueueModel :: iter_to_id(const Gtk::TreeIter &iter)
{
return GPOINTER_TO_UINT(iter.gobj()->user_data);
}
unsigned int QueueModel::path_to_id(const Gtk::TreePath &path)
{
return queue->operator[](path[0])->id;
}
/*
*
* Function overrides begin here
*
*/
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
{
switch (index) {
case 0:
case 5:
case 7:
return G_TYPE_UINT;
case 1:
case 2:
case 3:
case 4:
case 6:
case 8:
case 9:
return G_TYPE_STRING;
default:
return 0;
}
}
void QueueModel::get_value_uint(Track *track, int column,
Glib::ValueBase &value) const
{
Glib::Value<unsigned int> specific;
specific.init(Glib::Value<unsigned int>::value_type());
switch (column) {
case 0:
specific.set(track->track);
break;
case 5:
specific.set(track->album->year);
break;
case 7:
specific.set(track->play_count);
}
value.init(Glib::Value<unsigned int>::value_type());
value = specific;
}
void QueueModel::get_value_str(Track *track, int column,
Glib::ValueBase &value) const
{
std::stringstream ss;
Glib::Value<std::string> specific;
specific.init(Glib::Value<std::string>::value_type());
switch (column) {
case 1:
specific.set(track->title);
break;
case 2:
specific.set(track->length_str);
break;
case 3:
specific.set(track->artist->name);
break;
case 4:
specific.set(track->album->name);
break;
case 6:
specific.set(track->genre->name);
break;
case 8:
if (track->play_count == 0)
specific.set("Never");
else {
ss << track->last_month << " / ";
ss << track->last_day << " / ";
ss << track->last_year;
specific.set(ss.str());
}
break;
case 9:
specific.set(Glib::Markup::escape_text(track->path()));
}
value.init(Glib::Value<std::string>::value_type());
value = specific;
}
void QueueModel::get_value_vfunc(const Gtk::TreeIter &iter, int column,
Glib::ValueBase &value) const
{
unsigned int row;
Track *track;
if (!check_iter_validity(iter))
return;
if (column > get_n_columns_vfunc())
return;
row = GPOINTER_TO_UINT(iter.gobj()->user_data);
track = queue->operator[](row);
switch (column) {
case 0:
case 5:
case 7:
get_value_uint(track, column, value);
break;
default:
get_value_str(track, column, value);
}
}
bool QueueModel::iter_next_vfunc(const Gtk::TreeIter &iter,
Gtk::TreeIter &iter_next) const
{
unsigned int index;
if (!check_iter_validity(iter)) {
iter_next = Gtk::TreeIter();
return false;
}
index = GPOINTER_TO_UINT(iter.gobj()->user_data);
return iter_nth_root_child_vfunc(++index, iter_next);
}
bool QueueModel::iter_children_vfunc(const Gtk::TreeIter &parent,
Gtk::TreeIter &iter) const
{
return iter_nth_child_vfunc(parent, 0, iter);
}
bool QueueModel::iter_has_child_vfunc(const Gtk::TreeIter &iter) const
{
return (iter_n_children_vfunc(iter) > 0);
}
int QueueModel::iter_n_children_vfunc(const Gtk::TreeIter &iter) const
{
return 0;
}
int QueueModel::iter_n_root_children_vfunc() const
{
return queue->size();
}
bool QueueModel::iter_nth_child_vfunc(const Gtk::TreeIter &parent,
int n, Gtk::TreeIter &iter) const
{
iter = Gtk::TreeIter();
return false;
}
bool QueueModel::iter_nth_root_child_vfunc(int n, Gtk::TreeIter &iter) const
{
iter = Gtk::TreeIter();
if (n >= (int)queue->size())
return false;
iter.set_stamp(stamp);
iter.gobj()->user_data = GUINT_TO_POINTER(n);
return true;
}
bool QueueModel::iter_parent_vfunc(const Gtk::TreeIter &child,
Gtk::TreeIter &iter) const
{
iter = Gtk::TreeIter();
return false;
}
Gtk::TreeModel::Path QueueModel::get_path_vfunc(const Gtk::TreeIter &iter) const
{
Gtk::TreeModel::Path path;
if (check_iter_validity(iter))
path.push_back(GPOINTER_TO_UINT(iter.gobj()->user_data));
return path;
}
bool QueueModel::get_iter_vfunc(const Gtk::TreePath &path,
Gtk::TreeIter &iter) const
{
if (path.size() != 1) {
iter = Gtk::TreeIter();
return false;
}
return iter_nth_root_child_vfunc(path[0], iter);
}
bool QueueModel::check_iter_validity(const Gtk::TreeIter &iter) const
{
return stamp == iter.get_stamp();
}