Re: Combined search and combobox?



Indeed, you were right regarding gtk_comb_box_set_entry_text_column().

For the record, below find a translation into C of your python program. Here are some enhancements that I thought of, though I highly doubt that they will be adapted because they are too specialized.
  • Turn it into a widget, that takes a receives of strings in its constructor.
  • Add keybindings for the following functionality:
    • Restore the last string input into the entry widget before selecting a match i the combo-box. E.g. [Meta-Up], [Ctrl-/]
    • Select next entry matching the last string input. [Ctrl-Up]
    • Select previous entry matching the last string input. [Ctrl-Down]
    • Toggle mathing method between Regular expressions, and partial string matches. [Ctrl-=]
  • The special keybindings should also be shown when doing rightclick in the enty widget, that should allow the above functionality.
Based on the code below, I have now also created a pull request for gucharmap: https://github.com/GNOME/gucharmap/pull/2 .

Thanks again!
#include <stdlib.h>
#include <gtk/gtk.h>

enum {
      COL_FONT = 0
};

void populate_store(GtkListStore *store)
{
    int i;

    for (i=0; i<100; i++) {
        char buf[100];
        GtkTreeIter iter;
        sprintf(buf, "Font %d", i);
        gtk_list_store_insert_with_values(store,
                                          &iter,
                                          -1,
                                          COL_FONT, buf,
                                          -1);
    }
}

static gboolean
match_function (GtkEntryCompletion *completion,
                const gchar *key,
                GtkTreeIter *iter,
                gpointer user_data)
{
    GtkTreeModel *model = GTK_TREE_MODEL(user_data);
    char *family, *family_fold;
    gchar **sub_match, **p;
    gboolean all_matches = TRUE;

    gtk_tree_model_get (model,
                        iter,
                        COL_FONT, &family,
                        -1);
    family_fold = g_utf8_casefold (family, -1);

    /* Match by all space separated substrings are part of family string */
    sub_match = g_strsplit(key, " ", -1);
    p = sub_match;
    while (*p) {
        gchar *match_fold = g_utf8_casefold (*p++, -1);
        if (!g_strstr_len (family_fold, -1, match_fold)) {
            all_matches = FALSE;
            break;
        }
    }

    g_free (family);
    g_free (family_fold);
    g_strfreev (sub_match);

    return all_matches;
}


static gboolean
completion_match_selected(GtkEntryCompletion *widget,
                          GtkTreeModel       *model,
                          GtkTreeIter        *iter,
                          gpointer           *user_data)
{
    char *font;

    gtk_tree_model_get (model,
                        iter,
                        COL_FONT, &font,
                        -1);
    printf("selected %s\n", font);
    g_free (font);

    return FALSE;
}

static void
combo_changed (GtkComboBox *combo,
               gpointer user_data)
{
    GtkTreeModel *model = GTK_TREE_MODEL (user_data);  
    GtkTreeIter iter;
    char *font;

    if (!gtk_combo_box_get_active_iter (combo, &iter))
        return;

    gtk_tree_model_get (model,
                        &iter,
                        COL_FONT, &font,
                        -1);
    if (!font)
        return;

    printf("Choosen %s\n", font);
    g_free (font);
}


int main(int argc, char **argv)
{
    gtk_init(&argc, &argv);
    GtkWidget *w_mw = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(w_mw,"destroy",gtk_main_quit, NULL);

    GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING);
    populate_store(store);
    GtkWidget *w_combo = gtk_combo_box_new_with_model_and_entry (GTK_TREE_MODEL (store));
    gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX(w_combo), COL_FONT);
    g_signal_connect (w_combo, "changed",
                      G_CALLBACK (combo_changed), store);
  
    GtkEntryCompletion *completion = gtk_entry_completion_new();
    gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (store));
    gtk_entry_completion_set_text_column (completion, COL_FONT);
    gtk_entry_completion_set_match_func(completion, match_function, GTK_TREE_MODEL(store), NULL);
    g_signal_connect (G_OBJECT (completion), "match-selected",
                      G_CALLBACK (completion_match_selected), NULL);

    gtk_entry_set_completion (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (w_combo))),
                              completion);

    gtk_container_add(GTK_CONTAINER(w_mw), w_combo);
    gtk_widget_show_all(w_mw);
    gtk_main();

    exit(0);
} 


On Sat, Jul 28, 2018 at 2:34 PM Reuben Rissler <silrep emypeople net> wrote:


(gucharmap:30880): Gtk-CRITICAL **: 17:41:07.804: gtk_entry_set_text: assertion 'text != NULL' failed

This happens e.g. when I'm using the up down arrows within the text entry. Btw, this happens also if I only replace (without setting up all the connections), gtk_combo_box_new() with gtk_combo_box_new_with_entry(). I'm still trying to figure out what went wrong.

I will hazard a guess that you didn't set the text column with gtk_combo_box_set_entry_text_column ()

Reuben



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