/* * Copyright © 2004-2007 Jens Oknelid, paskharen@gmail.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "publichubs.hh" #include "wulformanager.hh" using namespace std; PublicHubs::PublicHubs(): BookEntry(_("Public Hubs"), "publichubs.glade"), hubs(0), filter("") { FavoriteManager *favMan = FavoriteManager::getInstance(); favMan->addListener(this); // Configure the dialog gtk_dialog_set_alternative_button_order(GTK_DIALOG(getWidget("configureDialog")), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); // Initialize public hub list treeview hubView.setView(GTK_TREE_VIEW(getWidget("hubView")), true, "publichubs"); hubView.insertColumn("Name", G_TYPE_STRING, TreeView::STRING, 200); hubView.insertColumn("Description", G_TYPE_STRING, TreeView::STRING, 350); hubView.insertColumn("Users", G_TYPE_INT, TreeView::INT, 75); hubView.insertColumn("Address", G_TYPE_STRING, TreeView::STRING, 110); hubView.insertColumn("Country", G_TYPE_STRING, TreeView::STRING, 100); hubView.insertColumn("Shared", G_TYPE_STRING, TreeView::STRING, 70); hubView.insertColumn("Min Share", G_TYPE_STRING, TreeView::STRING, 80); hubView.insertColumn("Min Slots", G_TYPE_INT, TreeView::INT, 70); hubView.insertColumn("Max Hubs", G_TYPE_INT, TreeView::INT, 80); hubView.insertColumn("Max Users", G_TYPE_INT, TreeView::INT, 80); hubView.insertColumn("Rating", G_TYPE_STRING, TreeView::STRING, 70); hubView.finalize(); hubStore = gtk_list_store_newv(hubView.getColCount(), hubView.getGTypes()); gtk_tree_view_set_model(hubView.get(), GTK_TREE_MODEL(hubStore)); g_object_unref(hubStore); hubSelection = gtk_tree_view_get_selection(hubView.get()); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(hubStore), hubView.col("Users"), GTK_SORT_DESCENDING); gtk_tree_view_column_set_sort_indicator(gtk_tree_view_get_column(hubView.get(), hubView.col("Users")), TRUE); gtk_tree_view_set_fixed_height_mode(hubView.get(), TRUE); // Initialize list of public hub lists treeview listsView.setView(GTK_TREE_VIEW(getWidget("listsView"))); listsView.insertColumn("List", G_TYPE_STRING, TreeView::EDIT_STRING, -1); listsView.finalize(); listsStore = gtk_list_store_newv(listsView.getColCount(), listsView.getGTypes()); gtk_tree_view_set_model(listsView.get(), GTK_TREE_MODEL(listsStore)); g_object_unref(listsStore); gtk_tree_view_set_headers_visible(listsView.get(), FALSE); listsSelection = gtk_tree_view_get_selection(listsView.get()); GtkTreeViewColumn *c = gtk_tree_view_get_column(listsView.get(), 0); GList *l = gtk_tree_view_column_get_cell_renderers(c); GObject *editRenderer = G_OBJECT(g_list_nth_data(l, 0)); g_list_free(l); StringList list = favMan->getHubLists(); GtkTreeIter iter; for (StringList::iterator it = list.begin(); it != list.end(); ++it) { gtk_list_store_append(listsStore, &iter); gtk_list_store_set(listsStore, &iter, 0, it->c_str(), -1); } // Fill the combo box with hub lists gtk_combo_box_set_model(GTK_COMBO_BOX(getWidget("hubListBox")), GTK_TREE_MODEL(listsStore)); GtkCellRenderer *cell = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(GTK_COMBO_BOX(getWidget("hubListBox"))), cell, FALSE); gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(GTK_COMBO_BOX(getWidget("hubListBox"))), cell, "text", 0); if (static_cast(favMan->getSelectedHubList()) >= list.size()) gtk_combo_box_set_active(GTK_COMBO_BOX(getWidget("hubListBox")), list.size() - 1); else gtk_combo_box_set_active(GTK_COMBO_BOX(getWidget("hubListBox")), favMan->getSelectedHubList()); // Connect the signals to their callback functions. g_signal_connect(getWidget("filterEntry"), "key-release-event", G_CALLBACK(onFilterHubs_gui), (gpointer)this); g_signal_connect(getWidget("connectButton"), "clicked", G_CALLBACK(onConnect_gui), (gpointer)this); g_signal_connect(getWidget("connectMenuItem"), "activate", G_CALLBACK(onConnect_gui), (gpointer)this); g_signal_connect(getWidget("refreshButton"), "clicked", G_CALLBACK(onRefresh_gui), (gpointer)this); g_signal_connect(getWidget("hubListBox"), "changed", G_CALLBACK(onRefresh_gui), (gpointer)this); g_signal_connect(getWidget("configureButton"), "clicked", G_CALLBACK(onConfigure_gui), (gpointer)this); g_signal_connect(getWidget("upButton"), "clicked", G_CALLBACK(onMoveUp_gui), (gpointer)this); g_signal_connect(getWidget("downButton"), "clicked", G_CALLBACK(onMoveDown_gui), (gpointer)this); g_signal_connect(getWidget("addButton"), "clicked", G_CALLBACK(onAdd_gui), (gpointer)this); g_signal_connect(getWidget("removeButton"), "clicked", G_CALLBACK(onRemove_gui), (gpointer)this); g_signal_connect(editRenderer, "edited", G_CALLBACK(onCellEdited_gui), (gpointer)this); g_signal_connect(hubView.get(), "button-press-event", G_CALLBACK(onButtonPress_gui), (gpointer)this); g_signal_connect(hubView.get(), "button-release-event", G_CALLBACK(onButtonRelease_gui), (gpointer)this); g_signal_connect(hubView.get(), "key-release-event", G_CALLBACK(onKeyRelease_gui), (gpointer)this); g_signal_connect(getWidget("favMenuItem"), "activate", G_CALLBACK(onAddFav_gui), (gpointer)this); if (favMan->isDownloading()) setStatus_gui("statusMain", "Downloading hub list"); } PublicHubs::~PublicHubs() { FavoriteManager::getInstance()->removeListener(this); gtk_widget_destroy(getWidget("configureDialog")); } void PublicHubs::downloadList_client() { hubs = FavoriteManager::getInstance()->getPublicHubs(); if (hubs.empty()) FavoriteManager::getInstance()->refresh(); FavoriteManager::getInstance()->save(); Func0 *func = new Func0(this, &PublicHubs::updateList_gui); WulforManager::get()->dispatchGuiFunc(func); } void PublicHubs::updateList_gui() { HubEntry::List::const_iterator i; GtkTreeIter iter; int numHubs = 0; int numUsers = 0; gint sortColumn; GtkSortType sortType; gtk_list_store_clear(hubStore); gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(hubStore), &sortColumn, &sortType); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(hubStore), GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, sortType); for (i = hubs.begin(); i != hubs.end(); i++) { if (filter.getPattern().empty() || filter.match(i->getName()) || filter.match(i->getDescription()) || filter.match(i->getServer())) { gtk_list_store_append(hubStore, &iter); gtk_list_store_set(hubStore, &iter, hubView.col("Name"), i->getName().c_str(), hubView.col("Description"), i->getDescription().c_str(), hubView.col("Users"), i->getUsers(), hubView.col("Address"), i->getServer().c_str(), hubView.col("Country"), i->getCountry().c_str(), hubView.col("Shared"), Util::formatBytes(i->getShared()).c_str(), hubView.col("Min Share"), Util::formatBytes(i->getMinShare()).c_str(), hubView.col("Min Slots"), i->getMinSlots(), hubView.col("Max Hubs"), i->getMaxHubs(), hubView.col("Max Users"), i->getMaxUsers(), hubView.col("Rating"), i->getRating().c_str(), -1); numUsers += i->getUsers(); numHubs++; } } gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(hubStore), sortColumn, sortType); setStatus_gui("statusHubs", _("Hubs: ") + Util::toString(numHubs)); setStatus_gui("statusUsers", _("Users: ") + Util::toString(numUsers)); } void PublicHubs::setStatus_gui(string statusBar, string text) { gtk_statusbar_pop(GTK_STATUSBAR(getWidget(statusBar)), 0); gtk_statusbar_push(GTK_STATUSBAR(getWidget(statusBar)), 0, text.c_str()); } gboolean PublicHubs::onButtonPress_gui(GtkWidget *widget, GdkEventButton *event, gpointer data) { PublicHubs *ph = (PublicHubs *)data; if (event->type == GDK_BUTTON_PRESS || event->type == GDK_2BUTTON_PRESS) { ph->oldType = event->type; ph->oldButton = event->button; } return FALSE; } gboolean PublicHubs::onButtonRelease_gui(GtkWidget *widget, GdkEventButton *event, gpointer data) { PublicHubs *ph = (PublicHubs *)data; if (ph->oldButton == event->button && gtk_tree_selection_get_selected(ph->hubSelection, NULL, NULL)) { if (event->button == 3 && ph->oldType == GDK_BUTTON_PRESS) { gtk_menu_popup(GTK_MENU(ph->getWidget("menu")), NULL, NULL, NULL, NULL, 0, event->time); gtk_widget_show_all(ph->getWidget("menu")); } else if (event->button == 1 && ph->oldType == GDK_2BUTTON_PRESS) { ph->onConnect_gui(NULL, data); } } return FALSE; } gboolean PublicHubs::onKeyRelease_gui(GtkWidget *widget, GdkEventKey *event, gpointer data) { PublicHubs *ph = (PublicHubs *)data; if (gtk_tree_selection_get_selected(ph->hubSelection, NULL, NULL)) { if (event->keyval == GDK_Menu || (event->keyval == GDK_F10 && event->state & GDK_SHIFT_MASK)) { gtk_menu_popup(GTK_MENU(ph->getWidget("menu")), NULL, NULL, NULL, NULL, 0, event->time); gtk_widget_show_all(ph->getWidget("menu")); } else if (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter) { ph->onConnect_gui(NULL, data); } } return FALSE; } gboolean PublicHubs::onFilterHubs_gui(GtkWidget *widget, GdkEventKey *event, gpointer data) { PublicHubs *ph = (PublicHubs *)data; StringSearch pattern(gtk_entry_get_text(GTK_ENTRY(ph->getWidget("filterEntry")))); if (!(pattern == ph->filter)) { ph->filter = pattern; ph->updateList_gui(); } return FALSE; } void PublicHubs::onConnect_gui(GtkWidget *widget, gpointer data) { PublicHubs *ph = (PublicHubs *)data; GtkTreeIter iter; if (gtk_tree_selection_get_selected(ph->hubSelection, NULL, &iter)) { string address = ph->hubView.getString(&iter, "Address"); WulforManager::get()->addHub_gui(address); } } void PublicHubs::onRefresh_gui(GtkWidget *widget, gpointer data) { PublicHubs *ph = (PublicHubs *)data; int pos = gtk_combo_box_get_active(GTK_COMBO_BOX(ph->getWidget("hubListBox"))); typedef Func1 F1; F1 *func = new F1(ph, &PublicHubs::refresh_client, pos); WulforManager::get()->dispatchClientFunc(func); } void PublicHubs::onAddFav_gui(GtkMenuItem *item, gpointer data) { PublicHubs *ph = (PublicHubs *)data; GtkTreeIter iter; if (gtk_tree_selection_get_selected(ph->hubSelection, NULL, &iter)) { FavoriteHubEntry entry; string name = ph->hubView.getString(&iter, "Name"); string description = ph->hubView.getString(&iter, "Description"); string address = ph->hubView.getString(&iter, "Address"); entry.setName(name); entry.setServer(address); entry.setDescription(description); entry.setNick(SETTING(NICK)); entry.setPassword(""); entry.setUserDescription(SETTING(DESCRIPTION)); typedef Func1 F1; F1 *func = new F1(ph, &PublicHubs::addFav_client, entry); WulforManager::get()->dispatchClientFunc(func); } } void PublicHubs::onConfigure_gui(GtkWidget *widget, gpointer data) { PublicHubs *ph = (PublicHubs *)data; // Have to get active here since temp could be NULL after dialog is closed gchar *temp = gtk_combo_box_get_active_text(GTK_COMBO_BOX(ph->getWidget("hubListBox"))); string active = string(temp); g_free(temp); gint ret = gtk_dialog_run(GTK_DIALOG(ph->getWidget("configureDialog"))); gtk_widget_hide(ph->getWidget("configureDialog")); if (ret == GTK_RESPONSE_OK) { string lists, url; GtkTreeIter iter; GtkTreeModel *m = GTK_TREE_MODEL(ph->listsStore); gboolean valid = gtk_tree_model_get_iter_first(m, &iter); while (valid) { url = ph->listsView.getString(&iter, "List"); lists += url + ";"; if (url == active) gtk_combo_box_set_active_iter(GTK_COMBO_BOX(ph->getWidget("hubListBox")), &iter); valid = gtk_tree_model_iter_next(m, &iter); } if (gtk_combo_box_get_active(GTK_COMBO_BOX(ph->getWidget("hubListBox"))) < 0) gtk_combo_box_set_active(GTK_COMBO_BOX(ph->getWidget("hubListBox")), 0); if (!lists.empty()) lists.erase(lists.size() - 1); SettingsManager::getInstance()->set(SettingsManager::HUBLIST_SERVERS, lists); } } void PublicHubs::onAdd_gui(GtkWidget *widget, gpointer data) { PublicHubs *ph = (PublicHubs *)data; GtkTreeIter iter; GtkTreePath *path; GtkTreeViewColumn *col; gtk_list_store_append(ph->listsStore, &iter); gtk_list_store_set(ph->listsStore, &iter, ph->listsView.col("List"), _("New list"), -1); path = gtk_tree_model_get_path(GTK_TREE_MODEL(ph->listsStore), &iter); col = gtk_tree_view_get_column(ph->listsView.get(), 0); gtk_tree_view_set_cursor(ph->listsView.get(), path, col, TRUE); gtk_tree_path_free(path); } void PublicHubs::onMoveUp_gui(GtkWidget *widget, gpointer data) { PublicHubs *ph = (PublicHubs *)data; GtkTreeIter prev, current; GtkTreeModel *m = GTK_TREE_MODEL(ph->listsStore); if (gtk_tree_selection_get_selected(ph->listsSelection, NULL, ¤t)) { GtkTreePath *path = gtk_tree_model_get_path(m, ¤t); if (gtk_tree_path_prev(path) && gtk_tree_model_get_iter(m, &prev, path)) gtk_list_store_swap(ph->listsStore, ¤t, &prev); gtk_tree_path_free(path); } } void PublicHubs::onMoveDown_gui(GtkWidget *widget, gpointer data) { PublicHubs *ph = (PublicHubs *)data; GtkTreeIter current, next; if (gtk_tree_selection_get_selected(ph->listsSelection, NULL, ¤t)) { next = current; if (gtk_tree_model_iter_next(GTK_TREE_MODEL(ph->listsStore), &next)) gtk_list_store_swap(ph->listsStore, ¤t, &next); } } void PublicHubs::onRemove_gui(GtkWidget *widget, gpointer data) { PublicHubs *ph = (PublicHubs *)data; GtkTreeIter current; if (gtk_tree_selection_get_selected(ph->listsSelection, NULL, ¤t)) gtk_list_store_remove(ph->listsStore, ¤t); } void PublicHubs::onCellEdited_gui(GtkCellRendererText *cell, char *path, char *text, gpointer data) { PublicHubs *ph = (PublicHubs *)data; GtkTreeIter it; if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(ph->listsStore), &it, path)) gtk_list_store_set(ph->listsStore, &it, ph->listsView.col("List"), text, -1); } void PublicHubs::refresh_client(int pos) { FavoriteManager::getInstance()->setHubList(pos); FavoriteManager::getInstance()->refresh(); } void PublicHubs::addFav_client(FavoriteHubEntry entry) { FavoriteManager::getInstance()->addFavorite(entry); } void PublicHubs::on(FavoriteManagerListener::DownloadStarting, const string &file) throw() { string msg = _("Download starting: ") + file; typedef Func2 Func; Func *func = new Func(this, &PublicHubs::setStatus_gui, "statusMain", msg); WulforManager::get()->dispatchGuiFunc(func); } void PublicHubs::on(FavoriteManagerListener::DownloadFailed, const string &file) throw() { string msg = _("Download failed: ") + file; typedef Func2 Func; Func *func = new Func(this, &PublicHubs::setStatus_gui, "statusMain", msg); WulforManager::get()->dispatchGuiFunc(func); } void PublicHubs::on(FavoriteManagerListener::DownloadFinished, const string &file) throw() { string msg = _("Download finished: ") + file; typedef Func2 Func; Func *f2 = new Func(this, &PublicHubs::setStatus_gui, "statusMain", msg); WulforManager::get()->dispatchGuiFunc(f2); hubs = FavoriteManager::getInstance()->getPublicHubs(); Func0 *f0 = new Func0(this, &PublicHubs::updateList_gui); WulforManager::get()->dispatchGuiFunc(f0); }