static inline void update_row(const void *key, void *value, void *user_data) { struct node_data *data = value; time_t *now_ptr = user_data, now = *now_ptr; gnet_node_status_t status; g_assert(NULL != data); g_assert(data->node_id == key); if (!guc_node_get_status(data->node_id, &status)) return; /* * Update additional info too if it has recorded changes. */ if (remove_item(ht_node_info_changed, data->node_id)) { gnet_node_info_t info; if (guc_node_fill_info(data->node_id, &info)) { nodes_gui_update_node_info(data, &info); guc_node_clear_info(&info); } } if (remove_item(ht_node_flags_changed, data->node_id)) { gnet_node_flags_t flags; if (guc_node_fill_flags(data->node_id, &flags)) { nodes_gui_update_node_flags(data, &flags); } } if (status.connect_date) data->connected = delta_time(now, status.connect_date); if (status.up_date) data->uptime = delta_time(now, status.up_date); /* Update the status line */ { const gchar *s; size_t size; s = nodes_gui_common_status_str(&status); size = 1 + strlen(s); if (size > data->info_size) { WFREE_NULL(data->info, data->info_size); data->info = wcopy(s, size); data->info_size = size; } else { memcpy(data->info, s, size); } } tree_model_iter_changed(GTK_TREE_MODEL(nodes_model), &data->iter); }
/** * Update all the nodes at the same time. * * @bug * FIXME: We should remember for every node when it was last * updated and only refresh every node at most once every * second. This information should be kept in a struct pointed * to by the row user_data and should be automatically freed * when removing the row (see upload stats code). */ void nodes_gui_update_display(time_t now) { GtkCList *clist; GList *l; gint row = 0; gnet_node_status_t status; clist = GTK_CLIST(gui_main_window_lookup("clist_nodes")); gtk_clist_freeze(clist); for (l = clist->row_list, row = 0; l; l = l->next, row++) { const struct nid *node_id = ((GtkCListRow *) l->data)->data; guc_node_get_status(node_id, &status); /* * Update additional info too if it has recorded changes. */ if (remove_item(hs_node_info_changed, node_id)) { gnet_node_info_t info; guc_node_fill_info(node_id, &info); nodes_gui_update_node_info(&info, row); guc_node_clear_info(&info); } if (remove_item(hs_node_flags_changed, node_id)) { gnet_node_flags_t flags; guc_node_fill_flags(node_id, &flags); nodes_gui_update_node_flags(node_id, &flags, -1); } /* * Don't update times if we've already disconnected. */ if (status.status == GTA_NODE_CONNECTED) { gtk_clist_set_text(clist, row, c_gnet_connected, short_uptime(delta_time(now, status.connect_date))); if (status.up_date) gtk_clist_set_text(clist, row, c_gnet_uptime, status.up_date ? short_uptime(delta_time(now, status.up_date)) : "..."); } gtk_clist_set_text(clist, row, c_gnet_info, nodes_gui_common_status_str(&status)); } gtk_clist_thaw(clist); }
/** * Update the row with the given nodeinfo. If row is -1 the row number * is determined by the node_id contained in the gnet_node_info_t. */ static void nodes_gui_update_node_info(gnet_node_info_t *n, gint row) { GtkCList *clist = GTK_CLIST(gui_main_window_lookup("clist_nodes")); g_assert(n != NULL); if (row == -1) { row = gtk_clist_find_row_from_data(clist, deconstify_gpointer(n->node_id)); } if (row != -1) { gchar ver_buf[64]; gnet_node_status_t status; time_t now = tm_time(); if (guc_node_get_status(n->node_id, &status)) { gtk_clist_set_text(clist, row, c_gnet_user_agent, n->vendor ? lazy_utf8_to_locale(n->vendor) : "..."); gtk_clist_set_text(clist, row, c_gnet_loc, deconstify_gchar(iso3166_country_cc(n->country))); str_bprintf(ver_buf, sizeof ver_buf, "%d.%d", n->proto_major, n->proto_minor); gtk_clist_set_text(clist, row, c_gnet_version, ver_buf); if (status.status == GTA_NODE_CONNECTED) gtk_clist_set_text(clist, row, c_gnet_connected, short_uptime(delta_time(now, status.connect_date))); if (status.up_date) gtk_clist_set_text(clist, row, c_gnet_uptime, status.up_date ? short_uptime(delta_time(now, status.up_date)) : "..."); gtk_clist_set_text(clist, row, c_gnet_info, nodes_gui_common_status_str(&status)); } } else { g_warning("%s(): no matching row found", G_STRFUNC); } }
/** * Updates vendor, version and info column. */ static void nodes_gui_update_node_info(struct node_data *data, gnet_node_info_t *info) { gnet_node_status_t status; g_assert(info != NULL); if (data == NULL) data = find_node(info->node_id); g_assert(NULL != data); g_assert(data->node_id == info->node_id); if (guc_node_get_status(info->node_id, &status)) { str_bprintf(data->version, sizeof data->version, "%u.%u", info->proto_major, info->proto_minor); atom_str_free_null(&data->user_agent); data->user_agent = info->vendor ? atom_str_get(info->vendor) : NULL; data->country = info->country; } }