285 lines
5.5 KiB
C++
285 lines
5.5 KiB
C++
/*
|
|
* Copyright 2014 (c) Anna Schumaker.
|
|
*
|
|
* See the example at:
|
|
* https://git.gnome.org/browse/gtkmm-documentation/tree/examples/others/treemodelcustom
|
|
*/
|
|
#include <audio.h>
|
|
#include <ocarina.h>
|
|
#include <stdlib.h>
|
|
#include <sstream>
|
|
|
|
|
|
PlayqueueModel::PlayqueueModel(Playqueue *q)
|
|
: Glib::ObjectBase( typeid(PlayqueueModel) ),
|
|
Glib::Object(), queue(q)
|
|
{
|
|
do {
|
|
stamp = rand();
|
|
} while (stamp == 0);
|
|
}
|
|
|
|
void PlayqueueModel::increment_stamp()
|
|
{
|
|
do {
|
|
stamp++;
|
|
} while (stamp == 0);
|
|
}
|
|
|
|
void PlayqueueModel::on_row_inserted(unsigned int row)
|
|
{
|
|
Gtk::TreePath path;
|
|
Gtk::TreeIter iter;
|
|
|
|
path.push_back(row);
|
|
increment_stamp();
|
|
row_inserted(path, iter);
|
|
}
|
|
|
|
void PlayqueueModel::on_row_deleted(unsigned int row)
|
|
{
|
|
Gtk::TreePath path;
|
|
|
|
path.push_back(row);
|
|
increment_stamp();
|
|
row_deleted(path);
|
|
}
|
|
|
|
void PlayqueueModel::on_row_changed(unsigned int row)
|
|
{
|
|
Gtk::TreePath path;
|
|
Gtk::TreeIter iter;
|
|
|
|
path.push_back(row);
|
|
increment_stamp();
|
|
row_changed(path, iter);
|
|
}
|
|
|
|
void PlayqueueModel::on_path_selected(const Gtk::TreePath &path)
|
|
{
|
|
audio :: load_trackid(path_to_id(path));
|
|
queue->path_selected(path[0]);
|
|
audio :: play();
|
|
}
|
|
|
|
unsigned int PlayqueueModel :: iter_to_id(const Gtk::TreeIter &iter)
|
|
{
|
|
return GPOINTER_TO_UINT(iter.gobj()->user_data);
|
|
}
|
|
|
|
unsigned int PlayqueueModel::path_to_id(const Gtk::TreePath &path)
|
|
{
|
|
return queue->operator[](path[0]);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
*
|
|
* Function overrides begin here
|
|
*
|
|
*/
|
|
|
|
Gtk::TreeModelFlags PlayqueueModel::get_flags_vfunc() const
|
|
{
|
|
return Gtk::TREE_MODEL_LIST_ONLY;
|
|
}
|
|
|
|
int PlayqueueModel::get_n_columns_vfunc() const
|
|
{
|
|
return 10;
|
|
}
|
|
|
|
GType PlayqueueModel::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 PlayqueueModel::get_value_uint(struct library::Song &song, 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(song.track->track);
|
|
break;
|
|
case 5:
|
|
specific.set(song.album->year);
|
|
break;
|
|
case 7:
|
|
specific.set(song.track->play_count);
|
|
}
|
|
|
|
value.init(Glib::Value<unsigned int>::value_type());
|
|
value = specific;
|
|
}
|
|
|
|
void PlayqueueModel::get_value_str(struct library::Song &song, 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(song.track->title);
|
|
break;
|
|
case 2:
|
|
specific.set(song.track->length_str);
|
|
break;
|
|
case 3:
|
|
specific.set(song.artist->primary_key);
|
|
break;
|
|
case 4:
|
|
specific.set(song.album->name);
|
|
break;
|
|
case 6:
|
|
specific.set(song.genre->primary_key);
|
|
break;
|
|
case 8:
|
|
if (song.track->play_count == 0)
|
|
specific.set("Never");
|
|
else {
|
|
ss << song.track->last_month << " / ";
|
|
ss << song.track->last_day << " / ";
|
|
ss << song.track->last_year;
|
|
specific.set(ss.str());
|
|
}
|
|
break;
|
|
case 9:
|
|
specific.set(Glib::Markup::escape_text(song.track->primary_key));
|
|
}
|
|
|
|
value.init(Glib::Value<std::string>::value_type());
|
|
value = specific;
|
|
|
|
}
|
|
|
|
void PlayqueueModel::get_value_vfunc(const Gtk::TreeIter &iter, int column,
|
|
Glib::ValueBase &value) const
|
|
{
|
|
unsigned int row;
|
|
struct library::Song song;
|
|
|
|
if (!check_iter_validity(iter))
|
|
return;
|
|
|
|
if (column > get_n_columns_vfunc())
|
|
return;
|
|
|
|
row = GPOINTER_TO_UINT(iter.gobj()->user_data);
|
|
library :: lookup((*queue)[row], &song);
|
|
|
|
switch (column) {
|
|
case 0:
|
|
case 5:
|
|
case 7:
|
|
get_value_uint(song, column, value);
|
|
break;
|
|
default:
|
|
get_value_str(song, column, value);
|
|
}
|
|
}
|
|
|
|
bool PlayqueueModel::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 PlayqueueModel::iter_children_vfunc(const Gtk::TreeIter &parent,
|
|
Gtk::TreeIter &iter) const
|
|
{
|
|
return iter_nth_child_vfunc(parent, 0, iter);
|
|
}
|
|
|
|
bool PlayqueueModel::iter_has_child_vfunc(const Gtk::TreeIter &iter) const
|
|
{
|
|
return (iter_n_children_vfunc(iter) > 0);
|
|
}
|
|
|
|
int PlayqueueModel::iter_n_children_vfunc(const Gtk::TreeIter &iter) const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int PlayqueueModel::iter_n_root_children_vfunc() const
|
|
{
|
|
return queue->size();
|
|
}
|
|
|
|
bool PlayqueueModel::iter_nth_child_vfunc(const Gtk::TreeIter &parent,
|
|
int n, Gtk::TreeIter &iter) const
|
|
{
|
|
iter = Gtk::TreeIter();
|
|
return false;
|
|
}
|
|
|
|
bool PlayqueueModel::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 PlayqueueModel::iter_parent_vfunc(const Gtk::TreeIter &child,
|
|
Gtk::TreeIter &iter) const
|
|
{
|
|
iter = Gtk::TreeIter();
|
|
return false;
|
|
}
|
|
|
|
Gtk::TreeModel::Path PlayqueueModel::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 PlayqueueModel::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 PlayqueueModel::check_iter_validity(const Gtk::TreeIter &iter) const
|
|
{
|
|
return stamp == iter.get_stamp();
|
|
}
|