1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3
* Copyright 2009-2010 Red Hat, Inc,
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
* Written by: Matthias Clasen <mclasen@redhat.com>
22
#include <gdk/gdkkeysyms.h>
23
#include "cc-editable-entry.h"
25
#define EMPTY_TEXT "\xe2\x80\x94"
27
struct _CcEditableEntryPrivate {
28
GtkNotebook *notebook;
41
gboolean in_stop_editing;
44
#define CC_EDITABLE_ENTRY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CC_TYPE_EDITABLE_ENTRY, CcEditableEntryPrivate))
68
static guint signals [LAST_SIGNAL] = { 0, };
70
G_DEFINE_TYPE (CcEditableEntry, cc_editable_entry, GTK_TYPE_ALIGNMENT);
73
cc_editable_entry_set_text (CcEditableEntry *e,
76
CcEditableEntryPrivate *priv;
82
tmp = g_strdup (text);
86
gtk_entry_set_text (priv->entry, tmp);
88
if (tmp == NULL || tmp[0] == '\0')
91
gtk_label_set_text (priv->label, tmp);
92
label = gtk_bin_get_child (GTK_BIN (priv->button));
93
gtk_label_set_text (GTK_LABEL (label), tmp);
95
g_object_notify (G_OBJECT (e), "text");
99
cc_editable_entry_get_text (CcEditableEntry *e)
101
return e->priv->text;
105
cc_editable_entry_set_editable (CcEditableEntry *e,
108
CcEditableEntryPrivate *priv;
112
if (priv->editable != editable) {
113
priv->editable = editable;
115
gtk_notebook_set_current_page (priv->notebook, editable ? PAGE_BUTTON : PAGE_LABEL);
117
g_object_notify (G_OBJECT (e), "editable");
122
cc_editable_entry_get_editable (CcEditableEntry *e)
124
return e->priv->editable;
128
cc_editable_entry_set_selectable (CcEditableEntry *e,
131
CcEditableEntryPrivate *priv;
135
if (priv->selectable != selectable) {
136
priv->selectable = selectable;
138
gtk_label_set_selectable (priv->label, selectable);
140
g_object_notify (G_OBJECT (e), "selectable");
145
cc_editable_entry_get_selectable (CcEditableEntry *e)
147
return e->priv->selectable;
152
update_fonts (CcEditableEntry *e)
154
PangoAttrList *attrs;
155
PangoAttribute *attr;
158
CcEditableEntryPrivate *priv = e->priv;
160
attrs = pango_attr_list_new ();
161
if (priv->scale_set) {
162
attr = pango_attr_scale_new (priv->scale);
163
pango_attr_list_insert (attrs, attr);
165
if (priv->weight_set) {
166
attr = pango_attr_weight_new (priv->weight);
167
pango_attr_list_insert (attrs, attr);
170
gtk_label_set_attributes (priv->label, attrs);
172
label = gtk_bin_get_child (GTK_BIN (priv->button));
173
gtk_label_set_attributes (GTK_LABEL (label), attrs);
174
gtk_entry_set_attributes (priv->entry, attrs);
176
pango_attr_list_unref (attrs);
180
cc_editable_entry_set_weight (CcEditableEntry *e,
183
CcEditableEntryPrivate *priv = e->priv;
185
if (priv->weight == weight && priv->weight_set)
188
priv->weight = weight;
189
priv->weight_set = TRUE;
193
g_object_notify (G_OBJECT (e), "weight");
194
g_object_notify (G_OBJECT (e), "weight-set");
198
cc_editable_entry_get_weight (CcEditableEntry *e)
200
return e->priv->weight;
204
cc_editable_entry_set_scale (CcEditableEntry *e,
207
CcEditableEntryPrivate *priv = e->priv;
209
if (priv->scale == scale && priv->scale_set)
213
priv->scale_set = TRUE;
217
g_object_notify (G_OBJECT (e), "scale");
218
g_object_notify (G_OBJECT (e), "scale-set");
222
cc_editable_entry_get_scale (CcEditableEntry *e)
224
return e->priv->scale;
228
cc_editable_entry_set_property (GObject *object,
233
CcEditableEntry *e = CC_EDITABLE_ENTRY (object);
237
cc_editable_entry_set_text (e, g_value_get_string (value));
240
cc_editable_entry_set_editable (e, g_value_get_boolean (value));
242
case PROP_SELECTABLE:
243
cc_editable_entry_set_selectable (e, g_value_get_boolean (value));
246
cc_editable_entry_set_weight (e, g_value_get_int (value));
248
case PROP_WEIGHT_SET:
249
e->priv->weight_set = g_value_get_boolean (value);
252
cc_editable_entry_set_scale (e, g_value_get_double (value));
255
e->priv->scale_set = g_value_get_boolean (value);
258
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
264
cc_editable_entry_get_property (GObject *object,
269
CcEditableEntry *e = CC_EDITABLE_ENTRY (object);
273
g_value_set_string (value,
274
cc_editable_entry_get_text (e));
277
g_value_set_boolean (value,
278
cc_editable_entry_get_editable (e));
280
case PROP_SELECTABLE:
281
g_value_set_boolean (value,
282
cc_editable_entry_get_selectable (e));
285
g_value_set_int (value,
286
cc_editable_entry_get_weight (e));
288
case PROP_WEIGHT_SET:
289
g_value_set_boolean (value, e->priv->weight_set);
292
g_value_set_double (value,
293
cc_editable_entry_get_scale (e));
296
g_value_set_boolean (value, e->priv->scale_set);
299
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
305
cc_editable_entry_finalize (GObject *object)
307
CcEditableEntry *e = (CcEditableEntry*)object;
309
g_free (e->priv->text);
311
G_OBJECT_CLASS (cc_editable_entry_parent_class)->finalize (object);
315
cc_editable_entry_class_init (CcEditableEntryClass *class)
317
GObjectClass *object_class;
319
object_class = G_OBJECT_CLASS (class);
321
object_class->set_property = cc_editable_entry_set_property;
322
object_class->get_property = cc_editable_entry_get_property;
323
object_class->finalize = cc_editable_entry_finalize;
325
signals[EDITING_DONE] =
326
g_signal_new ("editing-done",
327
G_TYPE_FROM_CLASS (class),
329
G_STRUCT_OFFSET (CcEditableEntryClass, editing_done),
331
g_cclosure_marshal_VOID__VOID,
334
g_object_class_install_property (object_class, PROP_TEXT,
335
g_param_spec_string ("text",
336
"Text", "The text of the button",
340
g_object_class_install_property (object_class, PROP_EDITABLE,
341
g_param_spec_boolean ("editable",
342
"Editable", "Whether the text can be edited",
346
g_object_class_install_property (object_class, PROP_SELECTABLE,
347
g_param_spec_boolean ("selectable",
348
"Selectable", "Whether the text can be selected by mouse",
352
g_object_class_install_property (object_class, PROP_WEIGHT,
353
g_param_spec_int ("weight",
354
"Font Weight", "The font weight to use",
355
0, G_MAXINT, PANGO_WEIGHT_NORMAL,
358
g_object_class_install_property (object_class, PROP_WEIGHT_SET,
359
g_param_spec_boolean ("weight-set",
360
"Font Weight Set", "Whether a font weight is set",
364
g_object_class_install_property (object_class, PROP_SCALE,
365
g_param_spec_double ("scale",
366
"Font Scale", "The font scale to use",
367
0.0, G_MAXDOUBLE, 1.0,
370
g_object_class_install_property (object_class, PROP_SCALE_SET,
371
g_param_spec_boolean ("scale-set",
372
"Font Scale Set", "Whether a font scale is set",
376
g_type_class_add_private (class, sizeof (CcEditableEntryPrivate));
380
start_editing (CcEditableEntry *e)
382
gtk_notebook_set_current_page (e->priv->notebook, PAGE_ENTRY);
386
stop_editing (CcEditableEntry *e)
388
/* Avoid launching another "editing-done" signal
389
* caused by the notebook page change */
390
if (e->priv->in_stop_editing)
393
e->priv->in_stop_editing = TRUE;
394
gtk_notebook_set_current_page (e->priv->notebook, PAGE_BUTTON);
395
cc_editable_entry_set_text (e, gtk_entry_get_text (e->priv->entry));
396
g_signal_emit (e, signals[EDITING_DONE], 0);
397
e->priv->in_stop_editing = FALSE;
401
cancel_editing (CcEditableEntry *e)
403
gtk_entry_set_text (e->priv->entry, cc_editable_entry_get_text (e));
404
gtk_notebook_set_current_page (e->priv->notebook, PAGE_BUTTON);
408
button_clicked (GtkWidget *widget,
415
entry_activated (GtkWidget *widget,
422
entry_focus_out (GtkWidget *widget,
423
GdkEventFocus *event,
431
entry_key_press (GtkWidget *widget,
435
if (event->keyval == GDK_KEY_Escape) {
442
update_button_padding (GtkWidget *widget,
443
GtkAllocation *allocation,
446
CcEditableEntryPrivate *priv = e->priv;
451
gtk_widget_get_allocation (gtk_widget_get_parent (widget), &alloc);
453
offset = allocation->x - alloc.x;
455
gtk_misc_get_padding (GTK_MISC (priv->label), &pad, NULL);
457
gtk_misc_set_padding (GTK_MISC (priv->label), offset, 0);
461
cc_editable_entry_init (CcEditableEntry *e)
463
CcEditableEntryPrivate *priv;
465
priv = e->priv = CC_EDITABLE_ENTRY_GET_PRIVATE (e);
467
priv->weight = PANGO_WEIGHT_NORMAL;
468
priv->weight_set = FALSE;
470
priv->scale_set = FALSE;
472
priv->notebook = (GtkNotebook*)gtk_notebook_new ();
473
gtk_notebook_set_show_tabs (priv->notebook, FALSE);
474
gtk_notebook_set_show_border (priv->notebook, FALSE);
477
priv->label = (GtkLabel*)gtk_label_new (EMPTY_TEXT);
478
gtk_misc_set_alignment (GTK_MISC (priv->label), 0.0, 0.5);
479
gtk_notebook_append_page (priv->notebook, (GtkWidget*)priv->label, NULL);
482
priv->button = (GtkButton*)gtk_button_new_with_label (EMPTY_TEXT);
483
gtk_widget_set_receives_default ((GtkWidget*)priv->button, TRUE);
484
gtk_button_set_relief (priv->button, GTK_RELIEF_NONE);
485
gtk_button_set_alignment (priv->button, 0.0, 0.5);
486
gtk_notebook_append_page (priv->notebook, (GtkWidget*)priv->button, NULL);
487
g_signal_connect (priv->button, "clicked", G_CALLBACK (button_clicked), e);
490
priv->entry = (GtkEntry*)gtk_entry_new ();
491
gtk_notebook_append_page (priv->notebook, (GtkWidget*)priv->entry, NULL);
493
g_signal_connect (priv->entry, "activate", G_CALLBACK (entry_activated), e);
494
g_signal_connect (priv->entry, "focus-out-event", G_CALLBACK (entry_focus_out), e);
495
g_signal_connect (priv->entry, "key-press-event", G_CALLBACK (entry_key_press), e);
496
g_signal_connect (gtk_bin_get_child (GTK_BIN (priv->button)), "size-allocate", G_CALLBACK (update_button_padding), e);
498
gtk_container_add (GTK_CONTAINER (e), (GtkWidget*)priv->notebook);
500
gtk_widget_show ((GtkWidget*)priv->notebook);
501
gtk_widget_show ((GtkWidget*)priv->label);
502
gtk_widget_show ((GtkWidget*)priv->button);
503
gtk_widget_show ((GtkWidget*)priv->entry);
505
gtk_notebook_set_current_page (priv->notebook, PAGE_LABEL);
509
cc_editable_entry_new (void)
511
return (GtkWidget *) g_object_new (CC_TYPE_EDITABLE_ENTRY, NULL);