models.cpp 3.91 KB
Newer Older
1
/*
Sébastien Blin's avatar
Sébastien Blin committed
2
 *  Copyright (C) 2015-2019 Savoir-faire Linux Inc.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *  Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
 *
 *  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
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
 */

#include "models.h"

#include "../models/gtkqtreemodel.h"
23
#include <QtCore/QItemSelectionModel>
24 25 26 27 28 29 30 31 32 33 34 35

QModelIndex
get_index_from_selection(GtkTreeSelection *selection)
{
    GtkTreeIter iter;
    GtkTreeModel *model = NULL;

    if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
        if (GTK_IS_Q_TREE_MODEL(model))
            return gtk_q_tree_model_get_source_idx(GTK_Q_TREE_MODEL(model), &iter);
    }
    return QModelIndex();
36 37 38 39 40
}

QModelIndex
gtk_combo_box_get_index(GtkComboBox *box)
{
41 42
    GtkTreeIter iter;
    GtkTreeModel *model = gtk_combo_box_get_model(box);
43

44
    if (gtk_combo_box_get_active_iter(box, &iter)) {
45
        if (GTK_IS_Q_TREE_MODEL(model))
46
            return gtk_q_tree_model_get_source_idx(GTK_Q_TREE_MODEL(model), &iter);
47 48 49 50 51 52 53 54 55 56 57
    }
    return QModelIndex();
}

static void
update_selection(GtkComboBox *box, QItemSelectionModel *selection_model)
{
    QModelIndex idx = gtk_combo_box_get_index(box);
    if (idx.isValid()) {
        selection_model->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect);
    }
58
    selection_model->clearSelection();
59 60 61 62 63 64 65
}

void
gtk_combo_box_set_active_index(GtkComboBox *box, const QModelIndex& idx)
{
    if (idx.isValid()) {
        GtkTreeIter new_iter;
66
        GtkTreeModel *model = gtk_combo_box_get_model(box);
67

68
        g_return_if_fail(GTK_IS_Q_TREE_MODEL(model));
69

70 71
        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);
72 73 74 75 76 77 78 79 80 81 82 83
        } else {
            g_warning("Given QModelIndex doesn't exist in GtkTreeModel");
        }
    }
}

QMetaObject::Connection
gtk_combo_box_set_qmodel(GtkComboBox *box, QAbstractItemModel *qmodel, QItemSelectionModel *selection_model)
{
    QMetaObject::Connection connection;
    GtkTreeModel *model;

84 85 86 87
    model = (GtkTreeModel *)gtk_q_tree_model_new(
        qmodel,
        1,
        0, Qt::DisplayRole, G_TYPE_STRING);
88

89
    gtk_combo_box_set_model(box, GTK_TREE_MODEL(model));
90

91 92
    if (!selection_model) return connection;

93 94 95
   /* sync the initial selection */
   gtk_combo_box_set_active_index(box, selection_model->currentIndex());

96 97 98 99
    /* connect signals to and from the selection model */
    connection = QObject::connect(
        selection_model,
        &QItemSelectionModel::currentChanged,
100
        [=](const QModelIndex current, G_GNUC_UNUSED const QModelIndex & previous) {
101 102 103 104 105 106 107 108 109
            gtk_combo_box_set_active_index(box, current);
        }
    );
    g_signal_connect(box,
                     "changed",
                     G_CALLBACK(update_selection),
                     selection_model);

    return connection;
110
}
111 112 113 114 115 116 117 118 119 120 121 122 123

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;
}