improve combo box model utility functions

- remove filtering of disabled items to simplify code (this can be
  (done via a QSortFilterProxy model if needed)
- add a more generic version of the helper function which doesn't
  force a text renderer

Change-Id: Ic916f7e60f83331a3753b45f56fee1cb38e80858
Reviewed-by: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>
diff --git a/src/utils/models.cpp b/src/utils/models.cpp
index f9bd81c..32b88df 100644
--- a/src/utils/models.cpp
+++ b/src/utils/models.cpp
@@ -19,11 +19,8 @@
 
 #include "models.h"
 
-#include <gtk/gtk.h>
 #include "../models/gtkqtreemodel.h"
-#include <QtCore/QModelIndex>
 #include <QtCore/QItemSelectionModel>
-#include <QtCore/QSortFilterProxyModel>
 
 QModelIndex
 get_index_from_selection(GtkTreeSelection *selection)
@@ -41,29 +38,12 @@
 QModelIndex
 gtk_combo_box_get_index(GtkComboBox *box)
 {
-    GtkTreeIter filter_iter;
-    GtkTreeIter child_iter;
-    GtkTreeModel *filter_model = gtk_combo_box_get_model(box);
-    GtkTreeModel *model = filter_model;
+    GtkTreeIter iter;
+    GtkTreeModel *model = gtk_combo_box_get_model(box);
 
-    GtkTreeIter *iter = NULL;
-
-    if (GTK_IS_TREE_MODEL_FILTER(filter_model))
-        model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(filter_model));
-
-    if (gtk_combo_box_get_active_iter(box, &filter_iter)) {
-        if (GTK_IS_TREE_MODEL_FILTER(filter_model)) {
-            gtk_tree_model_filter_convert_iter_to_child_iter(
-                GTK_TREE_MODEL_FILTER(filter_model),
-                &child_iter,
-                &filter_iter);
-            iter = &child_iter;
-        } else {
-            iter = &filter_iter;
-        }
-
+    if (gtk_combo_box_get_active_iter(box, &iter)) {
         if (GTK_IS_Q_TREE_MODEL(model))
-            return gtk_q_tree_model_get_source_idx(GTK_Q_TREE_MODEL(model), iter);
+            return gtk_q_tree_model_get_source_idx(GTK_Q_TREE_MODEL(model), &iter);
     }
     return QModelIndex();
 }
@@ -75,19 +55,7 @@
     if (idx.isValid()) {
         selection_model->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect);
     }
-}
-
-static gboolean
-filter_disabled_items(GtkTreeModel *model, GtkTreeIter *iter, G_GNUC_UNUSED gpointer data)
-{
-    QModelIndex idx;
-    if (GTK_IS_Q_TREE_MODEL(model))
-        idx = gtk_q_tree_model_get_source_idx(GTK_Q_TREE_MODEL(model), iter);
-
-    if (idx.isValid()) {
-        return idx.flags() & Qt::ItemIsEnabled ? TRUE : FALSE;
-    }
-    return FALSE;
+    selection_model->clearSelection();
 }
 
 void
@@ -95,32 +63,12 @@
 {
     if (idx.isValid()) {
         GtkTreeIter new_iter;
-        GtkTreeModel *filter_model = gtk_combo_box_get_model(box);
-        g_return_if_fail(filter_model);
-        GtkTreeModel *model = filter_model;
+        GtkTreeModel *model = gtk_combo_box_get_model(box);
 
-        if (GTK_IS_TREE_MODEL_FILTER(filter_model))
-            model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(filter_model));
+        g_return_if_fail(GTK_IS_Q_TREE_MODEL(model));
 
-        gboolean valid = FALSE;
-        if (GTK_IS_Q_TREE_MODEL(model))
-            valid = gtk_q_tree_model_source_index_to_iter(GTK_Q_TREE_MODEL(model), idx, &new_iter);
-
-        if (valid) {
-            if (GTK_IS_TREE_MODEL_FILTER(filter_model)) {
-                GtkTreeIter filter_iter;
-                if (gtk_tree_model_filter_convert_child_iter_to_iter(
-                        GTK_TREE_MODEL_FILTER(filter_model),
-                        &filter_iter,
-                        &new_iter)
-                ) {
-                    gtk_combo_box_set_active_iter(box, &filter_iter);
-                } else {
-                    g_warning("failed to convert iter from source model to filter model iter");
-                }
-            } else {
-                gtk_combo_box_set_active_iter(box, &new_iter);
-            }
+        if (gtk_q_tree_model_source_index_to_iter(GTK_Q_TREE_MODEL(model), idx, &new_iter)) {
+            gtk_combo_box_set_active_iter(box, &new_iter);
         } else {
             g_warning("Given QModelIndex doesn't exist in GtkTreeModel");
         }
@@ -138,17 +86,7 @@
         1,
         0, Qt::DisplayRole, G_TYPE_STRING);
 
-    /* use a filter model to remove disabled items */
-    GtkTreeModel *filter_model = gtk_tree_model_filter_new(model, NULL);
-    gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter_model),
-                                           (GtkTreeModelFilterVisibleFunc)filter_disabled_items,
-                                           NULL, NULL);
-
-    gtk_combo_box_set_model(box, GTK_TREE_MODEL(filter_model));
-    GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
-    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(box), renderer, FALSE);
-    gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(box), renderer,
-                                   "text", 0, NULL);
+    gtk_combo_box_set_model(box, GTK_TREE_MODEL(model));
 
     if (!selection_model) return connection;
 
@@ -170,3 +108,16 @@
 
     return connection;
 }
+
+QMetaObject::Connection
+gtk_combo_box_set_qmodel_text(GtkComboBox *box, QAbstractItemModel *qmodel, QItemSelectionModel *selection_model)
+{
+    auto connection = gtk_combo_box_set_qmodel(box, qmodel, selection_model);
+
+    GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
+    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(box), renderer, FALSE);
+    gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(box), renderer,
+                                   "text", 0, NULL);
+
+    return connection;
+}
diff --git a/src/utils/models.h b/src/utils/models.h
index f0ea7c5..09dd692 100644
--- a/src/utils/models.h
+++ b/src/utils/models.h
@@ -36,7 +36,24 @@
 void
 gtk_combo_box_set_active_index(GtkComboBox *box, const QModelIndex& idx);
 
+/**
+ * Helper method to automatically place the qmodel into the combobox and sync it with the
+ * selection model (if given). Returns the connection to the QItemSelectionModel::currentChanged
+ * signal of the given selection model.
+ * This function doesn't set any GtkCellRenderer for the combo box, so nothing will be displayed
+ * by default. If you simply want to display the Qt::DisplayRole of the model as text, you should
+ * use gtk_combo_box_set_qmodel_text()
+ */
 QMetaObject::Connection
 gtk_combo_box_set_qmodel(GtkComboBox *box, QAbstractItemModel *qmodel, QItemSelectionModel *selection_model);
 
+/**
+ * Like gtk_combo_box_set_qmodel, but sets a GtkCellRendererText for the combo box which will
+ * display the Qt::DisplayRole as simple text. This function is a usefull default for most
+ * combo boxes. If you want to customize the GtkCellRenderer of your combo box, you should usefull
+ * gtk_combo_box_set_qmodel()
+ */
+QMetaObject::Connection
+gtk_combo_box_set_qmodel_text(GtkComboBox *box, QAbstractItemModel *qmodel, QItemSelectionModel *selection_model);
+
 #endif /* _MODELS_H */