GTK+2 panel 

GTK+2 panel Git Source Tree

Root/libgpwidgets/gpw-strftime.c

1/* Gtk2Panel - A bleeding edge Gtk+2 panel
2 * Copyright (C) 2009 Nicola Fontana <ntd at entidi.it>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20
21/**
22 * SECTION:gpw-strftime
23 * @title: GpwStrftime
24 * @short_description: A #GtkLabel showing a provided time string
25 *
26 * GpwStrftime is GtkLabel widget with its content based on strftime():
27 * as such it can show any string returned by strftime(). This allows
28 * to express both date and time throught a single or different
29 * labels based on the same widget.
30 *
31 * The GpwStrftime:format property specifies the template argument to pass
32 * to strftime(). There is an hardcoded limit of 255 chars for label length.
33 *
34 * With GpwStrftime:period (an unsigned integer value expressed in
35 * milliseconds) you can fine tune the frequency of updates. Setting it
36 * to 0 will disable the updating of tha label.
37 **/
38
39/**
40 * GpwStrftime:
41 *
42 * All fields are private and should not be used directly.
43 * Use its public methods instead.
44 **/
45
46
47#include "gpw-strftime.h"
48#include "gpw-strftime-private.h"
49#include "gpw-intl.h"
50
51
52enum {
53 PROP_0,
54 PROP_FORMAT,
55 PROP_PERIOD
56};
57
58
59static void get_property (GObject *object,
60 guint prop_id,
61 GValue *value,
62 GParamSpec *pspec);
63static void set_property (GObject *object,
64 guint prop_id,
65 const GValue *value,
66 GParamSpec *pspec);
67static void finalize (GObject *object);
68static void realize (GtkWidget *widget);
69static void set_format (GpwStrftime *gpw_strftime,
70 const gchar *format);
71static void set_period (GpwStrftime *gpw_strftime,
72 guint period);
73static gboolean update (GpwStrftime *gpw_strftime);
74
75
76G_DEFINE_TYPE(GpwStrftime, gpw_strftime, GTK_TYPE_LABEL);
77
78
79static void
80gpw_strftime_class_init(GpwStrftimeClass *klass)
81{
82 GObjectClass *gobject_class;
83 GtkWidgetClass *widget_class;
84 GParamSpec *param;
85
86 gobject_class = (GObjectClass *) klass;
87 widget_class = (GtkWidgetClass *) klass;
88
89 g_type_class_add_private(klass, sizeof(GpwStrftimePrivate));
90
91 gobject_class->get_property = get_property;
92 gobject_class->set_property = set_property;
93 gobject_class->finalize = finalize;
94
95 widget_class->realize = realize;
96
97 param = g_param_spec_string("format",
98 P_("Format"),
99 P_("The format to use as template for strftime()"),
100 NULL,
101 G_PARAM_READWRITE);
102 g_object_class_install_property(gobject_class, PROP_FORMAT, param);
103
104 param = g_param_spec_uint("period",
105 P_("Period"),
106 P_("The time frame (in milliseconds) between two updates"),
107 0, G_MAXUINT, 0,
108 G_PARAM_READWRITE);
109 g_object_class_install_property(gobject_class, PROP_PERIOD, param);
110}
111
112static void
113gpw_strftime_init(GpwStrftime *gpw_strftime)
114{
115 GpwStrftimePrivate *data;
116
117 data = G_TYPE_INSTANCE_GET_PRIVATE(gpw_strftime, GPW_TYPE_STRFTIME,
118 GpwStrftimePrivate);
119
120 data->poll = 0;
121 data->format = NULL;
122 data->period = 0;
123
124 gpw_strftime->data = data;
125}
126
127static void
128get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
129{
130 GpwStrftimePrivate *data = GPW_STRFTIME_GET_DATA(object);
131
132 switch (prop_id) {
133 case PROP_FORMAT:
134 g_value_set_string(value, data->format);
135 break;
136 case PROP_PERIOD:
137 g_value_set_uint(value, data->period);
138 break;
139 default:
140 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
141 break;
142 }
143}
144
145static void
146set_property(GObject *object,
147 guint prop_id, const GValue *value, GParamSpec *pspec)
148{
149 GpwStrftime *gpw_strftime = (GpwStrftime *) object;
150
151 switch (prop_id) {
152 case PROP_FORMAT:
153 set_format(gpw_strftime, g_value_get_string(value));
154 break;
155 case PROP_PERIOD:
156 set_period(gpw_strftime, g_value_get_uint(value));
157 break;
158 default:
159 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
160 break;
161 }
162}
163
164static void
165finalize(GObject *object)
166{
167 GpwStrftime *gpw_strftime = (GpwStrftime *) object;
168
169 set_format(gpw_strftime, NULL);
170 set_period(gpw_strftime, 0);
171
172 G_OBJECT_CLASS(gpw_strftime_parent_class)->finalize(object);
173}
174
175static void
176realize(GtkWidget *widget)
177{
178 GpwStrftimePrivate *data = GPW_STRFTIME_GET_DATA(widget);
179
180 ((GtkWidgetClass *) gpw_strftime_parent_class)->realize(widget);
181
182 /* Ensure the timeout callback is properly set */
183 set_period((GpwStrftime *) widget, data->period);
184}
185
186static void
187set_format(GpwStrftime *gpw_strftime, const gchar *format)
188{
189 GpwStrftimePrivate *data = GPW_STRFTIME_GET_DATA(gpw_strftime);
190
191 /* Check for a "clear" request */
192 if (format == NULL) {
193 g_free(data->format);
194 data->format = NULL;
195 gtk_label_set_text(GTK_LABEL(gpw_strftime), "");
196 return;
197 }
198
199 /* Check if something changed */
200 if (data->format != NULL && strcmp(format, data->format) == 0)
201 return;
202
203 g_free(data->format);
204 data->format = g_strdup(format);
205 update(gpw_strftime);
206}
207
208static void
209set_period(GpwStrftime *gpw_strftime, guint period)
210{
211 GpwStrftimePrivate *data = GPW_STRFTIME_GET_DATA(gpw_strftime);
212
213 if (period == data->period)
214 return;
215
216 /* Remove the old timeout callback, if any */
217 if (data->poll != 0)
218 g_source_remove(data->poll);
219
220 /* Disable the updating if period is 0, otherwise reinstall the
221 * callback with the proper period */
222 if (period == 0)
223 data->poll = 0;
224 else
225 data->poll = g_timeout_add(period, (GSourceFunc) update, gpw_strftime);
226
227 data->period = period;
228}
229
230static gboolean
231update(GpwStrftime *gpw_strftime)
232{
233 GpwStrftimePrivate *data = GPW_STRFTIME_GET_DATA(gpw_strftime);
234
235 if (data->format != NULL) {
236 time_t now;
237 gchar buffer[256];
238
239 now = time(NULL);
240 strftime(buffer, 256, data->format, localtime(&now));
241
242 gtk_label_set_label(GTK_LABEL(gpw_strftime), buffer);
243 }
244
245 return TRUE;
246}

Archive Download this file

Branches

Tags