/* * Copyright (C) 2012 - Juan Ferrer Toribio * * 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, see . */ #include "vn-column-spin.h" #include "../vn-list-model.h" G_DEFINE_TYPE (VnColumnSpin, vn_column_spin, VN_TYPE_COLUMN); VnColumn * vn_column_spin_new () { return g_object_new (VN_TYPE_COLUMN_SPIN, NULL); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private static void vn_column_spin_on_edited (GtkCellRendererSpin * cell, const gchar * path, gchar * text, VnColumnSpin * self) { GValue value = G_VALUE_INIT; if (g_strcmp0 (text, "")) { g_value_init (&value, G_TYPE_DOUBLE); g_value_set_double (&value, g_strtod (text, NULL)); } else g_value_init (&value, GVN_TYPE_NULL); VN_COLUMN_GET_CLASS (self)->value_changed (VN_COLUMN (self), path, &value); g_value_unset (&value); } void vn_column_spin_on_editing_started (GtkCellRenderer * renderer, GtkEntry * entry, gchar * path, GtkTreeViewColumn * self) { GtkTreeIter iter; GtkTreeModel * model; GtkTreeView * tree; if (!GTK_IS_SPIN_BUTTON (entry)) return; tree = GTK_TREE_VIEW (gtk_tree_view_column_get_tree_view (self)); model = gtk_tree_view_get_model (tree); if (gtk_tree_model_get_iter_from_string (model, &iter, path)) { GValue value = G_VALUE_INIT; gint col = vn_column_get_column_index (VN_COLUMN (self)); gtk_tree_model_get_value (model, &iter, col, &value); if (gvn_value_is_null (&value)) gtk_entry_set_text (entry, ""); } } static void vn_column_spin_set_editable (VnColumn * self, gboolean editable) { if (editable) { g_signal_connect (self->cell, "editing-started", G_CALLBACK (vn_column_spin_on_editing_started), self); g_signal_connect (self->cell, "edited", G_CALLBACK (vn_column_spin_on_edited), self); } else { g_signal_handlers_disconnect_by_func (self->cell, vn_column_spin_on_editing_started, self); g_signal_handlers_disconnect_by_func (self->cell, vn_column_spin_on_edited, self); } g_object_set (self->cell, "editable", editable, NULL); } static void vn_column_spin_set_value (VnColumnSpin * self, GtkTreeModel * model, GtkTreeIter * iter, GObject * cell, const GValue * value) { guint digits; GType type = G_VALUE_TYPE (value); GValue new_value = G_VALUE_INIT; g_value_init (&new_value, G_TYPE_STRING); g_object_get (cell, "digits", &digits, NULL); switch (type) { case G_TYPE_FLOAT: case G_TYPE_DOUBLE: { gdouble dec; gchar buffer [G_ASCII_DTOSTR_BUF_SIZE]; if (type == G_TYPE_FLOAT) dec = (gdouble) g_value_get_float (value); else dec = g_value_get_double (value); g_ascii_formatd (buffer, G_ASCII_DTOSTR_BUF_SIZE, self->format, dec); g_value_set_string (&new_value, buffer); break; } default: if (!gvn_value_is_null (value)) g_value_transform (value, &new_value); else g_value_set_string (&new_value, ""); } g_object_set_property (cell, "text", &new_value); g_value_unset (&new_value); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class enum { PROP_DIGITS = 1 }; static void vn_column_spin_set_property (VnColumnSpin * self, guint id, const GValue * value, GParamSpec * pspec) { switch (id) { case PROP_DIGITS: { guint digits = g_value_get_uint (value); g_object_set (VN_COLUMN (self)->cell, "digits", digits, NULL); g_free (self->format); self->format = g_strdup_printf ("%%.%df", digits); break; } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec); } } static void vn_column_spin_get_property (VnColumnSpin * self, guint id, GValue * value, GParamSpec * pspec) { switch (id) { case PROP_DIGITS: g_object_get_property (G_OBJECT (VN_COLUMN (self)->cell), "digits", value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec); } } static void vn_column_spin_init (VnColumnSpin * self) { GtkCellRenderer * cell; self->format = NULL; cell = gtk_cell_renderer_spin_new (); g_object_set (cell ,"xalign", 1.0 ,"alignment", PANGO_ALIGN_RIGHT ,NULL ); VN_COLUMN_GET_CLASS (self)->set_renderer (VN_COLUMN (self), cell); } static void vn_column_spin_finalize (VnColumnSpin * self) { g_free (self->format); G_OBJECT_CLASS (vn_column_spin_parent_class)->finalize (G_OBJECT (self)); } static void vn_column_spin_class_init (VnColumnSpinClass * klass) { GObjectClass * k = G_OBJECT_CLASS (klass); VnColumnClass * col_k = VN_COLUMN_CLASS (klass); k->finalize = (GObjectFinalizeFunc) vn_column_spin_finalize; k->set_property = (GObjectSetPropertyFunc) vn_column_spin_set_property; k->get_property = (GObjectGetPropertyFunc) vn_column_spin_get_property; col_k->set_value = (VnColumnSetValueFunc) vn_column_spin_set_value; col_k->set_editable = (VnColumnSetEditableFunc) vn_column_spin_set_editable; g_object_class_install_property (k, PROP_DIGITS, g_param_spec_uint ("digits" ,_("Digits") ,_("The number of decimal places to display.") ,0 ,20 ,0 ,G_PARAM_CONSTRUCT | G_PARAM_READWRITE )); }