Patricio Rossi
Patricio Rossi

Reputation: 163

Gtkmm 3 ComboBoxText how to disable options?

I have been trying several ways to get this done, but I am stuck, I can access the model, but I cannot access the view part to set the option disabled with set_sensitive I cannot find any example or documentation that mention how to do this. I have a comboboxtext object inside combobox variable, and the id inside id. this is what I did:

auto model = combobox.get_model();
for (auto iter = model->children().begin();
iter != model->children().end(); ++iter) {
    auto row = *iter;
    std::string value;
    row->get_value(1, value);
    if (value == id) {
        // disable the row
        ???
        break;
    }
}

Upvotes: 0

Views: 120

Answers (1)

Patricio Rossi
Patricio Rossi

Reputation: 163

I cannot find a way to access the selected row cellRenderer to do a sensitive false. Basically, I was unable to access the internals of the ComboBoxText I am able to extract the model and some parts of it, but nothing usable. (version 4 provides get_column_types in the model, but not version 3)

What I did after a lot of trial and error is give up and use a normal combobox. I'm leaving a sample code so others that are looking for an example finds something useful and don't waste five days researching. There are a couple of ways to do this, but is just an example:

// Create a class or just do it inline up you you.
class ModelColumns : public Gtk::TreeModel::ColumnRecord {

public:

    ModelColumns() {
        add(colId); add(colText); add(colSensitive);
    }

    Gtk::TreeModelColumn<Glib::ustring> colId;
    Gtk::TreeModelColumn<Glib::ustring> colText;
    Gtk::TreeModelColumn<bool>          colSensitive;
};

// Create a recordset
ModelColumns record;

// Define the TreeModel, set some data.
auto model = Gtk::ListStore::create(record);
for (auto c = 0; c < 3; ++c) {
    auto row = *(model->append());
    row[record.colId]    = std::to_string(c + 1);
    row[record.colText] = "Text " + std::to_string(c + 1);
    // This row will track the sensitive and will be linked to the view.
    row[record.colSensitive] = true;
}

// Define renderer
Gtk::CellRendererText* renderer = Gtk::manage(new Gtk::CellRendererText());

// Create a ComboBox with the TreeModel and renderer.
auto comboBox = Gtk::make_managed<Gtk::ComboBox>();
comboBox->set_model(model);

// This is only needed if you are using an ID like I did on the model above, other case you can use the row number from 0.
comboBox->set_id_column(0);

// add the renderer and link the columns with the data
comboBox->pack_start(*renderer, false);

comboBox->add_attribute(*renderer, "text", record.colText);
comboBox->add_attribute(*renderer, "sensitive", record.colSensitive);

// Example of finding the active ID (the hard way) I keeped this code, because I was trying to get the cell from there.
int index = 0;
for (auto iter = model->children().begin(); iter != model->children().end(); ++iter) {
    auto row = *iter;
    if (row[record.colId] == "2") {
        comboBox->set_active(index);
        break;
    }
    index++;
}

// Get the active row (id = "2") and set it to disable.
auto a = comboBox->get_active();
// You will say, "why you don't just did this with the ComboBoxText?",
well... the manual said to avoid messing with the layout, also, as I said, I was unable to extract the record out of the model, so "record" is nonexistent.
a->set_value(record.colSensitive, false);

// Now get the active ID (the ez way) and disable it too.
comboBox->set_active_id("3");
a = comboBox->get_active();
// Setting this to false will set senstive to false because they are linked.
a->set_value(record.colSensitive, false);

Hope someone finds the answer, will be cool to see it. Thanks.

Upvotes: 0

Related Questions