1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
4
* Copyright (C) Philip Withnall 2008 <philip@tecnocode.co.uk>
6
* Almanah is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
11
* Almanah is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with Almanah. If not, see <http://www.gnu.org/licenses/>.
27
static void almanah_entry_init (AlmanahEntry *self);
28
static void almanah_entry_finalize (GObject *object);
29
static void almanah_entry_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
30
static void almanah_entry_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
32
struct _AlmanahEntryPrivate {
45
G_DEFINE_TYPE (AlmanahEntry, almanah_entry, G_TYPE_OBJECT)
46
#define ALMANAH_ENTRY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ALMANAH_TYPE_ENTRY, AlmanahEntryPrivate))
49
almanah_entry_class_init (AlmanahEntryClass *klass)
51
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
53
g_type_class_add_private (klass, sizeof (AlmanahEntryPrivate));
55
gobject_class->set_property = almanah_entry_set_property;
56
gobject_class->get_property = almanah_entry_get_property;
57
gobject_class->finalize = almanah_entry_finalize;
59
g_object_class_install_property (gobject_class, PROP_DAY,
60
g_param_spec_uint ("day",
61
"Day", "The day for which this is the entry.",
63
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
64
g_object_class_install_property (gobject_class, PROP_MONTH,
65
g_param_spec_uint ("month",
66
"Month", "The month for which this is the entry.",
68
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
69
g_object_class_install_property (gobject_class, PROP_YEAR,
70
g_param_spec_uint ("year",
71
"Year", "The year for which this is the entry.",
73
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
77
almanah_entry_init (AlmanahEntry *self)
79
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, ALMANAH_TYPE_ENTRY, AlmanahEntryPrivate);
80
self->priv->data = NULL;
81
self->priv->length = 0;
82
g_date_clear (&(self->priv->date), 1);
86
almanah_entry_finalize (GObject *object)
88
AlmanahEntryPrivate *priv = ALMANAH_ENTRY (object)->priv;
93
/* Chain up to the parent class */
94
G_OBJECT_CLASS (almanah_entry_parent_class)->finalize (object);
98
almanah_entry_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
100
AlmanahEntryPrivate *priv = ALMANAH_ENTRY (object)->priv;
102
switch (property_id) {
104
g_value_set_uint (value, g_date_get_day (&(priv->date)));
107
g_value_set_uint (value, g_date_get_month (&(priv->date)));
110
g_value_set_uint (value, g_date_get_year (&(priv->date)));
113
/* We don't have any other property... */
114
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
120
almanah_entry_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
122
AlmanahEntryPrivate *priv = ALMANAH_ENTRY (object)->priv;
124
switch (property_id) {
126
g_date_set_day (&(priv->date), g_value_get_uint (value));
129
g_date_set_month (&(priv->date), g_value_get_uint (value));
132
g_date_set_year (&(priv->date), g_value_get_uint (value));
135
/* We don't have any other property... */
136
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
142
almanah_entry_new (GDate *date)
144
return g_object_new (ALMANAH_TYPE_ENTRY,
145
"day", g_date_get_day (date),
146
"month", g_date_get_month (date),
147
"year", g_date_get_year (date),
151
/* NOTE: There's a difference between content and data, as recognised by AlmanahEntry.
152
* Content is deserialized, and handled in terms of GtkTextBuffers.
153
* Data is serialized, and handled in terms of a guint8 *data and gsize length. */
155
almanah_entry_get_data (AlmanahEntry *self, gsize *length)
158
*length = self->priv->length;
159
return self->priv->data;
163
almanah_entry_set_data (AlmanahEntry *self, const guint8 *data, gsize length)
165
AlmanahEntryPrivate *priv = self->priv;
169
priv->data = g_memdup (data, length * sizeof (*data));
170
priv->length = length;
171
priv->is_empty = FALSE;
175
almanah_entry_get_content (AlmanahEntry *self, GtkTextBuffer *text_buffer, gboolean create_tags, GError **error)
178
GtkTextIter start_iter;
179
AlmanahEntryPrivate *priv = self->priv;
180
GError *deserialise_error = NULL;
182
format_atom = gtk_text_buffer_register_deserialize_tagset (text_buffer, PACKAGE_NAME);
183
gtk_text_buffer_deserialize_set_can_create_tags (text_buffer, format_atom, create_tags);
184
gtk_text_buffer_get_start_iter (text_buffer, &start_iter);
186
/* Try deserializing the (hopefully) serialized data first */
187
if (gtk_text_buffer_deserialize (text_buffer, text_buffer,
190
priv->data, priv->length,
191
&deserialise_error) == FALSE) {
192
/* Since that failed, check the data's in the old format, and try to just load it as text */
193
if (g_strcmp0 ((gchar*) priv->data, "GTKTEXTBUFFERCONTENTS-0001") != 0) {
194
gtk_text_buffer_set_text (text_buffer, (gchar*) priv->data, priv->length);
195
g_error_free (deserialise_error);
199
g_propagate_error (error, deserialise_error);
207
almanah_entry_set_content (AlmanahEntry *self, GtkTextBuffer *text_buffer)
209
GtkTextIter start, end;
211
AlmanahEntryPrivate *priv = self->priv;
213
/* Update our cached empty status */
214
self->priv->is_empty = (gtk_text_buffer_get_char_count (text_buffer) == 0) ? TRUE : FALSE;
218
gtk_text_buffer_get_bounds (text_buffer, &start, &end);
219
format_atom = gtk_text_buffer_register_serialize_tagset (text_buffer, PACKAGE_NAME);
220
priv->data = gtk_text_buffer_serialize (text_buffer, text_buffer,
226
/* NOTE: Designed for use on the stack */
228
almanah_entry_get_date (AlmanahEntry *self, GDate *date)
230
g_date_set_dmy (date,
231
g_date_get_day (&(self->priv->date)),
232
g_date_get_month (&(self->priv->date)),
233
g_date_get_year (&(self->priv->date)));
236
AlmanahEntryEditability
237
almanah_entry_get_editability (AlmanahEntry *self)
242
/* Entries are always editable if we have import mode on */
243
if (almanah->import_mode == TRUE)
244
return ALMANAH_ENTRY_EDITABLE;
246
g_date_set_time_t (¤t_date, time (NULL));
248
/* Entries can't be edited before they've happened */
249
days_between = g_date_days_between (&(self->priv->date), ¤t_date);
251
if (days_between < 0)
252
return ALMANAH_ENTRY_FUTURE;
253
else if (days_between > ALMANAH_ENTRY_CUTOFF_AGE)
254
return ALMANAH_ENTRY_PAST;
256
return ALMANAH_ENTRY_EDITABLE;
260
almanah_entry_is_empty (AlmanahEntry *self)
262
return (self->priv->is_empty == TRUE ||
263
self->priv->length == 0 ||
264
self->priv->data == NULL ||
265
self->priv->data[0] == '\0') ? TRUE : FALSE;