summaryrefslogtreecommitdiff
path: root/shell.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell.c')
-rw-r--r--shell.c289
1 files changed, 215 insertions, 74 deletions
diff --git a/shell.c b/shell.c
index 50f36f6c..376f1034 100644
--- a/shell.c
+++ b/shell.c
@@ -1,6 +1,6 @@
/*
* HardInfo - Displays System Information
- * Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@linuxmag.com.br>
+ * Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
*
* 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
@@ -197,7 +197,7 @@ void shell_action_set_active(const gchar * action_name, gboolean setting)
void shell_status_pulse(void)
{
if (params.gui_running) {
- if (shell->_pulses++ == 20) {
+ if (shell->_pulses++ == 5) {
/* we're pulsing for some time, disable the interface and change the cursor
to a hourglass */
shell_view_set_enabled(FALSE);
@@ -252,7 +252,7 @@ void shell_view_set_enabled(gboolean setting)
shell_action_set_enabled("RefreshAction", setting);
shell_action_set_enabled("CopyAction", setting);
shell_action_set_enabled("ReportAction", setting);
- shell_action_set_enabled("SyncManagerAction", setting);
+ shell_action_set_enabled("SyncManagerAction", setting && sync_manager_count_entries() > 0);
shell_action_set_enabled("SaveGraphAction",
setting ? shell->view_type ==
SHELL_VIEW_PROGRESS : FALSE);
@@ -355,7 +355,7 @@ static void create_window(void)
gtk_window_set_icon(GTK_WINDOW(shell->window),
icon_cache_get_pixbuf("logo.png"));
gtk_window_set_title(GTK_WINDOW(shell->window), "System Information");
- gtk_widget_set_size_request(shell->window, 600, 400);
+ gtk_window_set_default_size(GTK_WINDOW(shell->window), 800, 600);
g_signal_connect(G_OBJECT(shell->window), "destroy", destroy_me, NULL);
vbox = gtk_vbox_new(FALSE, 0);
@@ -485,6 +485,10 @@ static void add_modules_to_gui(gpointer data, gpointer user_data)
ShellModule *module = (ShellModule *) data;
GtkTreeStore *store = GTK_TREE_STORE(shelltree->model);
GtkTreeIter parent;
+
+ if (!module) {
+ return;
+ }
gtk_tree_store_append(store, &parent, NULL);
gtk_tree_store_set(store, &parent, TREE_COL_NAME, module->name,
@@ -604,9 +608,11 @@ static gboolean update_field(gpointer data)
fu = (ShellFieldUpdate *) data;
g_return_val_if_fail(fu != NULL, FALSE);
+ DEBUG("update_field [%s]", fu->field_name);
+
iter = g_hash_table_lookup(update_tbl, fu->field_name);
g_return_val_if_fail(iter != NULL, FALSE);
-
+
/* if the entry is still selected, update it */
if (iter && fu->entry->selected && fu->entry->fieldfunc) {
GtkTreeStore *store = GTK_TREE_STORE(shell->info->model);
@@ -639,8 +645,6 @@ static gboolean update_field(gpointer data)
update_sfusrc = NULL;
}
- DEBUG("destroying ShellFieldUpdate for field %s", fu->field_name);
-
/* otherwise, cleanup and destroy the timeout */
g_free(fu->field_name);
g_free(fu);
@@ -648,6 +652,11 @@ static gboolean update_field(gpointer data)
return FALSE;
}
+#define RANGE_SET_VALUE(tree,scrollbar,value) \
+ gtk_range_set_value(GTK_RANGE \
+ (GTK_SCROLLED_WINDOW(shell->tree->scroll)-> \
+ scrollbar), value);
+
static gboolean reload_section(gpointer data)
{
ShellModuleEntry *entry = (ShellModuleEntry *) data;
@@ -657,10 +666,14 @@ static gboolean reload_section(gpointer data)
GtkTreePath *path = NULL;
GtkTreeIter iter;
+ /* avoid drawing the window while we reload */
+ gdk_window_freeze_updates(shell->window->window);
+
/* gets the current selected path */
if (gtk_tree_selection_get_selected
- (shell->info->selection, &shell->info->model, &iter))
+ (shell->info->selection, &shell->info->model, &iter)) {
path = gtk_tree_model_get_path(shell->info->model, &iter);
+ }
/* update the information, clear the treeview and populate it again */
module_entry_reload(entry);
@@ -670,8 +683,13 @@ static gboolean reload_section(gpointer data)
/* if there was a selection, reselect it */
if (path) {
gtk_tree_selection_select_path(shell->info->selection, path);
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(shell->info->view), path, NULL,
+ FALSE);
gtk_tree_path_free(path);
}
+
+ /* make the window drawable again */
+ gdk_window_thaw_updates(shell->window->window);
}
/* destroy the timeout: it'll be set up again */
@@ -714,34 +732,40 @@ info_tree_compare_val_func(GtkTreeModel * model,
return ret;
}
-static void set_view_type(ShellViewType viewtype)
+static void set_view_type(ShellViewType viewtype, gboolean reload)
{
+ if (viewtype < SHELL_VIEW_NORMAL || viewtype >= SHELL_VIEW_N_VIEWS)
+ viewtype = SHELL_VIEW_NORMAL;
+
+ shell->normalize_percentage = TRUE;
+ shell->view_type = viewtype;
+
/* reset to the default model */
gtk_tree_view_set_model(GTK_TREE_VIEW(shell->info->view),
shell->info->model);
/* reset to the default view columns */
- gtk_tree_view_column_set_visible(shell->info->col_progress, FALSE);
- gtk_tree_view_column_set_visible(shell->info->col_value, TRUE);
-
+ if (!reload) {
+ gtk_tree_view_column_set_visible(shell->info->col_extra1, FALSE);
+ gtk_tree_view_column_set_visible(shell->info->col_extra2, FALSE);
+ gtk_tree_view_column_set_visible(shell->info->col_progress, FALSE);
+ gtk_tree_view_column_set_visible(shell->info->col_value, TRUE);
+ }
+
/* turn off the rules hint */
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(shell->info->view), FALSE);
/* turn off the save graphic action */
shell_action_set_enabled("SaveGraphAction", FALSE);
- if (viewtype == shell->view_type)
- return;
-
- if (viewtype < SHELL_VIEW_NORMAL || viewtype >= SHELL_VIEW_N_VIEWS)
- viewtype = SHELL_VIEW_NORMAL;
-
- shell->view_type = viewtype;
-
switch (viewtype) {
default:
case SHELL_VIEW_NORMAL:
gtk_widget_hide(shell->notebook);
+
+ if (!reload) {
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(shell->info->view), FALSE);
+ }
break;
case SHELL_VIEW_DUAL:
gtk_notebook_set_page(GTK_NOTEBOOK(shell->notebook), 0);
@@ -756,20 +780,30 @@ static void set_view_type(ShellViewType viewtype)
shell->hpaned->allocation.height -
shell->loadgraph->height - 16);
break;
+ case SHELL_VIEW_PROGRESS_DUAL:
+ gtk_notebook_set_page(GTK_NOTEBOOK(shell->notebook), 0);
+ gtk_widget_show(shell->notebook);
+ /* fallthrough */
case SHELL_VIEW_PROGRESS:
shell_action_set_enabled("SaveGraphAction", TRUE);
- gtk_tree_view_column_set_visible(shell->info->col_progress, TRUE);
- gtk_tree_view_column_set_visible(shell->info->col_value, FALSE);
- gtk_widget_hide(shell->notebook);
+
+ if (!reload) {
+ gtk_tree_view_column_set_visible(shell->info->col_progress, TRUE);
+ gtk_tree_view_column_set_visible(shell->info->col_value, FALSE);
+ }
+
+ if (viewtype == SHELL_VIEW_PROGRESS)
+ gtk_widget_hide(shell->notebook);
break;
}
}
static void
group_handle_special(GKeyFile * key_file, ShellModuleEntry * entry,
- gchar * group, gchar ** keys)
+ gchar * group, gchar ** keys, gboolean reload)
{
if (g_str_equal(group, "$ShellParam$")) {
+ gboolean headers_visible = FALSE;
gint i;
for (i = 0; keys[i]; i++) {
@@ -790,6 +824,8 @@ group_handle_special(GKeyFile * key_file, ShellModuleEntry * entry,
sfutbl->sfu = fu;
update_sfusrc = g_slist_prepend(update_sfusrc, sfutbl);
+ } else if (g_str_equal(key, "NormalizePercentage")) {
+ shell->normalize_percentage = g_key_file_get_boolean(key_file, group, key, NULL);
} else if (g_str_equal(key, "LoadGraphSuffix")) {
gchar *suffix =
g_key_file_get_value(key_file, group, key, NULL);
@@ -807,13 +843,37 @@ group_handle_special(GKeyFile * key_file, ShellModuleEntry * entry,
ms = g_key_file_get_integer(key_file, group, key, NULL);
g_timeout_add(ms, rescan_section, entry);
+ } else if (g_str_equal(key, "ShowColumnHeaders")) {
+ headers_visible = g_key_file_get_boolean(key_file, group, key, NULL);
+ } else if (g_str_has_prefix(key, "ColumnTitle")) {
+ GtkTreeViewColumn *column;
+ gchar *value, *title = strchr(key, '$') + 1;
+
+ value = g_key_file_get_value(key_file, group, key, NULL);
+
+ if (g_str_equal(title, "Extra1")) {
+ column = shell->info->col_extra1;
+ } else if (g_str_equal(title, "Extra2")) {
+ column = shell->info->col_extra2;
+ } else if (g_str_equal(title, "Value")) {
+ column = shell->info->col_value;
+ } else if (g_str_equal(title, "TextValue")) {
+ column = shell->info->col_textvalue;
+ } else if (g_str_equal(title, "Progress")) {
+ column = shell->info->col_progress;
+ }
+
+ gtk_tree_view_column_set_title(column, value);
+ gtk_tree_view_column_set_visible(column, TRUE);
+
+ g_free(value);
} else if (g_str_equal(key, "OrderType")) {
shell->_order_type = g_key_file_get_integer(key_file,
group,
key, NULL);
} else if (g_str_equal(key, "ViewType")) {
set_view_type(g_key_file_get_integer(key_file, group,
- key, NULL));
+ key, NULL), reload);
} else if (g_str_has_prefix(key, "Icon")) {
GtkTreeIter *iter = g_hash_table_lookup(update_tbl,
strchr(key,
@@ -837,6 +897,8 @@ group_handle_special(GKeyFile * key_file, ShellModuleEntry * entry,
(key_file, group, key, NULL));
}
}
+
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(shell->info->view), headers_visible);
} else {
g_warning("Unknown parameter group: ``%s''", group);
}
@@ -870,16 +932,29 @@ group_handle_normal(GKeyFile * key_file, ShellModuleEntry * entry,
value = entry->fieldfunc(key);
}
- if ((key && value) &&
- g_utf8_validate(key, -1, NULL)
- && g_utf8_validate(value, -1, NULL)) {
+ if ((key && value) && g_utf8_validate(key, -1, NULL) && g_utf8_validate(value, -1, NULL)) {
if (ngroups == 1) {
gtk_tree_store_append(store, &child, NULL);
} else {
gtk_tree_store_append(store, &child, &parent);
}
- gtk_tree_store_set(store, &child, INFO_TREE_COL_VALUE, value,
- -1);
+
+ /* FIXME: use g_key_file_get_string_list? */
+ if (strchr(value, '|')) {
+ gchar **columns = g_strsplit(value, "|", 0);
+
+ gtk_tree_store_set(store, &child, INFO_TREE_COL_VALUE, columns[0], -1);
+ if (columns[1]) {
+ gtk_tree_store_set(store, &child, INFO_TREE_COL_EXTRA1, columns[1], -1);
+ if (columns[2]) {
+ gtk_tree_store_set(store, &child, INFO_TREE_COL_EXTRA2, columns[2], -1);
+ }
+ }
+
+ g_strfreev(columns);
+ } else {
+ gtk_tree_store_set(store, &child, INFO_TREE_COL_VALUE, value, -1);
+ }
strend(key, '#');
@@ -942,27 +1017,30 @@ static void update_progress()
GtkTreeStore *store = GTK_TREE_STORE(model);
GtkTreeIter iter, fiter;
gchar *tmp;
- gdouble maxv = 0, maxp = 0, cur;
+ gdouble maxv = 0, maxp = 0, cur, floatval;
gtk_tree_model_get_iter_first(model, &fiter);
/* finds the maximum value */
- iter = fiter;
- do {
- gtk_tree_model_get(model, &iter, INFO_TREE_COL_VALUE, &tmp, -1);
-
- cur = atof(tmp);
- maxv = MAX(maxv, cur);
-
- g_free(tmp);
- } while (gtk_tree_model_iter_next(model, &iter));
+ if (shell->normalize_percentage) {
+ iter = fiter;
+ do {
+ gtk_tree_model_get(model, &iter, INFO_TREE_COL_VALUE, &tmp, -1);
+
+ cur = atof(tmp);
+ maxv = MAX(maxv, cur);
+
+ g_free(tmp);
+ } while (gtk_tree_model_iter_next(model, &iter));
+ } else {
+ maxv = 100.0f;
+ }
/* calculates the relative percentage and finds the maximum percentage */
if (shell->_order_type == SHELL_ORDER_ASCENDING) {
iter = fiter;
do {
- gtk_tree_model_get(model, &iter, INFO_TREE_COL_VALUE, &tmp,
- -1);
+ gtk_tree_model_get(model, &iter, INFO_TREE_COL_VALUE, &tmp, -1);
cur = 100 - 100 * atof(tmp) / maxv;
maxp = MAX(cur, maxp);
@@ -976,14 +1054,29 @@ static void update_progress()
/* fix the maximum relative percentage */
iter = fiter;
do {
+ char *strval;
+
gtk_tree_model_get(model, &iter, INFO_TREE_COL_VALUE, &tmp, -1);
+ floatval = atof(tmp);
+ strval = g_strdup(tmp);
+ g_free(tmp);
+
+ cur = 100 * floatval / maxv;
- cur = 100 * atof(tmp) / maxv;
if (shell->_order_type == SHELL_ORDER_ASCENDING)
cur = 100 - cur + maxp;
-
- gtk_tree_store_set(store, &iter, INFO_TREE_COL_PROGRESS, cur, -1);
- g_free(tmp);
+
+ if (strchr(strval, ' ')) {
+ tmp = g_strdup_printf("%.2f%s", floatval, strchr(strval, ' '));
+ } else {
+ tmp = g_strdup_printf("%.2f", floatval);
+ }
+
+ tmp = strreplace(tmp, ",", '.');
+ gtk_tree_store_set(store, &iter, INFO_TREE_COL_PROGRESS, cur,
+ INFO_TREE_COL_VALUE, tmp, -1);
+ g_free(tmp);
+ g_free(strval);
} while (gtk_tree_model_iter_next(model, &iter));
/* now sort everything up. that wasn't as hard as i thought :) */
@@ -1020,17 +1113,24 @@ module_selected_show_info(ShellModuleEntry * entry, gboolean reload)
GKeyFile *key_file = g_key_file_new();
GtkTreeStore *store;
gchar *key_data, **groups;
+ gboolean has_shell_param = FALSE;
gint i;
gsize ngroups;
module_entry_scan(entry);
key_data = module_entry_function(entry);
+ /* */
+ gdk_window_freeze_updates(shell->info->view->window);
+
+ g_object_ref(shell->info->model);
+ gtk_tree_view_set_model(GTK_TREE_VIEW(shell->info->view), NULL);
+
/* reset the view type to normal */
- set_view_type(SHELL_VIEW_NORMAL);
+ set_view_type(SHELL_VIEW_NORMAL, reload);
- /* recreate the iter hash table */
if (!reload) {
+ /* recreate the iter hash table */
h_hash_table_remove_all(update_tbl);
}
@@ -1052,6 +1152,7 @@ module_selected_show_info(ShellModuleEntry * entry, gboolean reload)
}
store = GTK_TREE_STORE(shell->info->model);
+
gtk_tree_store_clear(store);
g_key_file_load_from_data(key_file, key_data, strlen(key_data), 0,
@@ -1067,21 +1168,41 @@ module_selected_show_info(ShellModuleEntry * entry, gboolean reload)
gchar **keys = g_key_file_get_keys(key_file, group, NULL, NULL);
if (*group == '$') {
- group_handle_special(key_file, entry, group, keys);
+ group_handle_special(key_file, entry, group, keys, reload);
+ has_shell_param = TRUE;
} else {
group_handle_normal(key_file, entry, group, keys, ngroups);
}
g_strfreev(keys);
}
-
+
+ /* */
+ if (!has_shell_param) {
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(shell->info->view), FALSE);
+ }
+
+ /* */
+ g_object_unref(shell->info->model);
+ gtk_tree_view_set_model(GTK_TREE_VIEW(shell->info->view), shell->info->model);
gtk_tree_view_expand_all(GTK_TREE_VIEW(shell->info->view));
- if (shell->view_type == SHELL_VIEW_PROGRESS) {
+ gdk_window_thaw_updates(shell->info->view->window);
+ shell_set_note_from_entry(entry);
+
+ if (shell->view_type == SHELL_VIEW_PROGRESS || shell->view_type == SHELL_VIEW_PROGRESS_DUAL) {
update_progress();
}
- shell_set_note_from_entry(entry);
+#if GTK_CHECK_VERSION(2,12,0)
+ if (ngroups == 1) {
+ gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(shell->info->view),
+ FALSE);
+ } else {
+ gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(shell->info->view),
+ TRUE);
+ }
+#endif
g_strfreev(groups);
g_key_file_free(key_file);
@@ -1169,18 +1290,11 @@ static void module_selected(gpointer data)
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(shell->info->view));
/* urgh. why don't GTK do this when the model is cleared? */
-#define RANGE_SET_VALUE(tree,scrollbar,value) \
- gtk_range_set_value(GTK_RANGE \
- (GTK_SCROLLED_WINDOW(shell->tree->scroll)-> \
- scrollbar), value);
-
RANGE_SET_VALUE(info, vscrollbar, 0.0);
RANGE_SET_VALUE(info, hscrollbar, 0.0);
RANGE_SET_VALUE(moreinfo, vscrollbar, 0.0);
RANGE_SET_VALUE(moreinfo, hscrollbar, 0.0);
-#undef RANGE_SET_VALUE
-
shell_status_update("Done.");
shell_status_set_enabled(FALSE);
@@ -1197,7 +1311,7 @@ static void module_selected(gpointer data)
shell_action_set_enabled("CopyAction", FALSE);
gtk_tree_store_clear(GTK_TREE_STORE(shell->info->model));
- set_view_type(SHELL_VIEW_NORMAL);
+ set_view_type(SHELL_VIEW_NORMAL, FALSE);
}
current = entry;
@@ -1236,17 +1350,34 @@ static ShellInfoTree *info_tree_new(gboolean extra)
(scroll), GTK_SHADOW_IN);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
+ GTK_POLICY_ALWAYS);
store =
gtk_tree_store_new(INFO_TREE_NCOL, G_TYPE_STRING, G_TYPE_STRING,
- G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_FLOAT);
+ G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_FLOAT,
+ G_TYPE_STRING, G_TYPE_STRING);
model = GTK_TREE_MODEL(store);
treeview = gtk_tree_view_new_with_model(model);
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
+ gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(treeview), TRUE);
- column = gtk_tree_view_column_new();
+ info->col_progress = column = gtk_tree_view_column_new();
+ gtk_tree_view_column_set_visible(column, FALSE);
+ gtk_tree_view_column_set_min_width(column, 240);
+ gtk_tree_view_column_set_clickable(column, TRUE);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+
+ cr_progress = gtk_cell_renderer_progress_new();
+ gtk_tree_view_column_pack_start(column, cr_progress, TRUE);
+ gtk_tree_view_column_add_attribute(column, cr_progress, "value",
+ INFO_TREE_COL_PROGRESS);
+ gtk_tree_view_column_add_attribute(column, cr_progress, "text",
+ INFO_TREE_COL_VALUE);
+ gtk_tree_view_column_set_visible(column, FALSE);
+
+ info->col_textvalue = column = gtk_tree_view_column_new();
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+ gtk_tree_view_column_set_clickable(column, TRUE);
cr_pbuf = gtk_cell_renderer_pixbuf_new();
gtk_tree_view_column_pack_start(column, cr_pbuf, FALSE);
@@ -1254,28 +1385,38 @@ static ShellInfoTree *info_tree_new(gboolean extra)
INFO_TREE_COL_PBUF);
cr_text = gtk_cell_renderer_text_new();
- gtk_tree_view_column_pack_start(column, cr_text, FALSE);
+ gtk_tree_view_column_pack_start(column, cr_text, TRUE);
gtk_tree_view_column_add_attribute(column, cr_text, "markup",
INFO_TREE_COL_NAME);
- info->col_value = column = gtk_tree_view_column_new();
+ info->col_extra1 = column = gtk_tree_view_column_new();
+ gtk_tree_view_column_set_visible(column, FALSE);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+ gtk_tree_view_column_set_clickable(column, TRUE);
cr_text = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(column, cr_text, FALSE);
gtk_tree_view_column_add_attribute(column, cr_text, "markup",
- INFO_TREE_COL_VALUE);
+ INFO_TREE_COL_EXTRA1);
- info->col_progress = column = gtk_tree_view_column_new();
+ info->col_extra2 = column = gtk_tree_view_column_new();
+ gtk_tree_view_column_set_visible(column, FALSE);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+ gtk_tree_view_column_set_clickable(column, TRUE);
- cr_progress = gtk_cell_renderer_progress_new();
- gtk_tree_view_column_pack_start(column, cr_progress, TRUE);
- gtk_tree_view_column_add_attribute(column, cr_progress, "value",
- INFO_TREE_COL_PROGRESS);
- gtk_tree_view_column_add_attribute(column, cr_progress, "text",
+ cr_text = gtk_cell_renderer_text_new();
+ gtk_tree_view_column_pack_start(column, cr_text, FALSE);
+ gtk_tree_view_column_add_attribute(column, cr_text, "markup",
+ INFO_TREE_COL_EXTRA2);
+
+ info->col_value = column = gtk_tree_view_column_new();
+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+ gtk_tree_view_column_set_clickable(column, TRUE);
+
+ cr_text = gtk_cell_renderer_text_new();
+ gtk_tree_view_column_pack_start(column, cr_text, FALSE);
+ gtk_tree_view_column_add_attribute(column, cr_text, "markup",
INFO_TREE_COL_VALUE);
- gtk_tree_view_column_set_visible(column, FALSE);
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
@@ -1311,7 +1452,7 @@ static ShellTree *tree_new()
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW
(scroll), GTK_SHADOW_IN);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
- GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
store = gtk_tree_store_new(TREE_NCOL, GDK_TYPE_PIXBUF, G_TYPE_STRING,