2014-01-18 14:43:24 -05:00
|
|
|
/*
|
|
|
|
* Copyright 2014 (c) Anna Schumaker.
|
|
|
|
*/
|
2014-01-24 20:31:33 -05:00
|
|
|
#include <audio.h>
|
2014-01-19 11:03:53 -05:00
|
|
|
#include <callback.h>
|
2014-01-18 14:43:24 -05:00
|
|
|
#include <deck.h>
|
2014-02-01 17:30:07 -05:00
|
|
|
#include <filter.h>
|
2014-01-18 14:43:24 -05:00
|
|
|
#include <ocarina.h>
|
2014-02-02 14:06:27 -05:00
|
|
|
#include <playlist.h>
|
2014-01-18 14:43:24 -05:00
|
|
|
#include <playqueue.h>
|
|
|
|
|
|
|
|
#include <map>
|
2014-02-01 17:30:07 -05:00
|
|
|
#include <set>
|
2014-01-19 10:34:26 -05:00
|
|
|
#include <sstream>
|
2014-01-18 14:43:24 -05:00
|
|
|
#include <string>
|
|
|
|
|
2014-01-24 20:01:19 -05:00
|
|
|
class OcarinaPage;
|
|
|
|
static std::map<Playqueue *, OcarinaPage *> tab_map;
|
2014-01-26 13:45:59 -05:00
|
|
|
static unsigned int sort_timeout_count = 0;
|
2014-01-18 14:43:24 -05:00
|
|
|
|
2014-02-02 14:06:27 -05:00
|
|
|
static class SidebarColumns : public Gtk::TreeModelColumnRecord {
|
|
|
|
public:
|
|
|
|
SidebarColumns()
|
|
|
|
{ add(sb_col_name); }
|
|
|
|
|
|
|
|
Gtk::TreeModelColumn<std::string> sb_col_name;
|
|
|
|
} sb_cols;
|
|
|
|
|
2014-01-19 15:19:24 -05:00
|
|
|
static class QueueColumns : public Gtk::TreeModelColumnRecord {
|
|
|
|
public:
|
|
|
|
QueueColumns()
|
|
|
|
{ add(q_col_track); add(q_col_title); add(q_col_length);
|
|
|
|
add(q_col_artist); add(q_col_album); add(q_col_year);
|
2014-01-29 22:23:07 -05:00
|
|
|
add(q_col_genre); add(q_col_count); add(q_col_played);
|
|
|
|
add(q_col_path); }
|
2014-01-19 15:19:24 -05:00
|
|
|
|
|
|
|
Gtk::TreeModelColumn<unsigned int> q_col_track;
|
|
|
|
Gtk::TreeModelColumn<std::string> q_col_title;
|
|
|
|
Gtk::TreeModelColumn<std::string> q_col_length;
|
|
|
|
Gtk::TreeModelColumn<std::string> q_col_artist;
|
|
|
|
Gtk::TreeModelColumn<std::string> q_col_album;
|
|
|
|
Gtk::TreeModelColumn<unsigned int> q_col_year;
|
|
|
|
Gtk::TreeModelColumn<std::string> q_col_genre;
|
|
|
|
Gtk::TreeModelColumn<unsigned int> q_col_count;
|
|
|
|
Gtk::TreeModelColumn<std::string> q_col_played;
|
2014-01-29 22:23:07 -05:00
|
|
|
Gtk::TreeModelColumn<std::string> q_col_path;
|
2014-01-19 15:19:24 -05:00
|
|
|
} queue_cols;
|
2014-01-24 16:49:48 -05:00
|
|
|
static unsigned int q_col_width[] = { 20, 300, 60, 100, 100, 45, 100, 60, 1 };
|
2014-01-26 13:45:59 -05:00
|
|
|
static sort_t q_col_sorts[] = {
|
|
|
|
SORT_TRACK, SORT_TITLE, SORT_LENGTH,
|
|
|
|
SORT_ARTIST, SORT_ALBUM, SORT_YEAR,
|
|
|
|
SORT_GENRE, SORT_COUNT, SORT_PLAYED
|
|
|
|
};
|
|
|
|
|
|
|
|
static void dec_sort_timeout()
|
|
|
|
{
|
|
|
|
if (sort_timeout_count > 0)
|
|
|
|
sort_timeout_count--;
|
|
|
|
if (sort_timeout_count == 0) {
|
|
|
|
Gtk::Label *label;
|
|
|
|
get_builder()->get_widget("o_sorting_indicator", label);
|
|
|
|
label->set_text("");
|
|
|
|
}
|
|
|
|
}
|
2014-01-19 15:19:24 -05:00
|
|
|
|
|
|
|
|
2014-01-24 20:01:19 -05:00
|
|
|
|
2014-01-18 14:43:24 -05:00
|
|
|
/*
|
|
|
|
* Tab class definition
|
|
|
|
*/
|
2014-01-31 20:38:33 -05:00
|
|
|
class OcarinaTab : public Gtk::HBox {
|
2014-01-31 21:09:31 -05:00
|
|
|
public:
|
|
|
|
OcarinaTab();
|
|
|
|
~OcarinaTab();
|
|
|
|
virtual void set_size(unsigned int) = 0;
|
2014-02-02 10:45:09 -05:00
|
|
|
virtual void set_number(unsigned int) = 0;
|
2014-01-31 21:09:31 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
OcarinaTab::OcarinaTab() {}
|
|
|
|
OcarinaTab::~OcarinaTab() {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PresetTab : public OcarinaTab {
|
2014-01-24 20:01:19 -05:00
|
|
|
public:
|
|
|
|
Gtk::Label name_label;
|
|
|
|
Gtk::Label size_label;
|
|
|
|
Gtk::Image tab_icon;
|
2014-01-31 21:09:31 -05:00
|
|
|
Gtk::VBox box;
|
2014-01-24 20:01:19 -05:00
|
|
|
|
2014-01-31 21:09:31 -05:00
|
|
|
PresetTab(const std::string &, const std::string &);
|
|
|
|
~PresetTab();
|
2014-01-24 20:01:19 -05:00
|
|
|
void set_size(unsigned int);
|
2014-02-02 10:45:09 -05:00
|
|
|
void set_number(unsigned int);
|
2014-01-24 20:01:19 -05:00
|
|
|
};
|
|
|
|
|
2014-01-31 21:09:31 -05:00
|
|
|
PresetTab::PresetTab(const std::string &name, const std::string &icon)
|
|
|
|
: name_label("<big>" + name + "</big>", 0.5, 0.5),
|
|
|
|
size_label("0", 0.5, 0.5)
|
2014-01-24 20:01:19 -05:00
|
|
|
{
|
|
|
|
tab_icon.set_from_icon_name(icon, Gtk::ICON_SIZE_MENU);
|
2014-01-24 20:31:33 -05:00
|
|
|
tab_icon.set_alignment(0, 0.5);
|
2014-01-24 20:01:19 -05:00
|
|
|
name_label.set_use_markup();
|
|
|
|
name_label.set_margin_right(1);
|
2014-02-02 11:15:43 -05:00
|
|
|
name_label.set_justify(Gtk::JUSTIFY_CENTER);
|
|
|
|
size_label.set_justify(Gtk::JUSTIFY_CENTER);
|
2014-01-31 20:38:33 -05:00
|
|
|
set_spacing(5);
|
2014-01-24 20:01:19 -05:00
|
|
|
|
2014-01-31 21:09:31 -05:00
|
|
|
box.pack_start(name_label);
|
|
|
|
box.pack_start(size_label);
|
2014-01-24 20:01:19 -05:00
|
|
|
|
2014-01-31 20:38:33 -05:00
|
|
|
pack_start(tab_icon);
|
2014-01-31 21:09:31 -05:00
|
|
|
pack_start(box);
|
2014-01-31 20:38:33 -05:00
|
|
|
show_all();
|
2014-01-31 21:09:31 -05:00
|
|
|
}
|
2014-01-30 22:33:24 -05:00
|
|
|
|
2014-01-31 21:09:31 -05:00
|
|
|
PresetTab::~PresetTab() {}
|
2014-02-02 10:45:09 -05:00
|
|
|
void PresetTab::set_number(unsigned int num) {}
|
2014-01-31 21:09:31 -05:00
|
|
|
|
|
|
|
void PresetTab::set_size(unsigned int size)
|
|
|
|
{
|
|
|
|
std::stringstream ss;
|
|
|
|
ss << size;
|
|
|
|
size_label.set_text(ss.str());
|
2014-01-24 20:01:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-01-31 21:09:31 -05:00
|
|
|
|
|
|
|
class PQTab : public OcarinaTab {
|
|
|
|
public:
|
2014-02-02 10:45:09 -05:00
|
|
|
Gtk::Label number_label;
|
2014-01-31 21:09:31 -05:00
|
|
|
Gtk::Label size_label;
|
2014-01-31 21:34:34 -05:00
|
|
|
Gtk::Image close_icon;
|
|
|
|
Gtk::Button close_button;
|
2014-01-31 21:09:31 -05:00
|
|
|
PQTab();
|
|
|
|
~PQTab();
|
|
|
|
void set_size(unsigned int);
|
2014-02-02 10:45:09 -05:00
|
|
|
void set_number(unsigned int);
|
2014-01-31 21:09:31 -05:00
|
|
|
};
|
|
|
|
|
2014-02-02 10:45:09 -05:00
|
|
|
PQTab::PQTab() : number_label("0", 0, 0.5), size_label("0", 0.5, 0.5)
|
2014-01-31 21:09:31 -05:00
|
|
|
{
|
2014-01-31 22:50:04 -05:00
|
|
|
close_icon.set_from_icon_name("window-close", Gtk::ICON_SIZE_MENU);
|
2014-01-31 21:34:34 -05:00
|
|
|
close_button.set_image(close_icon);
|
|
|
|
close_button.set_relief(Gtk::RELIEF_NONE);
|
2014-02-02 11:15:43 -05:00
|
|
|
number_label.set_justify(Gtk::JUSTIFY_CENTER);
|
2014-01-31 22:05:35 -05:00
|
|
|
|
2014-02-02 10:45:09 -05:00
|
|
|
pack_start(number_label, false, false);
|
2014-01-31 21:34:34 -05:00
|
|
|
pack_start(size_label, true, true);
|
|
|
|
pack_start(close_button, false, false);
|
2014-01-31 21:09:31 -05:00
|
|
|
show_all();
|
|
|
|
}
|
|
|
|
|
|
|
|
PQTab::~PQTab() {}
|
|
|
|
|
|
|
|
void PQTab::set_size(unsigned int size)
|
2014-01-24 20:01:19 -05:00
|
|
|
{
|
|
|
|
std::stringstream ss;
|
2014-01-31 21:09:31 -05:00
|
|
|
ss << "<span size='x-large'>" << size << "</span>";
|
|
|
|
size_label.set_markup(ss.str());
|
2014-01-24 20:01:19 -05:00
|
|
|
}
|
|
|
|
|
2014-02-02 10:45:09 -05:00
|
|
|
void PQTab::set_number(unsigned int num)
|
|
|
|
{
|
|
|
|
std::stringstream ss;
|
|
|
|
ss << "<span size='x-large'>" << num << ". </span>";
|
|
|
|
number_label.set_markup(ss.str());
|
|
|
|
}
|
|
|
|
|
2014-01-24 20:01:19 -05:00
|
|
|
|
|
|
|
|
2014-02-02 14:06:27 -05:00
|
|
|
class ManagerTab : public OcarinaTab {
|
|
|
|
public:
|
|
|
|
Gtk::Label name_label;
|
|
|
|
Gtk::Image tab_icon;
|
|
|
|
|
|
|
|
ManagerTab(const std::string &, const std::string &);
|
|
|
|
~ManagerTab();
|
|
|
|
void set_size(unsigned int);
|
|
|
|
void set_number(unsigned int);
|
|
|
|
};
|
|
|
|
|
|
|
|
ManagerTab::ManagerTab(const std::string &name, const std::string &icon)
|
|
|
|
: name_label(name, 0.5, 0.5)
|
|
|
|
{
|
|
|
|
name_label.set_justify(Gtk::JUSTIFY_CENTER);
|
|
|
|
tab_icon.set_from_icon_name(icon, Gtk::ICON_SIZE_MENU);
|
|
|
|
tab_icon.set_alignment(0, 0.5);
|
|
|
|
|
|
|
|
set_spacing(5);
|
|
|
|
pack_start(tab_icon);
|
|
|
|
pack_start(name_label);
|
|
|
|
show_all();
|
|
|
|
}
|
|
|
|
|
|
|
|
ManagerTab::~ManagerTab() {}
|
|
|
|
void ManagerTab::set_size(unsigned int) {}
|
|
|
|
void ManagerTab::set_number(unsigned int) {}
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-01-31 21:09:31 -05:00
|
|
|
|
2014-01-24 20:01:19 -05:00
|
|
|
/*
|
|
|
|
* Ocarina class definition
|
|
|
|
*/
|
2014-01-24 22:50:05 -05:00
|
|
|
class OcarinaPage : public Gtk::VBox {
|
2014-01-18 14:43:24 -05:00
|
|
|
private:
|
2014-01-24 23:01:02 -05:00
|
|
|
unsigned int init_flags;
|
2014-01-22 21:19:18 -05:00
|
|
|
Gtk::Notebook *notebook;
|
2014-02-02 12:33:58 -05:00
|
|
|
OcarinaTab *tab;
|
2014-01-19 10:34:26 -05:00
|
|
|
|
2014-02-01 17:30:07 -05:00
|
|
|
/* Filter state */
|
|
|
|
std::set<unsigned int> visible_ids;
|
|
|
|
|
2014-01-19 15:19:24 -05:00
|
|
|
/* Page widgets */
|
|
|
|
Gtk::HBox page_toolbar;
|
|
|
|
Gtk::SearchEntry page_entry;
|
2014-01-30 22:38:16 -05:00
|
|
|
Gtk::ToggleButton page_repeat;
|
2014-01-19 15:19:24 -05:00
|
|
|
Gtk::ScrolledWindow page_scroll;
|
2014-02-02 14:06:27 -05:00
|
|
|
Gtk::HBox page_viewbox;
|
2014-01-19 15:19:24 -05:00
|
|
|
Gtk::TreeView page_view;
|
|
|
|
|
2014-02-02 14:06:27 -05:00
|
|
|
/* Sidebar widgets */
|
|
|
|
Glib::RefPtr<Gtk::ListStore> sb_store;
|
|
|
|
Gtk::TreeView sb_view;
|
|
|
|
Gtk::ScrolledWindow sb_scroll;
|
|
|
|
|
|
|
|
void setup_common(Playqueue *, unsigned int, bool);
|
2014-01-31 21:09:31 -05:00
|
|
|
void setup_toolbar();
|
2014-02-02 14:06:27 -05:00
|
|
|
void setup_sidebar();
|
2014-01-31 21:09:31 -05:00
|
|
|
void setup_treeview();
|
2014-01-19 15:19:24 -05:00
|
|
|
void setup_columns();
|
2014-01-20 19:06:52 -05:00
|
|
|
void set_tab_size();
|
2014-01-19 10:34:26 -05:00
|
|
|
|
2014-01-18 14:43:24 -05:00
|
|
|
public:
|
2014-01-24 22:50:05 -05:00
|
|
|
Gtk::ToggleButton page_random;
|
2014-01-31 22:45:26 -05:00
|
|
|
Glib::RefPtr<PlayqueueModel> model;
|
2014-02-01 17:30:07 -05:00
|
|
|
Glib::RefPtr<Gtk::TreeModelFilter> filter;
|
2014-01-24 22:50:05 -05:00
|
|
|
|
2014-01-24 21:24:12 -05:00
|
|
|
OcarinaPage(const std::string &, const std::string &,
|
2014-01-31 21:09:31 -05:00
|
|
|
Playqueue *, unsigned int);
|
|
|
|
OcarinaPage(Playqueue *, unsigned int, unsigned int);
|
2014-02-02 14:06:27 -05:00
|
|
|
OcarinaPage(const std::string &, const std::string &, Playqueue *);
|
2014-01-24 20:01:19 -05:00
|
|
|
~OcarinaPage();
|
2014-01-22 21:19:18 -05:00
|
|
|
bool is_current_tab();
|
2014-01-24 23:01:02 -05:00
|
|
|
void check_pq_flags();
|
2014-01-30 22:53:44 -05:00
|
|
|
void queue_selected(bool);
|
2014-01-20 19:06:52 -05:00
|
|
|
|
2014-01-31 21:34:34 -05:00
|
|
|
void on_close_clicked();
|
2014-01-20 19:06:52 -05:00
|
|
|
void on_row_inserted(unsigned int);
|
|
|
|
void on_row_deleted(unsigned int);
|
2014-01-26 13:45:59 -05:00
|
|
|
void on_row_changed(unsigned int);
|
2014-01-22 21:19:18 -05:00
|
|
|
void on_runtime_changed();
|
2014-01-24 22:50:05 -05:00
|
|
|
void on_random_toggled();
|
2014-01-30 22:38:16 -05:00
|
|
|
void on_repeat_toggled();
|
2014-01-26 12:44:48 -05:00
|
|
|
void on_row_activated(const Gtk::TreePath &, Gtk::TreeViewColumn *);
|
2014-01-26 13:45:59 -05:00
|
|
|
void on_column_clicked(unsigned int);
|
2014-02-01 17:30:07 -05:00
|
|
|
void on_entry_changed();
|
|
|
|
bool on_entry_key_released(GdkEventKey *);
|
|
|
|
bool on_filter_visible(const Gtk::TreeIter &);
|
2014-02-02 10:45:09 -05:00
|
|
|
void on_page_renumbered();
|
|
|
|
bool on_view_key_pressed(GdkEventKey *);
|
2014-02-02 14:06:27 -05:00
|
|
|
void on_sidebar_cursor_changed();
|
2014-01-18 14:43:24 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-01-24 20:01:19 -05:00
|
|
|
OcarinaPage::OcarinaPage(const std::string &name, const std::string &icon,
|
2014-01-31 21:09:31 -05:00
|
|
|
Playqueue *pq, unsigned int flags)
|
2014-01-31 20:38:33 -05:00
|
|
|
: init_flags(flags)
|
2014-01-31 21:09:31 -05:00
|
|
|
{
|
|
|
|
tab = new PresetTab(name, icon);
|
2014-02-02 14:06:27 -05:00
|
|
|
setup_common(pq, 0, false);
|
2014-01-31 21:09:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
OcarinaPage::OcarinaPage(Playqueue *pq, unsigned int flags, unsigned int pg)
|
2014-01-31 22:05:35 -05:00
|
|
|
: init_flags(flags)
|
2014-01-31 21:09:31 -05:00
|
|
|
{
|
2014-01-31 21:34:34 -05:00
|
|
|
PQTab *pqt = new PQTab();
|
|
|
|
tab = pqt;
|
|
|
|
|
|
|
|
pqt->close_button.signal_clicked().connect(sigc::mem_fun(*this,
|
|
|
|
&OcarinaPage::on_close_clicked));
|
2014-02-02 14:06:27 -05:00
|
|
|
setup_common(pq, pg, false);
|
2014-01-31 22:45:26 -05:00
|
|
|
notebook->set_tab_reorderable(*this);
|
2014-01-31 21:09:31 -05:00
|
|
|
}
|
|
|
|
|
2014-02-02 14:06:27 -05:00
|
|
|
OcarinaPage::OcarinaPage(const std::string &name, const std::string &icon,
|
|
|
|
Playqueue *pq)
|
2014-02-06 19:54:43 -05:00
|
|
|
: init_flags(0)
|
2014-02-02 14:06:27 -05:00
|
|
|
{
|
|
|
|
ManagerTab *man_tab = new ManagerTab(name, icon);
|
|
|
|
tab = man_tab;
|
|
|
|
|
|
|
|
setup_common(pq, 0, true);
|
|
|
|
}
|
|
|
|
|
2014-01-31 21:09:31 -05:00
|
|
|
OcarinaPage::~OcarinaPage()
|
|
|
|
{
|
|
|
|
notebook->remove_page(*this);
|
|
|
|
tab_map.erase(model->queue);
|
|
|
|
}
|
|
|
|
|
2014-02-02 14:06:27 -05:00
|
|
|
void OcarinaPage::setup_common(Playqueue *pq, unsigned int pg, bool sidebar)
|
2014-01-18 14:43:24 -05:00
|
|
|
{
|
|
|
|
get_builder()->get_widget("o_notebook", notebook);
|
2014-01-20 19:06:52 -05:00
|
|
|
model = Glib::RefPtr<PlayqueueModel>(new PlayqueueModel(pq));
|
2014-02-01 17:30:07 -05:00
|
|
|
filter = Gtk::TreeModelFilter::create(model);
|
|
|
|
filter->set_visible_func(sigc::mem_fun(*this,
|
|
|
|
&OcarinaPage::on_filter_visible));
|
2014-01-19 10:34:26 -05:00
|
|
|
|
2014-01-31 22:05:35 -05:00
|
|
|
set_margin_left(1);
|
|
|
|
set_margin_right(1);
|
2014-02-02 14:06:27 -05:00
|
|
|
set_spacing(1);
|
2014-01-31 22:05:35 -05:00
|
|
|
|
2014-01-31 21:09:31 -05:00
|
|
|
setup_toolbar();
|
2014-02-02 14:06:27 -05:00
|
|
|
if (sidebar == true)
|
|
|
|
setup_sidebar();
|
2014-01-31 21:09:31 -05:00
|
|
|
setup_treeview();
|
2014-02-02 14:06:27 -05:00
|
|
|
pack_start(page_viewbox);
|
2014-01-31 21:09:31 -05:00
|
|
|
show_all();
|
2014-01-19 15:19:24 -05:00
|
|
|
|
2014-01-31 21:09:31 -05:00
|
|
|
/* Add to notebook */
|
|
|
|
notebook->insert_page(*this, *tab, pg);
|
|
|
|
tab_map[pq] = this;
|
|
|
|
set_tab_size();
|
|
|
|
}
|
|
|
|
|
|
|
|
void OcarinaPage::setup_toolbar()
|
|
|
|
{
|
2014-01-24 21:24:12 -05:00
|
|
|
page_toolbar.set_spacing(5);
|
|
|
|
page_toolbar.pack_start(page_entry);
|
2014-02-02 09:39:59 -05:00
|
|
|
page_toolbar.set_margin_left(5);
|
|
|
|
page_toolbar.set_margin_right(5);
|
2014-02-01 17:30:07 -05:00
|
|
|
|
|
|
|
/* Set up entry */
|
2014-01-24 21:24:12 -05:00
|
|
|
page_entry.set_margin_top(5);
|
|
|
|
page_entry.set_margin_bottom(5);
|
2014-02-01 17:30:07 -05:00
|
|
|
page_entry.signal_changed().connect(sigc::mem_fun(*this,
|
|
|
|
&OcarinaPage::on_entry_changed));
|
|
|
|
page_entry.signal_key_release_event().connect(sigc::mem_fun(*this,
|
|
|
|
&OcarinaPage::on_entry_key_released));
|
2014-01-24 21:24:12 -05:00
|
|
|
|
|
|
|
/* Make buttons */
|
2014-01-31 21:09:31 -05:00
|
|
|
if (init_flags & PQ_RANDOM) {
|
2014-01-24 21:24:12 -05:00
|
|
|
page_random.set_image_from_icon_name("media-playlist-shuffle");
|
|
|
|
page_toolbar.pack_start(page_random, false, false);
|
|
|
|
}
|
2014-01-31 21:09:31 -05:00
|
|
|
if (init_flags & PQ_REPEAT) {
|
2014-01-30 22:38:16 -05:00
|
|
|
page_repeat.set_image_from_icon_name("media-playlist-repeat");
|
|
|
|
page_toolbar.pack_start(page_repeat, false, false);
|
|
|
|
}
|
2014-01-24 21:24:12 -05:00
|
|
|
|
2014-01-31 21:09:31 -05:00
|
|
|
pack_start(page_toolbar, false, false);
|
|
|
|
}
|
2014-01-24 21:24:12 -05:00
|
|
|
|
2014-02-02 14:06:27 -05:00
|
|
|
void OcarinaPage::setup_sidebar()
|
|
|
|
{
|
|
|
|
Gtk::TreeModel::Row row;
|
|
|
|
|
|
|
|
sb_store = Gtk::ListStore::create(sb_cols);
|
|
|
|
sb_view.append_column("Playlists", sb_cols.sb_col_name);
|
|
|
|
sb_view.set_model(sb_store);
|
|
|
|
sb_view.get_selection()->set_mode(Gtk::SELECTION_BROWSE);
|
|
|
|
sb_view.signal_cursor_changed().connect(sigc::mem_fun(*this,
|
|
|
|
&OcarinaPage::on_sidebar_cursor_changed));
|
|
|
|
|
|
|
|
row = *(sb_store->append());
|
|
|
|
row[sb_cols.sb_col_name] = "Favorites";
|
|
|
|
|
|
|
|
row = *(sb_store->append());
|
|
|
|
row[sb_cols.sb_col_name] = "Banned";
|
|
|
|
|
|
|
|
sb_view.set_cursor(Gtk::TreePath("0"));
|
|
|
|
sb_scroll.set_shadow_type(Gtk::SHADOW_IN);
|
|
|
|
sb_scroll.set_margin_left(5);
|
|
|
|
sb_scroll.set_margin_bottom(5);
|
|
|
|
sb_scroll.add(sb_view);
|
|
|
|
|
|
|
|
page_viewbox.pack_start(sb_scroll, false, false);
|
|
|
|
}
|
|
|
|
|
2014-01-31 21:09:31 -05:00
|
|
|
void OcarinaPage::setup_treeview()
|
|
|
|
{
|
2014-01-19 15:19:24 -05:00
|
|
|
/* Make page content */
|
|
|
|
page_view.append_column("#", queue_cols.q_col_track);
|
|
|
|
page_view.append_column("Title", queue_cols.q_col_title);
|
|
|
|
page_view.append_column("Length", queue_cols.q_col_length);
|
|
|
|
page_view.append_column("Artist", queue_cols.q_col_artist);
|
|
|
|
page_view.append_column("Album", queue_cols.q_col_album);
|
|
|
|
page_view.append_column("Year", queue_cols.q_col_year);
|
|
|
|
page_view.append_column("Genre", queue_cols.q_col_genre);
|
|
|
|
page_view.append_column("Count", queue_cols.q_col_count);
|
|
|
|
page_view.append_column("Played", queue_cols.q_col_played);
|
2014-01-29 22:23:07 -05:00
|
|
|
page_view.set_tooltip_column(9);
|
2014-01-20 19:06:52 -05:00
|
|
|
|
2014-01-26 12:44:48 -05:00
|
|
|
page_view.signal_row_activated().connect(sigc::mem_fun(*this,
|
|
|
|
&OcarinaPage::on_row_activated));
|
2014-02-02 10:45:09 -05:00
|
|
|
page_view.signal_key_press_event().connect(sigc::mem_fun(*this,
|
|
|
|
&OcarinaPage::on_view_key_pressed));
|
|
|
|
|
2014-02-01 17:30:07 -05:00
|
|
|
page_view.set_model(filter);
|
2014-01-24 20:31:33 -05:00
|
|
|
page_view.set_rules_hint();
|
2014-01-30 22:33:24 -05:00
|
|
|
page_view.set_enable_search(false);
|
|
|
|
page_view.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
|
|
|
|
page_view.set_rubber_banding();
|
2014-02-02 12:33:58 -05:00
|
|
|
|
|
|
|
page_scroll.set_shadow_type(Gtk::SHADOW_IN);
|
|
|
|
page_scroll.set_margin_left(5);
|
|
|
|
page_scroll.set_margin_right(5);
|
|
|
|
page_scroll.set_margin_bottom(5);
|
2014-01-19 15:19:24 -05:00
|
|
|
page_scroll.add(page_view);
|
|
|
|
|
2014-01-31 21:09:31 -05:00
|
|
|
setup_columns();
|
2014-02-02 14:06:27 -05:00
|
|
|
page_viewbox.pack_start(page_scroll, true, true);
|
2014-01-18 14:43:24 -05:00
|
|
|
};
|
|
|
|
|
2014-01-24 20:01:19 -05:00
|
|
|
void OcarinaPage::setup_columns()
|
2014-01-19 15:19:24 -05:00
|
|
|
{
|
|
|
|
std::vector<Gtk::TreeViewColumn *> columns = page_view.get_columns();
|
|
|
|
for (unsigned int i = 0; i < columns.size(); i++) {
|
|
|
|
columns[i]->set_resizable();
|
|
|
|
columns[i]->set_fixed_width(q_col_width[i]);
|
2014-01-20 20:14:22 -05:00
|
|
|
columns[i]->set_sizing(Gtk::TREE_VIEW_COLUMN_FIXED);
|
2014-01-26 13:45:59 -05:00
|
|
|
columns[i]->set_clickable();
|
|
|
|
columns[i]->signal_clicked().connect(sigc::bind<unsigned int> (
|
|
|
|
sigc::mem_fun(*this, &OcarinaPage::on_column_clicked),
|
|
|
|
i));
|
2014-01-19 15:19:24 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-24 20:01:19 -05:00
|
|
|
bool OcarinaPage::is_current_tab()
|
2014-01-22 21:19:18 -05:00
|
|
|
{
|
2014-01-24 21:08:10 -05:00
|
|
|
return notebook->page_num(*this) == notebook->get_current_page();
|
2014-01-22 21:19:18 -05:00
|
|
|
}
|
|
|
|
|
2014-01-24 23:01:02 -05:00
|
|
|
void OcarinaPage::check_pq_flags()
|
|
|
|
{
|
|
|
|
if (init_flags & PQ_RANDOM) {
|
|
|
|
page_random.set_active(model->queue->get_flags() & PQ_RANDOM);
|
|
|
|
page_random.signal_toggled().connect(sigc::mem_fun(*this,
|
|
|
|
&OcarinaPage::on_random_toggled));
|
2014-01-30 22:53:44 -05:00
|
|
|
}
|
|
|
|
if (init_flags & PQ_REPEAT) {
|
2014-01-30 22:38:16 -05:00
|
|
|
page_repeat.set_active(model->queue->get_flags() & PQ_REPEAT);
|
|
|
|
page_repeat.signal_toggled().connect(sigc::mem_fun(*this,
|
|
|
|
&OcarinaPage::on_repeat_toggled));
|
2014-01-24 23:01:02 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-24 20:01:19 -05:00
|
|
|
void OcarinaPage::set_tab_size()
|
2014-01-20 19:06:52 -05:00
|
|
|
{
|
2014-01-31 20:38:33 -05:00
|
|
|
tab->set_size(model->queue->size());
|
2014-01-20 19:06:52 -05:00
|
|
|
}
|
|
|
|
|
2014-01-30 22:53:44 -05:00
|
|
|
void OcarinaPage::queue_selected(bool random)
|
2014-01-30 22:33:24 -05:00
|
|
|
{
|
|
|
|
Playqueue *pq;
|
|
|
|
unsigned int track_id;
|
|
|
|
std::vector<Gtk::TreeModel::Path>::iterator it;
|
|
|
|
Glib::RefPtr<Gtk::TreeSelection> sel = page_view.get_selection();
|
|
|
|
|
|
|
|
if (sel->count_selected_rows() == 0)
|
|
|
|
return;
|
|
|
|
|
2014-01-30 22:53:44 -05:00
|
|
|
pq = deck::create(random);
|
2014-01-30 22:33:24 -05:00
|
|
|
std::vector<Gtk::TreeModel::Path> rows = sel->get_selected_rows();
|
|
|
|
for (it = rows.begin(); it != rows.end(); it++) {
|
2014-02-02 10:45:09 -05:00
|
|
|
track_id = model->path_to_id(filter->convert_path_to_child_path(*it));
|
2014-01-30 22:33:24 -05:00
|
|
|
pq->add(track_id);
|
|
|
|
}
|
2014-01-31 21:34:34 -05:00
|
|
|
}
|
2014-01-30 22:33:24 -05:00
|
|
|
|
2014-01-31 21:34:34 -05:00
|
|
|
void OcarinaPage::on_close_clicked()
|
|
|
|
{
|
|
|
|
deck :: remove(notebook->page_num(*this));
|
2014-01-30 22:33:24 -05:00
|
|
|
}
|
|
|
|
|
2014-01-24 20:01:19 -05:00
|
|
|
void OcarinaPage::on_row_inserted(unsigned int row)
|
2014-01-20 19:06:52 -05:00
|
|
|
{
|
|
|
|
model->on_row_inserted(row);
|
|
|
|
set_tab_size();
|
2014-01-22 21:19:18 -05:00
|
|
|
if (is_current_tab())
|
|
|
|
on_runtime_changed();
|
2014-01-20 19:06:52 -05:00
|
|
|
}
|
|
|
|
|
2014-01-24 20:01:19 -05:00
|
|
|
void OcarinaPage::on_row_deleted(unsigned int row)
|
2014-01-20 19:06:52 -05:00
|
|
|
{
|
|
|
|
model->on_row_deleted(row);
|
|
|
|
set_tab_size();
|
2014-01-22 21:19:18 -05:00
|
|
|
if (is_current_tab())
|
|
|
|
on_runtime_changed();
|
|
|
|
}
|
|
|
|
|
2014-01-26 13:45:59 -05:00
|
|
|
void OcarinaPage::on_row_changed(unsigned int row)
|
|
|
|
{
|
|
|
|
model->on_row_changed(row);
|
|
|
|
if (is_current_tab())
|
|
|
|
on_runtime_changed();
|
|
|
|
}
|
|
|
|
|
2014-01-24 20:01:19 -05:00
|
|
|
void OcarinaPage::on_runtime_changed()
|
2014-01-22 21:19:18 -05:00
|
|
|
{
|
|
|
|
Gtk::Label *label;
|
|
|
|
get_builder()->get_widget("o_queue_time", label);
|
|
|
|
label->set_text(model->queue->get_length_str());
|
2014-01-20 19:06:52 -05:00
|
|
|
}
|
|
|
|
|
2014-01-24 22:50:05 -05:00
|
|
|
void OcarinaPage::on_random_toggled()
|
|
|
|
{
|
|
|
|
if (page_random.get_active())
|
|
|
|
model->queue->set_flag(PQ_RANDOM);
|
|
|
|
else
|
|
|
|
model->queue->unset_flag(PQ_RANDOM);
|
|
|
|
}
|
|
|
|
|
2014-01-30 22:38:16 -05:00
|
|
|
void OcarinaPage::on_repeat_toggled()
|
|
|
|
{
|
|
|
|
if (page_repeat.get_active())
|
|
|
|
model->queue->set_flag(PQ_REPEAT);
|
|
|
|
else
|
|
|
|
model->queue->unset_flag(PQ_REPEAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-01-26 12:44:48 -05:00
|
|
|
void OcarinaPage::on_row_activated(const Gtk::TreePath &path, Gtk::TreeViewColumn *col)
|
|
|
|
{
|
2014-02-01 17:30:07 -05:00
|
|
|
Gtk::TreePath model_path = filter->convert_path_to_child_path(path);
|
|
|
|
model->on_path_selected(model_path);
|
2014-01-26 12:44:48 -05:00
|
|
|
}
|
|
|
|
|
2014-01-26 13:45:59 -05:00
|
|
|
void OcarinaPage::on_column_clicked(unsigned int col_index)
|
|
|
|
{
|
|
|
|
Gtk::Label *sorting;
|
|
|
|
get_builder()->get_widget("o_sorting_indicator", sorting);
|
|
|
|
|
2014-01-31 22:10:20 -05:00
|
|
|
if (sort_timeout_count == 0) {
|
|
|
|
sorting->set_text("Sorting within " + page_view.get_column(col_index)->get_title());
|
2014-01-26 13:45:59 -05:00
|
|
|
model->queue->reset_sort(q_col_sorts[col_index]);
|
2014-01-31 22:10:20 -05:00
|
|
|
} else
|
2014-01-26 13:45:59 -05:00
|
|
|
model->queue->add_sort(q_col_sorts[col_index]);
|
|
|
|
sort_timeout_count++;
|
|
|
|
Glib::signal_timeout().connect_seconds_once(
|
2014-01-26 14:58:30 -05:00
|
|
|
sigc::ptr_fun(dec_sort_timeout), 2);
|
2014-01-26 13:45:59 -05:00
|
|
|
}
|
|
|
|
|
2014-02-01 17:30:07 -05:00
|
|
|
void OcarinaPage::on_entry_changed()
|
|
|
|
{
|
|
|
|
filter :: search(page_entry.get_text(), visible_ids);
|
|
|
|
filter->refilter();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OcarinaPage::on_entry_key_released(GdkEventKey *event)
|
|
|
|
{
|
|
|
|
std::string key = gdk_keyval_name(event->keyval);
|
|
|
|
return key == "space";
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OcarinaPage::on_filter_visible(const Gtk::TreeIter &iter)
|
|
|
|
{
|
|
|
|
unsigned int pq_id;
|
|
|
|
std::set<unsigned int>::iterator it;
|
|
|
|
|
|
|
|
if (page_entry.get_text().size() == 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
pq_id = model->iter_to_id(iter);
|
|
|
|
return visible_ids.find(model->queue->operator[](pq_id)) != visible_ids.end();
|
|
|
|
}
|
2014-01-20 19:06:52 -05:00
|
|
|
|
2014-02-02 10:45:09 -05:00
|
|
|
void OcarinaPage::on_page_renumbered()
|
|
|
|
{
|
|
|
|
tab->set_number(notebook->page_num(*this));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OcarinaPage::on_view_key_pressed(GdkEventKey *event)
|
|
|
|
{
|
|
|
|
std::string key = gdk_keyval_name(event->keyval);
|
|
|
|
|
|
|
|
if (key.size() >= 3) {
|
|
|
|
if (key.substr(0, 3) == "KP_")
|
|
|
|
key = key.substr(3);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (key >= "0" && key <= "9") {
|
|
|
|
unsigned int n = atoi(key.c_str());
|
|
|
|
if (n >= deck :: size())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
Glib::RefPtr<Gtk::TreeSelection> sel = page_view.get_selection();
|
|
|
|
if (sel->count_selected_rows() == 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
Playqueue *pq = deck :: get(n);
|
|
|
|
std::vector<Gtk::TreeModel::Path>::iterator it;
|
|
|
|
std::vector<Gtk::TreeModel::Path> rows = sel->get_selected_rows();
|
|
|
|
for (it = rows.begin(); it != rows.end(); it++) {
|
|
|
|
unsigned int track_id = model->path_to_id(filter->convert_path_to_child_path(*it));
|
|
|
|
pq->add(track_id);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-02-02 14:06:27 -05:00
|
|
|
void OcarinaPage::on_sidebar_cursor_changed()
|
|
|
|
{
|
|
|
|
Gtk::TreePath path;
|
|
|
|
Gtk::TreeViewColumn *col;
|
|
|
|
|
|
|
|
sb_view.get_cursor(path, col);
|
|
|
|
Gtk::TreeModel::Row row = *(sb_store->get_iter(path));
|
|
|
|
playlist :: select(row[sb_cols.sb_col_name]);
|
|
|
|
}
|
|
|
|
|
2014-01-18 14:43:24 -05:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Do stuff with tabs
|
|
|
|
*/
|
2014-01-20 19:06:52 -05:00
|
|
|
static void on_track_added(Playqueue *pq, unsigned int row)
|
2014-01-19 11:03:53 -05:00
|
|
|
{
|
2014-01-24 20:01:19 -05:00
|
|
|
std::map<Playqueue *, OcarinaPage *>::iterator it;
|
2014-01-22 22:31:42 -05:00
|
|
|
it = tab_map.find(pq);
|
|
|
|
if (it != tab_map.end())
|
|
|
|
it->second->on_row_inserted(row);
|
2014-01-19 11:03:53 -05:00
|
|
|
}
|
|
|
|
|
2014-01-20 19:06:52 -05:00
|
|
|
static void on_track_deleted(Playqueue *pq, unsigned int row)
|
2014-01-19 11:03:53 -05:00
|
|
|
{
|
2014-01-24 20:01:19 -05:00
|
|
|
std::map<Playqueue *, OcarinaPage *>::iterator it;
|
2014-01-22 22:31:42 -05:00
|
|
|
it = tab_map.find(pq);
|
|
|
|
if (it != tab_map.end())
|
|
|
|
it->second->on_row_deleted(row);
|
2014-01-19 11:03:53 -05:00
|
|
|
}
|
|
|
|
|
2014-01-26 13:45:59 -05:00
|
|
|
static void on_track_changed(Playqueue *pq, unsigned int row)
|
|
|
|
{
|
|
|
|
std::map<Playqueue *, OcarinaPage *>::iterator it;
|
|
|
|
it = tab_map.find(pq);
|
|
|
|
if (it != tab_map.end())
|
|
|
|
it->second->on_row_changed(row);
|
|
|
|
}
|
|
|
|
|
2014-01-24 21:08:10 -05:00
|
|
|
static void on_switch_page(Gtk::Widget *page, int num)
|
2014-01-22 21:19:18 -05:00
|
|
|
{
|
|
|
|
Gtk::Label *label;
|
2014-01-24 21:08:10 -05:00
|
|
|
Gtk::Notebook *notebook;
|
|
|
|
OcarinaPage *tab = (OcarinaPage *)page;
|
|
|
|
|
2014-01-22 21:19:18 -05:00
|
|
|
get_builder()->get_widget("o_queue_time", label);
|
2014-01-24 21:08:10 -05:00
|
|
|
get_builder()->get_widget("o_notebook", notebook);
|
2014-01-22 21:19:18 -05:00
|
|
|
|
2014-01-24 21:08:10 -05:00
|
|
|
if (num >= notebook->get_n_pages() - 1)
|
|
|
|
label->hide();
|
|
|
|
else {
|
|
|
|
tab->on_runtime_changed();
|
|
|
|
label->show();
|
2014-01-22 21:19:18 -05:00
|
|
|
}
|
2014-01-26 13:45:59 -05:00
|
|
|
|
|
|
|
sort_timeout_count = 0;
|
2014-01-22 21:19:18 -05:00
|
|
|
}
|
|
|
|
|
2014-02-02 10:45:09 -05:00
|
|
|
static void renumber_pqs()
|
|
|
|
{
|
|
|
|
std::map<Playqueue *, OcarinaPage *>::iterator it;
|
|
|
|
for (it = tab_map.begin(); it != tab_map.end(); it++)
|
|
|
|
it->second->on_page_renumbered();
|
|
|
|
}
|
|
|
|
|
2014-01-31 22:45:26 -05:00
|
|
|
static void on_page_reordered(Gtk::Widget *page, int num)
|
|
|
|
{
|
|
|
|
Gtk::Notebook *notebook;
|
|
|
|
OcarinaPage *tab = (OcarinaPage *)page;
|
|
|
|
|
|
|
|
get_builder()->get_widget("o_notebook", notebook);
|
|
|
|
|
|
|
|
if ((unsigned int)num >= deck :: size())
|
|
|
|
notebook->reorder_child(*page, deck::size() - 1);
|
2014-02-02 10:45:09 -05:00
|
|
|
else {
|
2014-01-31 22:45:26 -05:00
|
|
|
deck :: move(tab->model->queue, num);
|
2014-02-02 10:45:09 -05:00
|
|
|
renumber_pqs();
|
|
|
|
}
|
2014-01-31 22:45:26 -05:00
|
|
|
}
|
|
|
|
|
2014-01-30 22:33:24 -05:00
|
|
|
static void on_pq_created(Playqueue *pq, unsigned int num)
|
|
|
|
{
|
2014-01-31 21:09:31 -05:00
|
|
|
OcarinaPage *page = new OcarinaPage(pq, PQ_RANDOM | PQ_REPEAT, num);
|
2014-01-30 22:33:24 -05:00
|
|
|
page->check_pq_flags();
|
2014-02-02 10:45:09 -05:00
|
|
|
renumber_pqs();
|
2014-01-30 22:33:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static void on_pq_removed(Playqueue *pq)
|
|
|
|
{
|
|
|
|
std::map<Playqueue *, OcarinaPage *>::iterator it;
|
|
|
|
it = tab_map.find(pq);
|
|
|
|
if (it != tab_map.end())
|
|
|
|
delete it->second;
|
2014-02-02 10:45:09 -05:00
|
|
|
renumber_pqs();
|
2014-01-30 22:33:24 -05:00
|
|
|
}
|
|
|
|
|
2014-01-30 22:53:44 -05:00
|
|
|
void queue_selected(bool random)
|
2014-01-30 22:33:24 -05:00
|
|
|
{
|
|
|
|
std::map<Playqueue *, OcarinaPage *>::iterator it;
|
2014-02-02 10:45:09 -05:00
|
|
|
if (deck :: size() >= 10)
|
|
|
|
return;
|
|
|
|
|
2014-01-30 22:33:24 -05:00
|
|
|
for (it = tab_map.begin(); it != tab_map.end(); it++) {
|
|
|
|
if (it->second->is_current_tab()) {
|
2014-01-30 22:53:44 -05:00
|
|
|
it->second->queue_selected(random);
|
2014-01-30 22:33:24 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-19 10:34:26 -05:00
|
|
|
void init_tabs()
|
2014-01-18 14:43:24 -05:00
|
|
|
{
|
2014-01-22 21:19:18 -05:00
|
|
|
Gtk::Notebook *notebook;
|
|
|
|
get_builder()->get_widget("o_notebook", notebook);
|
|
|
|
|
2014-02-02 14:06:27 -05:00
|
|
|
new OcarinaPage("Playlist\nManager", "emblem-documents", playlist::get_pq());
|
2014-01-31 21:09:31 -05:00
|
|
|
new OcarinaPage("History", "document-open-recent", audio::get_recent_pq(), 0);
|
|
|
|
new OcarinaPage("Collection", "media-optical", deck::get_library_pq(), PQ_RANDOM);
|
2014-01-30 22:33:24 -05:00
|
|
|
get_callbacks()->on_pq_created = on_pq_created;
|
|
|
|
get_callbacks()->on_pq_removed = on_pq_removed;
|
2014-01-26 13:45:59 -05:00
|
|
|
get_callbacks()->on_queue_track_add = on_track_added;
|
|
|
|
get_callbacks()->on_queue_track_del = on_track_deleted;
|
|
|
|
get_callbacks()->on_queue_track_changed = on_track_changed;
|
2014-01-22 21:19:18 -05:00
|
|
|
|
|
|
|
notebook->signal_switch_page().connect(sigc::ptr_fun(on_switch_page));
|
2014-01-31 22:45:26 -05:00
|
|
|
notebook->signal_page_reordered().connect(sigc::ptr_fun(on_page_reordered));
|
2014-01-25 14:42:56 -05:00
|
|
|
notebook->set_current_page(0);
|
2014-01-18 14:43:24 -05:00
|
|
|
}
|
|
|
|
|
2014-01-24 23:01:02 -05:00
|
|
|
void init_tabs2()
|
|
|
|
{
|
|
|
|
std::map<Playqueue *, OcarinaPage *>::iterator it;
|
|
|
|
for (it = tab_map.begin(); it != tab_map.end(); it++)
|
|
|
|
it->second->check_pq_flags();
|
|
|
|
}
|
|
|
|
|
2014-01-18 14:43:24 -05:00
|
|
|
void cleanup_tabs()
|
|
|
|
{
|
2014-02-02 12:33:58 -05:00
|
|
|
while (tab_map.size() > 0)
|
|
|
|
delete tab_map.begin()->second;
|
2014-01-18 14:43:24 -05:00
|
|
|
}
|