示例#1
0
/**
 * Sets up the icon and canvas widgets.  This function was
 * generated by glade separatly from the main gui since the icon
 * widgets are independent of the rest of the gui, and there
 * are unresolved issues between GTK and GTK2.
 */
static void
create_icon(void)
{
    icon = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_name(icon, "icon");
    gtk_object_set_data(GTK_OBJECT(icon), "icon", icon);
    gtk_widget_set_usize(icon, ICON_WIDTH + 1, ICON_HEIGHT + 1);
    gtk_widget_set_sensitive(icon, FALSE);
    GTK_WIDGET_SET_FLAGS(icon, GTK_CAN_FOCUS);
    GTK_WIDGET_SET_FLAGS(icon, GTK_CAN_DEFAULT);
    gtk_widget_set_events(icon, GDK_VISIBILITY_NOTIFY_MASK);
    gtk_window_set_title(GTK_WINDOW(icon), "icon");
    gtk_window_set_default_size(GTK_WINDOW(icon),
                                ICON_WIDTH + 1, ICON_HEIGHT + 1);
    gtk_window_set_policy(GTK_WINDOW(icon), FALSE, FALSE, FALSE);

    canvas = gtk_drawing_area_new();
    gtk_widget_set_name(canvas, "canvas");
    gtk_widget_ref(canvas);
    gtk_object_set_data_full(GTK_OBJECT(icon), "canvas", canvas,
                             (GtkDestroyNotify) gtk_widget_unref);
    gtk_widget_show(canvas);
    gtk_container_add(GTK_CONTAINER(icon), canvas);
    gtk_widget_set_events(canvas, GDK_EXPOSURE_MASK);

    gui_signal_connect(icon, "map_event", on_icon_map_event, NULL);
    gui_signal_connect(icon, "unmap_event", on_icon_unmap_event, NULL);
    gui_signal_connect(canvas, "expose_event", on_canvas_expose_event, NULL);
}
示例#2
0
/**
 * Create a new GtkTreeView for search results.
 */
GtkWidget *
search_gui_create_tree(void)
{
	GtkTreeModel *model = create_results_model();
	GtkTreeSelection *selection;
	GtkTreeView	*tv;

	tv = GTK_TREE_VIEW(gtk_tree_view_new_with_model(model));
	g_object_unref(model);

	selection = gtk_tree_view_get_selection(tv);
	gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
	gtk_tree_view_set_headers_clickable(tv, TRUE);
	gtk_tree_view_set_headers_visible(tv, TRUE);
	gtk_tree_view_set_enable_search(tv, TRUE);
	gtk_tree_view_set_search_column(tv, 0);
	gtk_tree_view_set_rules_hint(tv, TRUE);
	gtk_tree_view_set_search_equal_func(tv, search_by_regex, NULL, NULL);
	tree_view_set_fixed_height_mode(tv, TRUE);

      /* add columns to the tree view */
	add_results_columns(tv);

	tree_view_restore_visibility(tv, PROP_SEARCH_RESULTS_COL_VISIBLE);
	tree_view_restore_widths(tv, PROP_SEARCH_RESULTS_COL_WIDTHS);

	gui_signal_connect(tv,
		"cursor-changed", on_tree_view_search_results_select_row, tv);
    gui_signal_connect(tv, "leave-notify-event", on_leave_notify, NULL);
	
	return GTK_WIDGET(tv);
}
示例#3
0
static void
status_icon_enable(void)
{
	GdkPixbuf *icon_pixbuf;

	if (status_icon)
		return;

	/*
	 * Due to lazy binding it's possible that runtime version is older
	 * than the compile-time version. This is the only code which requires
	 * Gtk+ >= 2.10 currently.
	 */
	if (!check_gtk_version(2,10,0))
		return;

	/*
	 * Create an status so that gtk-gnutella can be minimized to a
	 * so-called "system tray" if supported by the window manager.
	 */

	icon_pixbuf = create_pixbuf("icon.16x16.xpm");
	status_icon = gtk_status_icon_new_from_pixbuf(icon_pixbuf);

	gtk_status_icon_set_tooltip(status_icon,
		_("gtk-gnutella: Click to minimize/restore"));
	status_icon_set_visible(TRUE);
	gui_signal_connect(status_icon, "activate",
		on_status_icon_activate, NULL);
	gui_signal_connect(status_icon, "size-changed",
		on_status_icon_size_changed, NULL);
	gui_signal_connect(status_icon, "popup-menu",
		on_status_icon_popup_menu, NULL);
}
示例#4
0
void
on_button_config_add_dir_clicked(GtkButton *unused_button,
	gpointer unused_udata)
{
	(void) unused_button;
	(void) unused_udata;

	if (directory_chooser) {
		gtk_widget_destroy(directory_chooser);
		directory_chooser = NULL;
	}

	directory_chooser = gtk_file_selection_new(
			_("Please choose a directory to share"));

	gui_signal_connect(
		GTK_FILE_SELECTION(directory_chooser)->ok_button,
		"clicked", button_fs_add_dir_clicked, GINT_TO_POINTER(1));
	gui_signal_connect(GTK_FILE_SELECTION(directory_chooser)->cancel_button,
		"clicked", button_fs_add_dir_clicked, NULL);
	gui_signal_connect(directory_chooser,
		"delete_event", on_directory_chooser_delete_event, NULL);

	gtk_widget_show(directory_chooser);
}
示例#5
0
void
on_button_config_move_path_clicked(GtkButton *unused_button,
	gpointer unused_udata)
{
	(void) unused_button;
	(void) unused_udata;

	if (directory_chooser) {
		gtk_widget_destroy(directory_chooser);
		directory_chooser = NULL;
	}

	directory_chooser = gtk_file_selection_new(
			_("Please choose where to move files after successful download"));

	gui_signal_connect(
		GTK_FILE_SELECTION(directory_chooser)->ok_button,
		"clicked", button_fs_move_path_clicked, GINT_TO_POINTER(1));
	gui_signal_connect(
		GTK_FILE_SELECTION(directory_chooser)->cancel_button,
		"clicked", button_fs_move_path_clicked, NULL);
	gui_signal_connect(directory_chooser,
		"delete_event", on_directory_chooser_delete_event, NULL);

	gtk_widget_show(directory_chooser);
}
示例#6
0
/**
 * Initialize the nodes controller. Register callbacks in the backend.
 */
void
nodes_gui_init(void)
{
	GtkTreeView *tv;
	
	tv = GTK_TREE_VIEW(gui_main_window_lookup( "treeview_nodes"));
	treeview_nodes = tv;

	tree_view_restore_widths(tv, PROP_NODES_COL_WIDTHS);
	tree_view_restore_visibility(tv, PROP_NODES_COL_VISIBLE);
	tree_view_set_fixed_height_mode(tv, TRUE);

	nodes_handles = htable_create_any(nid_hash, nid_hash2, nid_equal);
    ht_node_info_changed = hset_create_any(nid_hash, nid_hash2, nid_equal);
    ht_node_flags_changed = hset_create_any(nid_hash, nid_hash2, nid_equal);
    ht_pending_lookups = hset_create_any(nid_hash, nid_hash2, nid_equal);

    guc_node_add_node_added_listener(nodes_gui_node_added);
    guc_node_add_node_removed_listener(nodes_gui_node_removed);
    guc_node_add_node_info_changed_listener(nodes_gui_node_info_changed);
    guc_node_add_node_flags_changed_listener(nodes_gui_node_flags_changed);

	widget_add_popup_menu(GTK_WIDGET(tv), nodes_gui_get_popup_menu);
	gui_signal_connect(tv, "cursor-changed", on_cursor_changed, tv);
	gui_signal_connect(tv, "leave-notify-event", on_leave_notify, tv);

	tvm_nodes = tree_view_motion_set_callback(tv, update_tooltip, 400);

	main_gui_add_timer(nodes_gui_timer);
}
示例#7
0
static void
treeview_download_files_init(void)
{
	GtkTreeView *tv;
	unsigned i;

	STATIC_ASSERT(FILEINFO_VISIBLE_COLUMNS == c_fi_num);

	tv = GTK_TREE_VIEW(gtk_tree_view_new());
	treeview_download_files = tv;

	for (i = 0; i < c_fi_num; i++) {
		add_column(tv, i,
			fi_gui_files_column_title(i),
			fi_gui_files_column_justify_right(i) ? 1.0 : 0.0,
			c_fi_progress == i ? gtk_cell_renderer_progress_new() : NULL,
			render_files);
	}

	gtk_tree_selection_set_mode(gtk_tree_view_get_selection(tv),
		GTK_SELECTION_MULTIPLE);
	gtk_tree_view_set_headers_visible(tv, TRUE);
	gtk_tree_view_set_headers_clickable(tv, TRUE);
	gtk_tree_view_set_enable_search(tv, FALSE);
	gtk_tree_view_set_rules_hint(tv, TRUE);
	tree_view_set_fixed_height_mode(tv, TRUE);

	gtk_tree_view_set_model(tv, GTK_TREE_MODEL(store_files));
	tree_view_restore_visibility(tv, PROP_FILE_INFO_COL_VISIBLE);
	tree_view_restore_widths(tv, PROP_FILE_INFO_COL_WIDTHS);

	gui_signal_connect(tv,
		"cursor-changed", on_treeview_download_files_cursor_changed, NULL);
}
示例#8
0
/**
 * Initialize the upload statistics GUI.
 *
 * Initialize the upload statistics GUI.  Define the
 * GtkTreeModel used to store the information as well
 * as rendering and sorting functions to use on the
 * cells and columns.
 */
static void
upload_stats_gui_init_intern(gboolean intern)
{
	static const struct {
		const guint id;
		const gchar * const title;
		const gfloat align;
		const GtkTreeIterCompareFunc func;
	} columns[] = {
		{ c_us_filename, N_("Filename"),   0.0, upload_stats_gui_cmp_filename },
		{ c_us_size,	 N_("Size"),	   1.0, upload_stats_gui_cmp_size },
		{ c_us_attempts, N_("Attempts"),   1.0, upload_stats_gui_cmp_attempts },
		{ c_us_complete, N_("Complete"),   1.0, upload_stats_gui_cmp_complete },
    	{ c_us_norm, 	 N_("Normalized"), 1.0, upload_stats_gui_cmp_norm },
    	{ c_us_rtime, 	 N_("Last Request"), 0.0, upload_stats_gui_cmp_rtime },
    	{ c_us_dtime, 	 N_("Last Upload"), 0.0, upload_stats_gui_cmp_dtime },
	};
	static gboolean initialized = FALSE;
	GtkTreeModel *model;
	guint i;

	STATIC_ASSERT(G_N_ELEMENTS(columns) == UPLOAD_STATS_GUI_VISIBLE_COLUMNS);

	if (!initialized) {
		initialized = TRUE;
		ht_uploads = htable_create(HASH_KEY_SELF, 0);
    	popup_upload_stats = create_popup_upload_stats();
		model = GTK_TREE_MODEL(gtk_list_store_new(1, G_TYPE_POINTER));
		upload_stats_treeview = GTK_TREE_VIEW(
			gui_main_window_lookup("treeview_ul_stats"));
		gtk_tree_view_set_model(upload_stats_treeview, model);
		g_object_unref(model);

		for (i = 0; i < G_N_ELEMENTS(columns); i++) {
			add_column(upload_stats_treeview,
				columns[i].id,
				_(columns[i].title),
				columns[i].align,
				columns[i].func,
				cell_renderer_func);
		}

		gui_signal_connect(upload_stats_treeview,
			"button_press_event", on_button_press_event, NULL);
	}

	if (!intern) {
		/* upload_stats_gui_init_intern() might be called internally before
		 * settings_gui_init(). If it's called externally it's called from
		 * main_gui_init() and the GUI properties are intialized. */

		tree_view_restore_widths(upload_stats_treeview,
			PROP_UL_STATS_COL_WIDTHS);
		tree_view_restore_visibility(upload_stats_treeview,
			PROP_UL_STATS_COL_VISIBLE);
	}

}
示例#9
0
文件: crack.c 项目: chinaktv/gxgui
int main(int argc, char **argv)
#endif
{
    if (gui_init(argc, argv) != 0) return -1;

    gui_signal_connect("on_menulist_clicked"   , on_menulist_clicked);
    gui_signal_connect("on_setlanguage_clicked", on_setlanguage_clicked);
    gui_signal_connect("on_MainWindow_keypress", on_MainWindow_keypress);

#ifndef WIN32
    if (argc > 1)
        i18n_set_language(argv[1]);
    else
#endif
        i18n_set_language("chinese");
    gui_loop();
    gui_release();

    return 0;
}
示例#10
0
static void
directory_chooser_show(enum dir_choice dir_choice, const char *title,
	const char *current_directory)
{
	GtkWidget *widget;

	if (directory_chooser) {
		gtk_widget_destroy(directory_chooser);
		directory_chooser = NULL;
	}

	widget = gtk_file_chooser_dialog_new(title,
				GTK_WINDOW(gui_main_window()),
				GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
				GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
				GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
				(void *) 0);
	g_return_if_fail(NULL != widget);
	directory_chooser = widget;

	gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(widget), TRUE);
	gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(widget),
		gtk_file_filter_new());	/* Display only directories */

	if (NULL != current_directory) {
		gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(widget),
			current_directory);
	}

	gui_signal_connect(widget, "destroy-event",
		on_directory_chooser_destroy_event, NULL);
	gui_signal_connect(widget, "delete-event",
		on_directory_chooser_delete_event, NULL);
	gui_signal_connect(widget, "response",
		on_directory_chooser_response, uint_to_pointer(dir_choice));

	gtk_widget_show(widget);
}
示例#11
0
static void
search_list_tree_view_init(void)
{
	GtkTreeView *tv;
	
    tv = GTK_TREE_VIEW(gui_main_window_lookup("tree_view_search"));
    tree_view_search = tv;

	gtk_tree_view_set_reorderable(tv, TRUE);	
	gtk_tree_selection_set_mode(gtk_tree_view_get_selection(tv),
		GTK_SELECTION_MULTIPLE);
	gtk_tree_view_set_model(tv, create_searches_model());
	add_list_columns(tv);

	widget_add_popup_menu(GTK_WIDGET(tv),
		search_gui_get_search_list_popup_menu);
	gui_signal_connect(tv,
		"button-release-event", on_search_list_button_release_event, NULL);
	gui_signal_connect(tv,
		"key-release-event", on_search_list_key_release_event, NULL);
	gui_signal_connect_after(gtk_tree_view_get_model(tv),
		"row-deleted", on_search_list_row_deleted, NULL);
}
示例#12
0
static void
fi_gui_details_treeview_init(void)
{
	static const struct {
		const char *title;
		gfloat xalign;
		gboolean editable;
	} tab[] = {
		{ "ID",		1.0, FALSE },
		{ "Item",	1.0, FALSE },
		{ "Value",	0.0, TRUE },
	};
	GtkTreeView *tv;
	GtkTreeModel *model;
	unsigned i;

	tv = GTK_TREE_VIEW(gui_main_window_lookup("treeview_download_details"));
	g_return_if_fail(tv);
	treeview_download_details = tv;

	model = GTK_TREE_MODEL(gtk_list_store_new(G_N_ELEMENTS(tab),
				G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING));

	gtk_tree_view_set_model(tv, model);
	g_object_unref(model);

	for (i = 0; i < G_N_ELEMENTS(tab); i++) {
    	GtkTreeViewColumn *column;
		GtkCellRenderer *renderer;
		
		renderer = create_text_cell_renderer(tab[i].xalign);
		g_object_set(G_OBJECT(renderer),
			"editable", tab[i].editable,
			(void *) 0);
		gui_signal_connect(renderer, "edited", on_cell_edited, tv);
		column = gtk_tree_view_column_new_with_attributes(tab[i].title,
					renderer, "text", i, (void *) 0);
		g_object_set(column,
			"visible",	i > 0 ? TRUE : FALSE,
			"min-width", 1,
			"resizable", TRUE,
			"sizing", 1 == i
						? GTK_TREE_VIEW_COLUMN_AUTOSIZE
						: GTK_TREE_VIEW_COLUMN_FIXED,
			(void *) 0);
    	gtk_tree_view_append_column(tv, column);
	}

	drag_attach_text(GTK_WIDGET(tv), download_details_get_text);
}
示例#13
0
static void
search_details_treeview_init(void)
{
	static const struct {
		const gchar *title;
		gfloat xalign;
		gboolean editable;
	} tab[] = {
		{ "Item",	1.0, FALSE },
		{ "Value",	0.0, TRUE },
	};
	GtkTreeView *tv;
	GtkTreeModel *model;
	guint i;

	tv = GTK_TREE_VIEW(gui_main_window_lookup("treeview_search_details"));
	g_return_if_fail(tv);

	model = GTK_TREE_MODEL(
				gtk_list_store_new(N_ITEMS(tab),
				G_TYPE_STRING, G_TYPE_STRING));

	gtk_tree_view_set_model(tv, model);
	g_object_unref(model);

	for (i = 0; i < N_ITEMS(tab); i++) {
    	GtkTreeViewColumn *column;
		GtkCellRenderer *renderer;

		renderer = create_cell_renderer(tab[i].xalign);
		g_object_set(G_OBJECT(renderer),
			"editable", tab[i].editable,
			NULL_PTR);
		column = gtk_tree_view_column_new_with_attributes(tab[i].title,
					renderer, "text", i, NULL_PTR);
		g_object_set(column,
			"min-width", 1,
			"resizable", TRUE,
			"sizing", (0 == i)
						? GTK_TREE_VIEW_COLUMN_AUTOSIZE
						: GTK_TREE_VIEW_COLUMN_FIXED,
			NULL_PTR);
    	gtk_tree_view_append_column(tv, column);
	}

	gui_signal_connect(tv,
		"key-press-event", on_search_details_key_press_event, NULL);
	drag_attach_text(GTK_WIDGET(tv), search_gui_details_get_text);
}
示例#14
0
文件: drop.c 项目: MrJoe/gtk-gnutella
void
drop_widget_init(GtkWidget *widget, drag_data_received_cb callback,
	void *user_data)
{
	static const GtkTargetEntry targets[] = {
#if GTK_CHECK_VERSION(2,0,0)
        { "UTF8_STRING",				0, 3 },
        { "text/plain;charset=utf-8",	0, 4 },
#endif	/* Gtk+ >= 2.0 */
		{ "STRING",						0, 1 },
		{ "text/plain", 				0, 2 },
	};

	g_return_if_fail(widget);
	g_return_if_fail(callback);

	gtk_drag_dest_set(widget, GTK_DEST_DEFAULT_ALL, targets,
		G_N_ELEMENTS(targets), GDK_ACTION_COPY | GDK_ACTION_MOVE);

#if GTK_CHECK_VERSION(2,0,0)
	{
		static GtkClipboard *clipboard;
	
		if (!clipboard) {
			clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
		}
	}
	
	gtk_drag_dest_set_target_list(widget, gtk_target_list_new(targets,
		G_N_ELEMENTS(targets)));
#endif /* USE_GTK2 */

#if !GTK_CHECK_VERSION(2,0,0)

	gtk_selection_add_targets(widget, GDK_SELECTION_TYPE_STRING,
		targets, G_N_ELEMENTS(targets));
#endif /* USE_GTK1 */

	gui_signal_connect(GTK_OBJECT(widget), "drag-data-received",
		callback, user_data);
}
示例#15
0
static void
dbg_tree_init(void)
{
	static const struct {
		const gchar *title;
		const gint width;
		const gboolean editable;
		const enum dbg_cols id;
	} columns[] = {
		{ N_("Saved"),	 	  0, FALSE, dbg_col_saved },
		{ N_("Type"),		  0, FALSE, dbg_col_type },
		{ N_("Property"),	  0, FALSE, dbg_col_name },
		{ N_("Value"),		200, TRUE,  dbg_col_value  },
		{ NULL,				  0, FALSE, dbg_col_property },	/* property_t */
	};
	GtkListStore *store;
	GtkTreeView *tv;
	guint i;

	STATIC_ASSERT(G_N_ELEMENTS(columns) == (guint) num_dbg_cols);
	
	tv = GTK_TREE_VIEW(gui_dlg_prefs_lookup("treeview_dbg_property"));
	store = GTK_LIST_STORE(gtk_list_store_new(G_N_ELEMENTS(columns),
				G_TYPE_STRING,		/* Type */
				G_TYPE_STRING,		/* Name */
				G_TYPE_STRING,		/* Value */
				G_TYPE_STRING,		/* Persistent */
				G_TYPE_UINT));		/* property_t */

	gtk_tree_view_set_model(tv, GTK_TREE_MODEL(store));
	g_object_unref(store);

	for (i = 0; i < G_N_ELEMENTS(columns); i++) {
		GtkTreeViewColumn *column;
		GtkCellRenderer *renderer;

		/* Skip invisible column zero which holds the property_t */
		if (!columns[i].title)
			continue;

		renderer = gtk_cell_renderer_text_new();

		if (columns[i].editable) {
			gui_signal_connect(renderer, "edited", on_cell_edited, NULL);
			g_object_set(renderer,
					"editable", TRUE,
					(void *) 0);
		}

		column = gtk_tree_view_column_new_with_attributes(
				_(columns[i].title), renderer,
				"text", i,
				(void *) 0);

		g_object_set(renderer,
				"xalign", 0.0,
				"xpad", GUI_CELL_RENDERER_XPAD,
				"ypad", GUI_CELL_RENDERER_YPAD,
				(void *) 0);
		g_object_set(column,
				"min-width", 1,
				"resizable", TRUE,
				"reorderable", FALSE,
				(void *) 0);
		
		if (columns[i].width) {
			g_object_set(column,
				"fixed-width", columns[i].width,
				"sizing", GTK_TREE_VIEW_COLUMN_FIXED,
				(void *) 0);
		} else {
			g_object_set(column,
				"sizing", GTK_TREE_VIEW_COLUMN_AUTOSIZE,
				(void *) 0);
		}
		

		gtk_tree_view_column_set_sort_column_id(column, i);
		gtk_tree_view_append_column(tv, column);
	}

	gui_signal_connect(tv, "enter-notify-event", on_enter_notify, tv);
	gui_signal_connect(tv, "leave-notify-event", on_leave_notify, tv);
	gui_signal_connect(tv, "cursor-changed", on_cursor_changed, tv);
}
示例#16
0
void
fi_gui_init(void)
{
	fi_sources = htable_create(HASH_KEY_SELF, 0);

	{
		GtkTreeViewColumn *column;
		GtkTreeView *tv;

		tv = GTK_TREE_VIEW(gui_main_window_lookup("treeview_download_aliases"));
		treeview_download_aliases = tv;

		store_aliases = gtk_list_store_new(1, G_TYPE_STRING);
		gtk_tree_view_set_model(tv, GTK_TREE_MODEL(store_aliases));

		column = gtk_tree_view_column_new_with_attributes(_("Aliases"),
					create_text_cell_renderer(0.0),
					"text", 0,
					NULL_PTR);
		configure_column(column);
		gtk_tree_view_column_set_sort_column_id(column, 0);
    	gtk_tree_view_append_column(tv, column);

		tree_view_set_fixed_height_mode(tv, TRUE);
		drag_attach_text(GTK_WIDGET(tv), fi_gui_get_alias);
	}

	{
		static const struct {
			enum c_src id;
			const char *title;
		} tab[] = {
   			{ c_src_host, 	 	N_("Host"), },
   			{ c_src_country, 	N_("Country"), },
   			{ c_src_server,  	N_("Server"), },
   			{ c_src_range, 	 	N_("Range"), },
   			{ c_src_progress,	N_("Progress"), },
   			{ c_src_status,	 	N_("Status"), },
		};
		GtkTreeView *tv;
		unsigned i;

		STATIC_ASSERT(c_src_num == N_ITEMS(tab));

		tv = GTK_TREE_VIEW(gui_main_window_lookup("treeview_download_sources"));
		treeview_download_sources = tv;

		store_sources = gtk_list_store_new(1, G_TYPE_POINTER);
		gtk_tree_view_set_model(tv, GTK_TREE_MODEL(store_sources));

		for (i = 0; i < N_ITEMS(tab); i++) {
			GtkCellRenderer *renderer;

			renderer = tab[i].id == c_src_progress
						? gtk_cell_renderer_progress_new()
						: NULL;
			(void) add_column(tv, tab[i].id, _(tab[i].title), 0.0,
				renderer, render_sources);
		}

		gtk_tree_view_set_headers_clickable(tv, FALSE);
		gtk_tree_selection_set_mode(gtk_tree_view_get_selection(tv),
			GTK_SELECTION_MULTIPLE);
		tree_view_restore_widths(tv, PROP_SOURCES_COL_WIDTHS);
		tree_view_set_fixed_height_mode(tv, TRUE);

		widget_add_popup_menu(GTK_WIDGET(tv), fi_gui_sources_get_popup_menu);
	}

	fi_gui_details_treeview_init();
	fi_gui_common_init();

	{
		uint32 page;
		GtkNotebook *notebook_downloads_info =
			GTK_NOTEBOOK(gui_main_window_lookup("notebook_downloads_info"));

		gui_prop_get_guint32_val(PROP_DOWNLOADS_INFO_NOTEBOOK_TAB, &page);

		if (page >= NUM_DOWNLOADS_INFO_NB_PAGES)
			page = DOWNLOADS_INFO_NB_PAGE_DETAILS;

		notebook_downloads_info_current_page = page;
		gtk_notebook_set_current_page(notebook_downloads_info, page);

		gui_signal_connect(notebook_downloads_info,
			"switch-page", on_notebook_downloads_info_switch_page, NULL);
	}
}