243 lines
7.6 KiB
C
243 lines
7.6 KiB
C
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 2 -*- */
|
|
/*
|
|
* gcal-editable-combo.c
|
|
*
|
|
* Copyright (C) 2012 - Erick Pérez Castellanos
|
|
*
|
|
* 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 2 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "gcal-editable-combo.h"
|
|
|
|
struct _GcalEditableComboPrivate
|
|
{
|
|
GtkWidget *view_widget;
|
|
GtkWidget *edit_widget;
|
|
};
|
|
|
|
static void gcal_editable_combo_constructed (GObject *object);
|
|
|
|
static void gcal_editable_combo_size_allocate (GtkWidget *widget,
|
|
GtkAllocation *allocation);
|
|
|
|
static void gcal_editable_combo_enter_edit_mode (GcalEditable *editable);
|
|
|
|
static void gcal_editable_combo_leave_edit_mode (GcalEditable *editable);
|
|
|
|
static void gcal_editable_combo_clear (GcalEditable *editable);
|
|
|
|
G_DEFINE_TYPE (GcalEditableCombo, gcal_editable_combo, GCAL_TYPE_EDITABLE);
|
|
|
|
static void gcal_editable_combo_class_init (GcalEditableComboClass *klass)
|
|
{
|
|
GcalEditableClass *editable_class;
|
|
GtkWidgetClass *widget_class;
|
|
GObjectClass *object_class;
|
|
|
|
editable_class = GCAL_EDITABLE_CLASS (klass);
|
|
editable_class->enter_edit_mode = gcal_editable_combo_enter_edit_mode;
|
|
editable_class->leave_edit_mode = gcal_editable_combo_leave_edit_mode;
|
|
editable_class->clear = gcal_editable_combo_clear;
|
|
|
|
widget_class = GTK_WIDGET_CLASS (klass);
|
|
widget_class->size_allocate = gcal_editable_combo_size_allocate;
|
|
|
|
object_class = G_OBJECT_CLASS (klass);
|
|
object_class->constructed = gcal_editable_combo_constructed;
|
|
|
|
g_type_class_add_private ((gpointer)klass, sizeof (GcalEditableComboPrivate));
|
|
}
|
|
|
|
|
|
|
|
static void gcal_editable_combo_init (GcalEditableCombo *self)
|
|
{
|
|
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
|
GCAL_TYPE_EDITABLE_COMBO,
|
|
GcalEditableComboPrivate);
|
|
}
|
|
|
|
static void
|
|
gcal_editable_combo_constructed (GObject *object)
|
|
{
|
|
GcalEditableComboPrivate *priv;
|
|
|
|
priv = GCAL_EDITABLE_COMBO (object)->priv;
|
|
|
|
if (G_OBJECT_CLASS (gcal_editable_combo_parent_class)->constructed != NULL)
|
|
G_OBJECT_CLASS (gcal_editable_combo_parent_class)->constructed (object);
|
|
|
|
priv->view_widget = gtk_label_new (NULL);
|
|
gtk_label_set_ellipsize (GTK_LABEL (priv->view_widget),
|
|
PANGO_ELLIPSIZE_END);
|
|
gtk_widget_show (priv->view_widget);
|
|
gtk_widget_set_valign (priv->view_widget, GTK_ALIGN_CENTER);
|
|
gtk_widget_set_halign (priv->view_widget, GTK_ALIGN_START);
|
|
gcal_editable_set_view_widget (GCAL_EDITABLE (object), priv->view_widget);
|
|
|
|
priv->edit_widget = gtk_combo_box_new ();
|
|
gtk_widget_show (priv->edit_widget);
|
|
gcal_editable_set_edit_widget (GCAL_EDITABLE (object), priv->edit_widget);
|
|
}
|
|
|
|
static void
|
|
gcal_editable_combo_size_allocate (GtkWidget *widget,
|
|
GtkAllocation *allocation)
|
|
{
|
|
GcalEditableComboPrivate *priv;
|
|
GtkAllocation view_allocation;
|
|
gint minimum;
|
|
gint natural;
|
|
|
|
g_return_if_fail (GCAL_IS_EDITABLE_COMBO (widget));
|
|
priv = GCAL_EDITABLE_COMBO (widget)->priv;
|
|
|
|
if (GTK_WIDGET_CLASS (gcal_editable_combo_parent_class)->size_allocate != NULL)
|
|
GTK_WIDGET_CLASS (gcal_editable_combo_parent_class)->size_allocate (widget, allocation);
|
|
|
|
//FIXME: hack to keep the label thin
|
|
gtk_widget_get_preferred_height (priv->view_widget, &minimum, &natural);
|
|
gtk_widget_get_allocation (priv->view_widget, &view_allocation);
|
|
view_allocation.height = minimum;
|
|
gtk_widget_size_allocate (priv->view_widget, &view_allocation);
|
|
}
|
|
|
|
static void
|
|
gcal_editable_combo_enter_edit_mode (GcalEditable *editable)
|
|
{
|
|
GcalEditableComboPrivate *priv;
|
|
gchar *uid;
|
|
|
|
g_return_if_fail (GCAL_IS_EDITABLE_COMBO (editable));
|
|
priv = GCAL_EDITABLE_COMBO (editable)->priv;
|
|
|
|
if (gtk_combo_box_get_model (GTK_COMBO_BOX (priv->edit_widget)) != NULL)
|
|
{
|
|
uid = gcal_get_source_uid (
|
|
gtk_combo_box_get_model (GTK_COMBO_BOX (priv->edit_widget)),
|
|
gtk_label_get_text (GTK_LABEL (priv->view_widget)));
|
|
|
|
gtk_combo_box_set_active_id (GTK_COMBO_BOX (priv->edit_widget), uid);
|
|
g_free (uid);
|
|
|
|
gtk_widget_grab_focus (priv->edit_widget);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gcal_editable_combo_leave_edit_mode (GcalEditable *editable)
|
|
{
|
|
GcalEditableComboPrivate *priv;
|
|
gchar *name;
|
|
|
|
g_return_if_fail (GCAL_IS_EDITABLE_COMBO (editable));
|
|
priv = GCAL_EDITABLE_COMBO (editable)->priv;
|
|
|
|
if (gtk_combo_box_get_model (GTK_COMBO_BOX (priv->edit_widget)) == NULL)
|
|
{
|
|
gtk_label_set_text (GTK_LABEL (priv->view_widget), NULL);
|
|
}
|
|
else
|
|
{
|
|
name = gcal_get_source_name (
|
|
gtk_combo_box_get_model (GTK_COMBO_BOX (priv->edit_widget)),
|
|
gtk_combo_box_get_active_id (GTK_COMBO_BOX (priv->edit_widget)));
|
|
|
|
gtk_label_set_text (GTK_LABEL (priv->view_widget), name);
|
|
g_free (name);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gcal_editable_combo_clear (GcalEditable *editable)
|
|
{
|
|
GcalEditableComboPrivate *priv;
|
|
|
|
g_return_if_fail (GCAL_IS_EDITABLE_COMBO (editable));
|
|
priv = GCAL_EDITABLE_COMBO (editable)->priv;
|
|
|
|
gtk_label_set_text (GTK_LABEL (priv->view_widget), NULL);
|
|
gtk_combo_box_set_active (GTK_COMBO_BOX (priv->edit_widget), -1);
|
|
}
|
|
|
|
/**
|
|
* gcal_editable_combo_new:
|
|
*
|
|
* Init the combo in EDIT_MODE
|
|
*
|
|
* Since: 0.1
|
|
* Returns: (transfer full):
|
|
**/
|
|
GtkWidget*
|
|
gcal_editable_combo_new (void)
|
|
{
|
|
GtkWidget *combo = g_object_new (GCAL_TYPE_EDITABLE_COMBO, NULL);
|
|
gcal_editable_enter_edit_mode (GCAL_EDITABLE (combo));
|
|
return combo;
|
|
}
|
|
|
|
/**
|
|
* gcal_editable_combo_new_with_content:
|
|
*
|
|
* Init the combo in VIEW_MODE
|
|
*
|
|
* Since 0.2
|
|
* Returns: (transfer full)
|
|
*/
|
|
GtkWidget*
|
|
gcal_editable_combo_new_with_content (const gchar* content)
|
|
{
|
|
GtkWidget *combo;
|
|
combo = g_object_new (GCAL_TYPE_EDITABLE_COMBO, NULL);
|
|
gcal_editable_combo_set_content (GCAL_EDITABLE_COMBO (combo), content);
|
|
gcal_editable_leave_edit_mode (GCAL_EDITABLE (combo));
|
|
return combo;
|
|
}
|
|
|
|
void
|
|
gcal_editable_combo_set_model (GcalEditableCombo *combo,
|
|
GtkTreeModel *model)
|
|
{
|
|
GcalEditableComboPrivate *priv;
|
|
GtkCellRenderer *renderer;
|
|
|
|
g_return_if_fail (GCAL_IS_EDITABLE_COMBO (combo));
|
|
priv = combo->priv;
|
|
|
|
gtk_combo_box_set_model (GTK_COMBO_BOX (priv->edit_widget), model);
|
|
gtk_combo_box_set_id_column (GTK_COMBO_BOX (priv->edit_widget), 0);
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->edit_widget),
|
|
renderer,
|
|
TRUE);
|
|
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (priv->edit_widget),
|
|
renderer,
|
|
"text",
|
|
1,
|
|
NULL);
|
|
gtk_combo_box_set_active (GTK_COMBO_BOX (priv->edit_widget), 0);
|
|
}
|
|
|
|
void
|
|
gcal_editable_combo_set_content (GcalEditableCombo *combo,
|
|
const gchar *content)
|
|
{
|
|
GcalEditableComboPrivate *priv;
|
|
|
|
g_return_if_fail (GCAL_IS_EDITABLE_COMBO (combo));
|
|
priv = combo->priv;
|
|
|
|
gtk_label_set_text (GTK_LABEL (priv->view_widget), content);
|
|
}
|