ClassEditor::TypeSelectorWidgets ClassEditor::createStimTypeSelector()
{
	TypeSelectorWidgets widgets;

	// Type Selector
	widgets.hbox = Gtk::manage(new Gtk::HBox(false, 0));

	widgets.label = Gtk::manage(new gtkutil::LeftAlignedLabel(_("Type:")));

	// Cast the helper class onto a ListStore and create a new treeview
	widgets.list = Gtk::manage(new Gtk::ComboBox(_stimTypes.getListStore()));
	widgets.list->set_size_request(-1, -1);

	// Add the cellrenderer for the name
	Gtk::CellRendererText* nameRenderer = Gtk::manage(new Gtk::CellRendererText);
	Gtk::CellRendererPixbuf* iconRenderer = Gtk::manage(new Gtk::CellRendererPixbuf);

	widgets.list->pack_start(*iconRenderer, false);
	widgets.list->pack_start(*nameRenderer, true);

	widgets.list->add_attribute(iconRenderer->property_pixbuf(), _stimTypes.getColumns().icon);
	widgets.list->add_attribute(nameRenderer->property_text(), _stimTypes.getColumns().captionPlusID);
	iconRenderer->set_fixed_size(26, -1);

	widgets.hbox->pack_start(*widgets.label, false, false, 0);
	widgets.hbox->pack_start(*Gtk::manage(new gtkutil::LeftAlignment(*widgets.list, 12, 1.0f)),
		true, true,	0
	);

	// Set the combo box to use two-column
	widgets.list->set_wrap_width(2);
	widgets.list->set_active(0);

	return widgets;
}
ClassEditor::ClassEditor(StimTypes& stimTypes) :
	Gtk::VBox(false, 6),
	_stimTypes(stimTypes),
	_updatesDisabled(false)
{
	set_border_width(6);

	_list = Gtk::manage(new Gtk::TreeView);
	_list->set_size_request(TREE_VIEW_WIDTH, TREE_VIEW_HEIGHT);

	// Connect the signals to the callbacks
	_list->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &ClassEditor::onSRSelectionChange));
	_list->signal_key_press_event().connect(sigc::mem_fun(*this, &ClassEditor::onTreeViewKeyPress), false);
	_list->signal_button_release_event().connect(
		sigc::bind(sigc::mem_fun(*this, &ClassEditor::onTreeViewButtonRelease), _list));

	// Add the columns to the treeview
	// ID number
	Gtk::TreeViewColumn* numCol = Gtk::manage(new Gtk::TreeViewColumn("#"));
	Gtk::CellRendererText* numRenderer = Gtk::manage(new Gtk::CellRendererText);

	numCol->pack_start(*numRenderer, false);
	numCol->add_attribute(numRenderer->property_text(), SREntity::getColumns().index);
	numCol->add_attribute(numRenderer->property_foreground(), SREntity::getColumns().colour);

	_list->append_column(*numCol);

	// The S/R icon
	Gtk::TreeViewColumn* classCol = Gtk::manage(new Gtk::TreeViewColumn(_("S/R")));

	Gtk::CellRendererPixbuf* pixbufRenderer = Gtk::manage(new Gtk::CellRendererPixbuf);

	classCol->pack_start(*pixbufRenderer, false);
	classCol->add_attribute(pixbufRenderer->property_pixbuf(), SREntity::getColumns().srClass);

	_list->append_column(*classCol);

	// The Type
	Gtk::TreeViewColumn* typeCol = Gtk::manage(new Gtk::TreeViewColumn(_("Type")));

	Gtk::CellRendererPixbuf* typeIconRenderer = Gtk::manage(new Gtk::CellRendererPixbuf);

	typeCol->pack_start(*typeIconRenderer, false);
	typeCol->add_attribute(typeIconRenderer->property_pixbuf(), SREntity::getColumns().icon);

	Gtk::CellRendererText* typeTextRenderer = Gtk::manage(new Gtk::CellRendererText);

	typeCol->pack_start(*typeTextRenderer, false);
	typeCol->add_attribute(typeTextRenderer->property_text(), SREntity::getColumns().caption);
	typeCol->add_attribute(typeTextRenderer->property_foreground(), SREntity::getColumns().colour);

	_list->append_column(*typeCol);
}
void SearchNotesWidget::notebook_pixbuf_cell_data_func(Gtk::CellRenderer * renderer,
                                                       const Gtk::TreeIter & iter)
{
  notebooks::Notebook::Ptr notebook;
  iter->get_value(0, notebook);
  if(!notebook) {
    return;
  }

  Gtk::CellRendererPixbuf *crp = dynamic_cast<Gtk::CellRendererPixbuf*>(renderer);
  notebooks::SpecialNotebook::Ptr special_nb = dynamic_pointer_cast<notebooks::SpecialNotebook>(notebook);
  if(special_nb) {
    crp->property_pixbuf() = special_nb->get_icon();
  }
  else {
    crp->property_pixbuf() = IconManager::obj().get_icon(IconManager::NOTEBOOK, 22);
  }
}
/** greebo: Creates all the widgets
 */
void CustomStimEditor::populatePage()
{
	set_border_width(6);

	// Setup a treemodel filter to display the custom stims only
	_customStimStore = Gtk::TreeModelFilter::create(_stimTypes.getListStore());
	_customStimStore->set_visible_column(_stimTypes.getColumns().isCustom);

	_list = Gtk::manage(new Gtk::TreeView(_customStimStore));
	_list->set_size_request(TREE_VIEW_WIDTH, TREE_VIEW_HEIGHT);

	// Connect the signals to the callbacks
	_list->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &CustomStimEditor::onSelectionChange));
	_list->signal_button_release_event().connect(sigc::mem_fun(*this, &CustomStimEditor::onTreeViewButtonRelease));

	// Add the columns to the treeview
	// ID number
	Gtk::TreeViewColumn* numCol = Gtk::manage(new Gtk::TreeViewColumn(_("ID")));

	Gtk::CellRendererText* numRenderer = Gtk::manage(new Gtk::CellRendererText);
	numCol->pack_start(*numRenderer, false);
	numCol->add_attribute(numRenderer->property_text(), _stimTypes.getColumns().id);

	_list->append_column(*numCol);

	// The Type
	Gtk::TreeViewColumn* typeCol = Gtk::manage(new Gtk::TreeViewColumn(_("Type")));

	Gtk::CellRendererPixbuf* typeIconRenderer = Gtk::manage(new Gtk::CellRendererPixbuf);
	typeCol->pack_start(*typeIconRenderer, false);

	Gtk::CellRendererText* typeTextRenderer = Gtk::manage(new Gtk::CellRendererText);
	typeCol->pack_start(*typeTextRenderer, false);

	typeCol->add_attribute(typeTextRenderer->property_text(), _stimTypes.getColumns().caption);
	typeCol->add_attribute(typeIconRenderer->property_pixbuf(), _stimTypes.getColumns().icon);

	_list->append_column(*typeCol);

	Gtk::VBox* listVBox = Gtk::manage(new Gtk::VBox(false, 6));
	listVBox->pack_start(*Gtk::manage(new gtkutil::ScrolledFrame(*_list)), true, true, 0);
	listVBox->pack_start(createListButtons(), false, false, 0);

	pack_start(*listVBox, false, false, 0);

	_propertyWidgets.vbox = Gtk::manage(new Gtk::VBox(false, 6));

	pack_start(*_propertyWidgets.vbox, true, true, 0);

	// The name widgets
	Gtk::HBox* nameHBox = Gtk::manage(new Gtk::HBox(false, 6));
	_propertyWidgets.nameLabel = Gtk::manage(new Gtk::Label(_("Name:")));
	_propertyWidgets.nameEntry = Gtk::manage(new Gtk::Entry);

	nameHBox->pack_start(*_propertyWidgets.nameLabel, false, false, 0);
	nameHBox->pack_start(*_propertyWidgets.nameEntry, true, true, 0);

	// Connect the entry field
	_propertyWidgets.nameEntry->signal_changed().connect(sigc::mem_fun(*this, &CustomStimEditor::onEntryChanged));

	_propertyWidgets.vbox->pack_start(*nameHBox, false, false, 0);

	Gtk::Label* infoText = Gtk::manage(new gtkutil::LeftAlignedLabel(
		_("<b>Note:</b> Please beware that deleting custom stims may\n"
		"affect other entities as well. So check before you delete.")
	));
	_propertyWidgets.vbox->pack_start(*infoText, false, false, 0);
}
// Cringe.
void GtkTorrentSideBar::setupColumns()
{
	int cid = 0;
	Gtk::TreeViewColumn     *col = nullptr;
	Gtk::CellRendererText   *cell = Gtk::manage(new Gtk::CellRendererText());
	Gtk::CellRendererPixbuf *cellp = Gtk::manage(new Gtk::CellRendererPixbuf());

	cell->set_alignment(0, 0.5);
	cell->signal_edited().connect([this](const std::string& path,const std::string& name){ addedItem(path, name); });

	cid = append_column(*Gtk::manage(new Gtk::TreeViewColumn("Name")));	
	col = get_column(cid - 1);
	col->pack_start(*cellp);
	col->pack_start(*cell);
	col->add_attribute(cell->property_markup(), m_cols.name);
	col->add_attribute(cell->property_editable(), m_cols.editable);
	col->add_attribute(cellp->property_pixbuf(), m_cols.icon);

        // This really isn't "setupColumns" anymore from this point.
        // TODO Move to own function
	m_torrent_row = *(m_liststore->append());
	m_torrent_row[m_cols.name] = "Torrents";
	m_torrent_row[m_cols.editable] = false;
	m_torrent_row[m_cols.clickCallback] = [](){}; // clicks on titles don't do shit

	auto torrent_icon = Gdk::Pixbuf::create_from_resource("/org/gtk/gtorrent/icon-torrent.png");
	auto torrent_icon_scaled =  torrent_icon->scale_simple(16, 16, Gdk::INTERP_BILINEAR);
	m_torrent_row[m_cols.icon] = torrent_icon_scaled;

        // XXX TMP WILL REMOVE AND REPLACE WITH PROPER FUNCTION
        // Yes this is horrible. Bear with it for now.
        auto g = Application::getSingleton()->getCore()->getAllTorrents();
	Gtk::TreeModel::Row row = *(m_liststore->append(m_torrent_row.children()));
	row[m_cols.name] = "All";
	row[m_cols.title] = "All";
	row[m_cols.group] = g;
	row[m_cols.group_vector] = &g->m_torrents_all;

	Gtk::TreeModel::Row row2 = *(m_liststore->append(row.children()));
	row2[m_cols.name] = "Downloading";
	row2[m_cols.title] = "Downloading";
	row2[m_cols.group_vector] = &g->m_torrents_downloading;
        row2 = *(m_liststore->append(row.children()));
        row2[m_cols.name] = "Seeding";
        row2[m_cols.title] = "Seeding";
        row2[m_cols.group_vector] = &g->m_torrents_seeding;
        row2 = *(m_liststore->append(row.children()));
        row2[m_cols.name] = "Checking";
        row2[m_cols.title] = "Checking";
        row2[m_cols.group_vector] = &g->m_torrents_checking;
        row2 = *(m_liststore->append(row.children()));
        row2[m_cols.name] = "Finished";
        row2[m_cols.title] = "Finished";
        row2[m_cols.group_vector] = &g->m_torrents_finished;
        row2 = *(m_liststore->append(row.children()));
        row2[m_cols.name] = "Stopped";
        row2[m_cols.title] = "Stopped";
        row2[m_cols.group_vector] = &g->m_torrents_stopped;
        row2 = *(m_liststore->append(row.children()));
        row2[m_cols.name] = "Paused";
        row2[m_cols.title] = "Paused";
        row2[m_cols.group_vector] = &g->m_torrents_paused;

        // End of new horrible code
        // Continue horrible code from before
	//row = *(m_liststore->append(m_torrent_row.children()));
	//row[m_cols.name] = "Add a label";
	//row[m_cols.editable] = true;
	//row[m_cols.icon] = Gtk::IconTheme::get_default()->lookup_icon("list-add-symbolic", 16, Gtk::ICON_LOOKUP_USE_BUILTIN).load_icon();
	//row[m_cols.clickCallback] = [row](){};

	m_rssfeed_row = *(m_liststore->append());
	m_rssfeed_row[m_cols.name] = "RSS Feeds";
	m_rssfeed_row[m_cols.editable] = false;
	m_rssfeed_row[m_cols.clickCallback] = [](){};

	auto rss_icon = Gdk::Pixbuf::create_from_resource("/org/gtk/gtorrent/icon-rss.png");
	auto rss_icon_scaled =  rss_icon->scale_simple(16, 16, Gdk::INTERP_BILINEAR);
	m_rssfeed_row[m_cols.icon] = rss_icon_scaled;

	for(auto fg : Application::getSingleton()->getCore()->m_feeds)
	{
		row = *(m_liststore->append(m_rssfeed_row.children()));
		row[m_cols.name] = fg->name;
		row[m_cols.editable] = false;
		// TODO change icon to some sort of generic RSS icon
		row[m_cols.clickCallback] = [this, fg](){m_rss->run(fg->name);m_rss->hide();};

	}
	
	row = *(m_liststore->append(m_rssfeed_row.children()));
	row[m_cols.name] = "Add an RSS group";
	row[m_cols.editable] = true;

	row[m_cols.icon] = Gtk::IconTheme::get_default()->lookup_icon("list-add-symbolic", 16, Gtk::ICON_LOOKUP_USE_BUILTIN).load_icon();
	row[m_cols.clickCallback] = [row](){};

	//Maybe migrate settings there
/*	row = *(m_liststore->append());
	row[m_cols.name] = "Settings";
	row[m_cols.title] = true;
	row[m_cols.clickCallback] = [](){}; // clicks on titles don't do shit*/
}