Hi,
Bit of a late reply, but hope this will help you. I have re-written your code a bit and adjusted the Glade file. This I hope gets closer to what you really want and corrects many other problems.
Code:
/* Compile with this linker options for builder to work:
`pkg-config --cflags --libs gtk+-2.0 gmodule-2.0` -export-dynamic
main.c
*/
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
GtkBuilder *builder;
GtkWidget *window;
GtkWidget *treeview1;
GtkLabel *label1, *label2, *label3;
GtkTreeViewColumn *col;
GtkCellRenderer *chkRend, *rendFifth;
GtkTreeModel *model;
GtkListStore *store;
GtkTreeSelection *treeselectmode;
GtkTreePath *path;
GtkTreeIter iter;
void ClearData();
void LoadData();
int getlastrow();
void DoEvents();
int row_count;
short CtrlDown = 1, faststep = 2;
short idle, idlesec = 3, playcycles = 5;
enum {
C_CHK = 0,
C_ONE,
C_TWO,
C_THREE,
C_FOUR,
C_FIVE,
C_SIX,
C_SEVEN,
NUM_COLS
};
enum {
SCROLL_UP, SCROLL_DOWN
};
G_MODULE_EXPORT
void on_gtk_main_quit (GtkWidget *object, gpointer user_data)
{
gtk_main_quit();
}
int scroll(int direction, int step)
{
GtkTreePath *path;
gtk_tree_view_get_cursor(GTK_TREE_VIEW(treeview1), &path, &col);
if (path) {
gchar s[20];
gint row = gtk_tree_path_get_indices(path)[0];
if ((row >= 0) && (direction == SCROLL_DOWN)) {
if (row <= row_count - step)
row += step;
else
row = row_count;
} else {
if (row >= step)
row -= step;
else
row = 0;
}
g_snprintf(s, sizeof(s), "%d", row);
path = gtk_tree_path_new_from_string(s);
gtk_tree_view_set_cursor(GTK_TREE_VIEW(treeview1), path, NULL, FALSE);
} else {
gtk_widget_grab_focus(treeview1);
g_print("Set focus to treeview\n");
}
gtk_tree_path_free (path);
return (1);
}
G_MODULE_EXPORT void
btnPlay_CB(GtkWidget *widget, gpointer user_data)
{
int lo, op;
for (lo = 0; lo < playcycles; lo++) {
for (op = 0; op < row_count; op++) {
scroll(SCROLL_DOWN, 1);
DoEvents();
g_usleep(20000);
}
for (op = row_count; op >=0; op--) {
scroll(SCROLL_UP, 1);
DoEvents();
g_usleep(20000);
}
}
}
//--------------------------------------------------------------
G_MODULE_EXPORT void
view_selected_foreach_func(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer userdata)
{
int first;
gchar *third;
gtk_tree_model_get(model, iter, C_THREE, &third, -1);
gtk_tree_model_get(model, iter, C_ONE, &first, -1);
g_print("\n%6d %s is entered\n", first, third);
g_free(third);
}
G_MODULE_EXPORT void
on_dblclick(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
{
GtkTreeSelection *treeselectmode;
treeselectmode = gtk_tree_view_get_selection(tree_view);
gtk_tree_selection_selected_foreach(treeselectmode, view_selected_foreach_func, NULL);
g_print("Row activated\n");
}
//--------------------------------------------------------------
gint
get_col_number_from_tree_view_column (GtkTreeViewColumn *col)
{
GList *cols;
gint num;
g_return_val_if_fail(col != NULL, -1);
g_return_val_if_fail(treeview1 != NULL, -1);
cols = gtk_tree_view_get_columns(GTK_TREE_VIEW(treeview1));
num = g_list_index(cols, (gpointer) col);
g_list_free(cols);
return num;
}
//--------------------------------------------------------------
G_MODULE_EXPORT gboolean
motion_notify_event (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
int x, y;
GdkModifierType state;
gchar s[40];
if (!gtk_tree_model_get_iter_first(model, &iter) == FALSE) {
GtkTreePath *path;
GtkTreeViewColumn *col;
if (event->motion.is_hint)
gdk_window_get_pointer(event->motion.window, &x, &y, &state);
else {
x = event->motion.x;
y = event->motion.y;
state = event->motion.state;
}
gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), x, y, &path, &col, &x, &y);
if (path) {
gchar *p = gtk_tree_path_to_string(path);
g_snprintf(s, sizeof(s), "Mouse over row %s column %d", p, get_col_number_from_tree_view_column(col));
gtk_window_set_title(GTK_WINDOW(window), s);
g_free(p);
}
gtk_tree_path_free (path);
}
idle = 0;
gdk_window_get_pointer(gtk_widget_get_window(window), &x, &y, &state);
g_snprintf(s, sizeof(s), "%d", x);
gtk_label_set_text(label1, s);
g_snprintf(s, sizeof(s), "%d", y);
gtk_label_set_text(label2, s);
gdk_event_request_motions (&event->motion);
return FALSE;
}
//--------------------------------------------------------------
void on_changed(GtkWidget *widget, gpointer data)
{
GtkTreeIter iter;
GtkTreeModel *model;
GtkTreePath *path;
int first;
gchar *third;
gtk_tree_view_get_cursor(GTK_TREE_VIEW(treeview1), &path, &col);
if (path) {
gint selrow = gtk_tree_path_get_indices(path)[0];
if (gtk_tree_selection_get_selected(GTK_TREE_SELECTION(widget), &model, &iter)) {
gtk_tree_model_get(model, &iter, C_THREE, &third, -1);
gtk_tree_model_get(model, &iter, C_ONE, &first, -1);
g_print ("selection changed to %6d %6d %s\n", selrow, first, third);
g_free(third);
}
}
gtk_tree_path_free(path);
}
//--------------------------------------------------------------
G_MODULE_EXPORT gboolean
on_view_scroll_event (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
switch(event->scroll.direction) {
case GDK_SCROLL_UP:
scroll(SCROLL_UP, CtrlDown);
break;
case GDK_SCROLL_DOWN:
scroll(SCROLL_DOWN, CtrlDown);
break;
default:
break;
}
return FALSE;
}
//--------------------------------------------------------------
G_MODULE_EXPORT gboolean
tree_button_press (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
if (event->type == GDK_BUTTON_PRESS) {
switch(event->button.button) {
case 1:
g_print ("LEFT mouse button pressed\n");
break;
case 3:
g_print ("RIGHT mouse button pressed\n");
break;
case 2:
g_print ("MIDDLE mouse button pressed\n");
break;
default:
break;
}
}
return FALSE;
}
//--------------------------------------------------------------
G_MODULE_EXPORT gboolean
tree_key_press(GtkWidget *widget, GdkEvent *ev, gpointer user_data)
{
if (ev->type == GDK_KEY_PRESS) {
switch(ev->key.keyval) {
case GDK_KEY_Delete:
gtk_tree_view_get_cursor(GTK_TREE_VIEW(treeview1), &path, NULL);
if (path) {
gint row = gtk_tree_path_get_indices(path)[0];
if (gtk_tree_model_get_iter(model, &iter, path)) {
gtk_list_store_remove(store, &iter);
gtk_tree_path_free(path);
if (row) row--;
row_count--;
path = gtk_tree_path_new_from_indices(row, -1);
gtk_tree_view_set_cursor(GTK_TREE_VIEW(treeview1), path, NULL, FALSE);
}
gtk_tree_path_free(path);
}
return TRUE;
case GDK_KEY_Down:
scroll(SCROLL_DOWN, CtrlDown);
return TRUE;
case GDK_KEY_Up:
scroll(SCROLL_UP, CtrlDown);
return TRUE;
case GDK_KEY_End:
case GDK_KEY_Home:
if ((ev->key.state) & GDK_CONTROL_MASK) {
int setlist = 0;
GtkTreePath *path;
if (ev->key.keyval == GDK_KEY_End) setlist = row_count;
gtk_tree_view_get_cursor(GTK_TREE_VIEW(treeview1), &path, &col);
if (path) {
gchar s[20];
g_snprintf(s, 20, "%d", setlist);
path = gtk_tree_path_new_from_string(s);
gtk_tree_view_set_cursor(GTK_TREE_VIEW(treeview1), path, NULL, FALSE);
gtk_tree_path_free(path);
}
}
return TRUE;
default:
break;
}
}
return FALSE;
}
//--------------------------------------------------------------
void five_cell_data_function (GtkTreeViewColumn *col,
GtkCellRenderer *rendFive,
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer user_data)
{
gfloat value_in5;
gchar s[20];
gtk_tree_model_get(model, iter, C_FIVE, &value_in5, -1);
g_snprintf(s, sizeof(s), "%.2f", value_in5);
g_object_set(rendFive, "text", s, NULL);
}
//--------------------------------------------------------------
G_MODULE_EXPORT void
FOUR_editing_started_cb(GtkCellRenderer *cell,
GtkCellEditable *editable,
gchar *pathtext, gpointer user_data)
{
if(GTK_IS_ENTRY(editable)) {
gtk_entry_set_max_length(GTK_ENTRY(editable), 3);
// To control edit...
// g_signal_connect(editable, "changed", G_CALLBACK(editable_changed_cb), NULL);
}
g_print("PRESS ENTER TO ACCEPT EDITED VALUE, ESC TO CANCEL\n");
g_print("Started editing %s\n", pathtext);
}
//--------------------------------------------------------------
G_MODULE_EXPORT
void FOUR_edited_callback (GtkCellRendererText *cell,
gchar *path_string,
gchar *new_text,
gpointer user_data)
{
path = gtk_tree_path_new_from_string(path_string);
gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path);
gtk_list_store_set(GTK_LIST_STORE(model), &iter, C_FOUR, new_text, -1);
g_print("edited %s in row %s\n", new_text, path_string);
gtk_tree_path_free (path);
}
//--------------------------------------------------------------
G_MODULE_EXPORT void
chktoggled_CB (GtkCellRendererToggle *chkRend,
gchar *path_str,
gpointer user_data)
{
GtkTreeIter iter;
GtkTreePath *path = gtk_tree_path_new_from_string(path_str);
gboolean fixed;
gtk_tree_model_get_iter(model, &iter, path);
gtk_tree_model_get(model, &iter, C_CHK, &fixed, -1);
fixed ^= 1;
gtk_list_store_set(GTK_LIST_STORE(model), &iter, C_CHK, fixed, -1);
gtk_tree_path_free(path);
}
/*--------------------------------------------------------------
* If looking for just the Control key, we must check for it by key value
*/
G_MODULE_EXPORT gboolean
win_keypress_CB(GtkWidget *object, GdkEvent *ev, gpointer user_data)
{
idle = 0;
if (ev->key.keyval == GDK_KEY_Control_L || ev->key.keyval == GDK_KEY_Control_R) {
CtrlDown = faststep;
g_print("Control Press\n");
}
return FALSE;
}
/*--------------------------------------------------------------
* If looking for just the Control key, we must check for it by key value
*/
G_MODULE_EXPORT gboolean
win_keyrelease_CB(GtkWidget *object, GdkEvent *ev, gpointer user_data)
{
idle = 0;
if (ev->key.keyval == GDK_KEY_Control_L || ev->key.keyval == GDK_KEY_Control_R) {
CtrlDown = 1;
g_print("Control release\n");
}
return FALSE;
}
//--------------------------------------------------------------
G_MODULE_EXPORT gboolean
kill_idle_CB (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
int x, y;
GdkModifierType state;
gchar s[20];
idle = 0;
if (event->motion.is_hint) {
gdk_window_get_pointer(event->motion.window, &x, &y, &state);
} else {
x = event->motion.x;
y = event->motion.y;
state = event->motion.state;
}
g_snprintf(s, sizeof(s), "%d", x);
gtk_label_set_text(label1, s);
g_snprintf(s, sizeof(s), "%d", y);
gtk_label_set_text(label2, s);
return FALSE;
}
//--------------------------------------------------------------
gboolean time_handler(gpointer user_data)
{
time_t rawtime;
struct tm * timeinfo;
char buffer[16];
if ((idle/10) >= idlesec) {
time (&rawtime);
timeinfo = localtime(&rawtime);
strftime(buffer, 16, "IDLE %H:%M:%S\n", timeinfo);
gtk_label_set_text(label3, buffer);
} else {
gtk_label_set_text(label3, "");
idle++;
}
return TRUE;
}
//--------------------------------------------------------------
int main (int argc, char *argv[])
{
gtk_init (&argc, &argv);
builder = gtk_builder_new ();
gtk_builder_add_from_file(builder, "minGladeTW.glade", NULL);
window = GTK_WIDGET(gtk_builder_get_object(builder, "window1"));
g_timeout_add(100, time_handler, NULL);
treeview1 = GTK_WIDGET(gtk_builder_get_object(builder, "treeview1"));
chkRend = GTK_CELL_RENDERER(gtk_builder_get_object(builder, "chkRend"));
rendFifth = GTK_CELL_RENDERER(gtk_builder_get_object(builder, "rendFifth"));
label1 = GTK_LABEL(gtk_builder_get_object(builder, "label1"));
label2 = GTK_LABEL(gtk_builder_get_object(builder, "label2"));
label3 = GTK_LABEL(gtk_builder_get_object(builder, "label3"));
treeselectmode = gtk_tree_view_get_selection (GTK_TREE_VIEW(treeview1));
gtk_tree_selection_set_mode(treeselectmode, GTK_SELECTION_SINGLE);
store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(treeview1)));
model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview1));
col = gtk_tree_view_get_column(GTK_TREE_VIEW (treeview1), C_FIVE);
gtk_tree_view_column_set_cell_data_func(col, rendFifth, five_cell_data_function, NULL, NULL);
gtk_builder_connect_signals(builder, NULL);
g_object_unref(G_OBJECT(builder));
LoadData();
gtk_widget_show_all(window);
gtk_main ();
return (0);
}
void ClearData()
{
if (!gtk_tree_model_get_iter_first(model, &iter) == FALSE)
gtk_list_store_clear(store);
row_count = 0;
}
void LoadData()
{
model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview1));
g_object_ref(model);
gtk_tree_view_set_model(GTK_TREE_VIEW(treeview1), NULL);
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, C_CHK, TRUE,
C_ONE, 1245,
C_TWO, "SOME <b>NAME</b> LIKE NIME",
C_THREE, "Some name like nime",
C_FOUR, "KOM",
C_FIVE, 1254.12568,
C_SIX, 243.125689,
C_SEVEN, "", -1);
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, C_CHK, FALSE,
C_ONE, 1,
C_TWO, "NO <b>NAME</b>",
C_THREE, "No name",
C_FOUR, "NA",
C_FIVE, 0.00,
C_SIX, 0.00,
C_SEVEN, "", -1);
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, C_CHK, FALSE,
C_ONE, 153,
C_TWO, "INTERESTING <b>NAME</b>D ROW",
C_THREE, "Interesting named row",
C_FOUR, "ROW",
C_FIVE, 22235.1101158,
C_SIX, 1235.215,
C_SEVEN, "", -1);
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, C_CHK, FALSE,
C_ONE, 84,
C_TWO, "<b>NAME</b> OF THE GAME",
C_THREE, "Name of the game",
C_FOUR, "NAM",
C_FIVE, 169.74521,
C_SIX, 1.585236,
C_SEVEN, "", -1);
gtk_tree_view_set_model(GTK_TREE_VIEW(treeview1), model);
g_object_unref(model);
row_count = getlastrow();
//--------------------
if (row_count) {
path = gtk_tree_path_new_from_string("0");
gtk_tree_selection_select_path(treeselectmode, path);
gtk_tree_path_free(path);
}
gtk_widget_grab_focus(treeview1);
}
int getlastrow()
{
GtkTreeIter iter1;
row_count = 0;
gtk_tree_model_get_iter_first(model, &iter1);
while(gtk_tree_model_iter_next(model, &iter1)) {
row_count++;
}
return row_count;
}
void DoEvents()
{
while (gtk_events_pending ())
gtk_main_iteration ();
}
Code:
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="2.24"/>
<object class="GtkListStore" id="liststore1">
<columns>
<!-- column-name colChk -->
<column type="gboolean"/>
<!-- column-name colOne -->
<column type="gint"/>
<!-- column-name colTwo -->
<column type="gchararray"/>
<!-- column-name colThree -->
<column type="gchararray"/>
<!-- column-name colFour -->
<column type="gchararray"/>
<!-- column-name colFive -->
<column type="gfloat"/>
<!-- column-name colSix -->
<column type="gfloat"/>
<!-- column-name colLast -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0">False</col>
<col id="1">28</col>
<col id="2" translatable="yes">MY <b>NAME</b> IS GLADE</col>
<col id="3" translatable="yes">My name is Glade</col>
<col id="4" translatable="yes">LIT</col>
<col id="5">1244.056884765625</col>
<col id="6">24.125690460205078</col>
<col id="7" translatable="yes"> </col>
</row>
<row>
<col id="0">False</col>
<col id="1">1256</col>
<col id="2" translatable="yes">SECOND ROW FROM GLADE</col>
<col id="3" translatable="yes">Second row from glade</col>
<col id="4" translatable="yes">ROW</col>
<col id="5">1458.326904296875</col>
<col id="6">0</col>
<col id="7" translatable="yes"> </col>
</row>
</data>
</object>
<object class="GtkWindow" id="window1">
<property name="height_request">400</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
<signal name="destroy" handler="on_gtk_main_quit" swapped="no"/>
<signal name="key-release-event" handler="win_keyrelease_CB" swapped="no"/>
<signal name="key-press-event" handler="win_keypress_CB" swapped="no"/>
<signal name="button-release-event" handler="kill_idle_CB" swapped="no"/>
<signal name="motion-notify-event" handler="kill_idle_CB" swapped="no"/>
<signal name="button-press-event" handler="kill_idle_CB" swapped="no"/>
<signal name="delete-event" handler="on_gtk_main_quit" swapped="no"/>
<child>
<object class="GtkHBox" id="hbox1">
<property name="can_focus">False</property>
<child>
<object class="GtkVBox" id="vbox1">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<object class="GtkHBox" id="hbox5">
<property name="can_focus">False</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">Exit</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="on_gtk_main_quit" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox4">
<property name="can_focus">False</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkButton" id="button2">
<property name="label" translatable="yes">Play</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="btnPlay_CB" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkHSeparator" id="hseparator1">
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="padding">10</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox3">
<property name="can_focus">False</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkLabel" id="label1">
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">move mouse</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">6</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox2">
<property name="can_focus">False</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkLabel" id="label2">
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">here</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">7</property>
</packing>
</child>
<child>
<object class="GtkHSeparator" id="hseparator2">
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="padding">10</property>
<property name="position">8</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label3">
<property name="width_request">99</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">9</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkTreeView" id="treeview1">
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK | GDK_SCROLL_MASK</property>
<property name="model">liststore1</property>
<property name="search_column">4</property>
<property name="rubber_banding">True</property>
<signal name="button-press-event" handler="tree_button_press" swapped="no"/>
<signal name="key-press-event" handler="tree_key_press" swapped="no"/>
<signal name="row-activated" handler="on_dblclick" swapped="no"/>
<signal name="motion-notify-event" handler="motion_notify_event" swapped="no"/>
<signal name="scroll-event" handler="on_view_scroll_event" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1">
<signal name="changed" handler="on_changed" swapped="no"/>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="colChk">
<property name="alignment">0.5</property>
<child>
<object class="GtkCellRendererToggle" id="chkRend">
<signal name="toggled" handler="chktoggled_CB" swapped="no"/>
</object>
<attributes>
<attribute name="active">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="col1">
<property name="sizing">fixed</property>
<property name="fixed_width">70</property>
<property name="title">First </property>
<property name="alignment">1</property>
<child>
<object class="GtkCellRendererText" id="rendFirst">
<property name="width">70</property>
<property name="xalign">1</property>
</object>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="col2">
<property name="sizing">fixed</property>
<property name="fixed_width">230</property>
<property name="title">Second</property>
<child>
<object class="GtkCellRendererText" id="rendSecond"/>
<attributes>
<attribute name="markup">2</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="col3">
<property name="visible">False</property>
<property name="title">Third</property>
<child>
<object class="GtkCellRendererText" id="rendThird"/>
<attributes>
<attribute name="text">3</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="col4">
<property name="sizing">fixed</property>
<property name="fixed_width">60</property>
<property name="title">Fourth</property>
<property name="alignment">0.5</property>
<child>
<object class="GtkCellRendererText" id="rendFourth">
<property name="width">60</property>
<property name="xalign">0.50999999046325684</property>
<property name="alignment">center</property>
<property name="editable">True</property>
<signal name="editing-started" handler="FOUR_editing_started_cb" swapped="no"/>
<signal name="edited" handler="FOUR_edited_callback" swapped="no"/>
</object>
<attributes>
<attribute name="text">4</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="col5">
<property name="sizing">fixed</property>
<property name="fixed_width">90</property>
<property name="title">Fifth </property>
<property name="alignment">1</property>
<child>
<object class="GtkCellRendererText" id="rendFifth">
<property name="width">90</property>
<property name="xalign">1</property>
</object>
<attributes>
<attribute name="text">5</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="col6">
<property name="sizing">fixed</property>
<property name="fixed_width">90</property>
<property name="title">Sixth </property>
<property name="alignment">1</property>
<property name="sort_indicator">True</property>
<child>
<object class="GtkCellRendererText" id="rendSixth">
<property name="xalign">1</property>
</object>
<attributes>
<attribute name="text">6</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="col7">
<child>
<object class="GtkCellRendererText" id="rendSeventh"/>
<attributes>
<attribute name="text">7</attribute>
</attributes>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
</interface>
The first thing I did was to run the code through astyle to re-format to code to make it easier to read. I also rearranged the code to remove the C99 style code, but have left the C++ style comments, this should allow the code to compile in more places.
Next I dealt with the memory leaks. These were mainly the use of g_strdup_printf() with the string not being freed. As well as other places such as allocating a GtkTreePath and not freeing it, obtaining a string and not freeing. These were mainly fixed by adding the correct freeing, but in some places because the expected string is small I allocated it on the stack and used bound check formatting of the strings using g_snprintf().
I changed the input parameters of scroll() to int as that is what the compiler would have done anyway internally and the use of char would be doing a fair bit of conversion in the back ground.
I then fixed the proto-types of all the call-backs and corrected the return values.
I also removed a large amount of deprecated code such as GDK_Home should now be GDK_KEY_Home. But have left some code that is deprecated in GTK+ 3.
I then looked at the Glade file. To do the alignment of the cell renderers you need to set both the "xalign" and "width" properties to get the expected alignment you want. For the text cell renderer the default "xalign" is 0.0 even though in Glade it shows up as 0.5. To get around this I used 0.51 , so that it is not a default value, which is probably close enough, but enough to tell GTK+/Glade to set "xalign" to centre-ish.
As for the problem with the TreeView. I did take a bit of time to try and work this out. it seams that it is not always passing the motion events from the TreeView to Widgets below it. This could be that GtkTreeView uses "motion-notify-event" internally. I have done a work around for it by adding extra code to motion_notify_event() in your code. This basically gets the pointer position for the window and sets the labels. It still does not work for when the mouse pointer is over the header of the TreeView.
As for tools for checking for memory leaks there are many out there, one of the most famous is valgrind. Valgrind can be very slow and with GTK+ does emit a fair amount of false positives so a suppression file will need to be generated.
Errol.