/* LIBPIKA - The PIKA Library * Copyright (C) 1995-1999 Peter Mattis and Spencer Kimball * * pikaunitcombobox.c * Copyright (C) 2004, 2008 Sven Neumann * * This library is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see * . */ #include "config.h" #include #include "pikawidgetstypes.h" #include "pikaunitcombobox.h" #include "pikaunitstore.h" /** * SECTION: pikaunitcombobox * @title: PikaUnitComboBox * @short_description: A #GtkComboBox to select a #PikaUnit. * @see_also: #PikaUnit, #PikaUnitStore * * #PikaUnitComboBox selects units stored in a #PikaUnitStore. **/ static void pika_unit_combo_box_popup_shown (PikaUnitComboBox *widget); static void pika_unit_combo_box_constructed (GObject *object); G_DEFINE_TYPE (PikaUnitComboBox, pika_unit_combo_box, GTK_TYPE_COMBO_BOX) #define parent_class pika_unit_combo_box_parent_class static void pika_unit_combo_box_class_init (PikaUnitComboBoxClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->constructed = pika_unit_combo_box_constructed; } static void pika_unit_combo_box_init (PikaUnitComboBox *combo) { g_signal_connect (combo, "notify::popup-shown", G_CALLBACK (pika_unit_combo_box_popup_shown), NULL); } static void pika_unit_combo_box_constructed (GObject *object) { PikaUnitComboBox *combo = PIKA_UNIT_COMBO_BOX (object); G_OBJECT_CLASS (parent_class)->constructed (object); pika_unit_combo_box_popup_shown (combo); } static void pika_unit_combo_box_popup_shown (PikaUnitComboBox *widget) { PikaUnitStore *store; gboolean shown; GtkCellRenderer *cell; g_object_get (widget, "model", &store, "popup-shown", &shown, NULL); if (store) { if (shown) _pika_unit_store_sync_units (store); g_object_unref (store); } gtk_cell_layout_clear (GTK_CELL_LAYOUT (widget)); cell = gtk_cell_renderer_text_new (); if (shown) { gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), cell, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), cell, "text", PIKA_UNIT_STORE_UNIT_LONG_FORMAT, NULL); /* XXX This is ugly but it seems that GtkComboBox won't resize its popup * menu when the contents changes (it only resizes the main "chosen item" * area). We force a redraw by popping down then up after a contents * change. */ g_signal_handlers_disconnect_by_func (widget, G_CALLBACK (pika_unit_combo_box_popup_shown), NULL); gtk_combo_box_popdown (GTK_COMBO_BOX (widget)); gtk_combo_box_popup (GTK_COMBO_BOX (widget)); g_signal_connect (widget, "notify::popup-shown", G_CALLBACK (pika_unit_combo_box_popup_shown), NULL); } else { gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), cell, FALSE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), cell, "text", PIKA_UNIT_STORE_UNIT_SHORT_FORMAT, NULL); } } /** * pika_unit_combo_box_new: * * Returns: a new #PikaUnitComboBox. **/ GtkWidget * pika_unit_combo_box_new (void) { GtkWidget *combo_box; PikaUnitStore *store; store = pika_unit_store_new (0); combo_box = g_object_new (PIKA_TYPE_UNIT_COMBO_BOX, "model", store, "id-column", PIKA_UNIT_STORE_UNIT_LONG_FORMAT, NULL); g_object_unref (store); return combo_box; } /** * pika_unit_combo_box_new_with_model: * @model: a #PikaUnitStore * * Returns: a new #PikaUnitComboBox. **/ GtkWidget * pika_unit_combo_box_new_with_model (PikaUnitStore *model) { return g_object_new (PIKA_TYPE_UNIT_COMBO_BOX, "model", model, "id-column", PIKA_UNIT_STORE_UNIT_LONG_FORMAT, NULL); } /** * pika_unit_combo_box_get_active: * @combo: a #PikaUnitComboBox * * Returns the #PikaUnit currently selected in the combo box. * * Returns: (transfer none): The selected #PikaUnit. **/ PikaUnit pika_unit_combo_box_get_active (PikaUnitComboBox *combo) { GtkTreeIter iter; gint unit; g_return_val_if_fail (PIKA_IS_UNIT_COMBO_BOX (combo), -1); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter); gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (combo)), &iter, PIKA_UNIT_STORE_UNIT, &unit, -1); return (PikaUnit) unit; } /** * pika_unit_combo_box_set_active: * @combo: a #PikaUnitComboBox * @unit: a #PikaUnit * * Sets @unit as the currently selected #PikaUnit on @combo. **/ void pika_unit_combo_box_set_active (PikaUnitComboBox *combo, PikaUnit unit) { GtkTreeModel *model; GtkTreeIter iter; gboolean iter_valid; g_return_if_fail (PIKA_IS_UNIT_COMBO_BOX (combo)); model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); _pika_unit_store_sync_units (PIKA_UNIT_STORE (model)); for (iter_valid = gtk_tree_model_get_iter_first (model, &iter); iter_valid; iter_valid = gtk_tree_model_iter_next (model, &iter)) { gint iter_unit; gtk_tree_model_get (model, &iter, PIKA_UNIT_STORE_UNIT, &iter_unit, -1); if (unit == (PikaUnit) iter_unit) { gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &iter); break; } } }