GtkTreeView with cells editable on entry



Hi all!
  I have a single-column GtkTreeView widget in which all cells are
editable, and I must let the user edit them without having to click
twice (in the standard GtkTreeView, one click selects a cell, and
another is needed to begin editing).
More clearly stated, there must never be cells which have the focus but
are not being edited; it the user is editing a cell and presses the
GDK_Down key, the current cell must stop editing, and the cell right
below it must begin editing, immediately.

I think I have reached my goal (there are minor issues to check), but
I'm not very satisfacted by the way I achieved it; it looks like a big
hack. I'll past the relevant parts of my code.

To have the user immediately start editing a cell when he focuses it,
I'm doing this:


    g_signal_connect_after(treeview, "cursor-changed",
                     G_CALLBACK(cursor_changed), self);


the cursor_changed() function does nothing but g_idle_add()'ing
start_editing(), which is:


static gboolean start_editing(JamMultiline *self)
{
    [...get the cell renderer...]
    gtk_tree_view_get_cursor(treeview, &path, &col);
    g_signal_handlers_block_by_func(treeview, cursor_changed, self);
    gtk_widget_grab_focus(GTK_WIDGET(treeview));
    gtk_tree_view_set_cursor_on_cell(treeview, path, col, renderer,
TRUE);
    g_signal_handlers_unblock_by_func(treeview, cursor_changed, self);
    gtk_tree_path_free(path);
    return FALSE;
}


I'm also connecting to the "editing-started" signal of the renderer, and
in it's callback (i.e., whenever a GtkEntry is created for the editing)
I connect to the signal "key-press-event" of the GtkEntry, in order to
capture the GDK keys that would stop editing and treat them differently.
Here's the callback:


static gboolean entry_key_press_event(GtkEntry *entry, GdkEventKey *event,
                                      JamMultiline *self)
{
    if (event->keyval == GDK_Up || event->keyval == GDK_Down) {
        GdkEventKey ev;
        ev = *event;
        ev.window = GTK_WIDGET(JAM_LISTBOX(self)->treeview)->window;
        /* this is the same thing that the gtk_cell_editable_key_press_event()
         * in the standard gtkentry.c does */
        gtk_cell_editable_editing_done(GTK_CELL_EDITABLE(entry));
        gtk_cell_editable_remove_widget(GTK_CELL_EDITABLE(entry));
        gdk_event_put((GdkEvent*)&ev);
        return TRUE;
    }
    return FALSE;
}


It's quite similar to what the standard GtkEntry does, the only
difference is that I'm forwarding the keypress event to the treeview, so
that it can immediately begin editing another cell (otherwise those keys
would just cause the editing to be stopped, and no movement would be
performed).
The good news: it works!
But I don't like this solution, especially the idle function and this
putting back the event in the queue with gdk_event_put()...
Do anyone have a better solution? It seems weird to me that there is no
cleaner way to achive this (not so uncommon, I presume) behaviour.

Looking forward for your comments!


-- 
Saluti,
    Mardy
http://www.interlingua.com
Chiacchiera con i tuoi amici in tempo reale! 
 http://it.yahoo.com/mail_it/foot/*http://it.messenger.yahoo.com 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]