[almanah] Highlight important entries in the calendar



commit ad5ccd5a9ca76d8032e0e4b1d759a18c6daa0157
Author: Philip Withnall <philip tecnocode co uk>
Date:   Sun Apr 18 14:25:57 2010 +0100

    Highlight important entries in the calendar
    
    This creates a new AlmanahCalendar widget, which takes care of a few things
    which require extensions to GtkCalendar. This is now used across the project.
    Helps: bgo#572927

 data/almanah.ui        |    4 +-
 src/Makefile.am        |    4 +-
 src/interface.c        |   24 --------
 src/main-window.c      |   31 +++-------
 src/printing.c         |   29 ++++-----
 src/storage-manager.c  |   28 +++++++++
 src/storage-manager.h  |    1 +
 src/widgets/calendar.c |  152 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/widgets/calendar.h |   57 ++++++++++++++++++
 9 files changed, 265 insertions(+), 65 deletions(-)
---
diff --git a/data/almanah.ui b/data/almanah.ui
index 1731d12..2e75900 100644
--- a/data/almanah.ui
+++ b/data/almanah.ui
@@ -369,11 +369,11 @@
 											</packing>
 										</child>
 										<child>
-											<object class="GtkCalendar" id="almanah_mw_calendar">
+											<object class="AlmanahCalendar" id="almanah_mw_calendar">
 												<property name="width-request">200</property>
 												<property name="can-focus">True</property>
+												<property name="show-details">False</property>
 												<signal name="day-selected" handler="mw_calendar_day_selected_cb"/>
-												<signal name="month-changed" handler="almanah_calendar_month_changed_cb"/>
 												<accessibility>
 													<relation target="almanah_mw_calendar_label" type="labelled-by"/>
 												</accessibility>
diff --git a/src/Makefile.am b/src/Makefile.am
index bc816ed..627937f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -42,7 +42,9 @@ almanah_SOURCES = \
 	events/f-spot-photo.c		\
 	events/f-spot-photo.h		\
 	event-factories/f-spot.c	\
-	event-factories/f-spot.h
+	event-factories/f-spot.h	\
+	widgets/calendar.c		\
+	widgets/calendar.h
 
 if HAVE_EVO
 almanah_SOURCES += \
diff --git a/src/interface.c b/src/interface.c
index fcb3079..07d646c 100644
--- a/src/interface.c
+++ b/src/interface.c
@@ -106,27 +106,3 @@ almanah_interface_create_text_tags (GtkTextBuffer *text_buffer, gboolean connect
 	if (connect_events == TRUE)
 		g_signal_connect (tag, "event", G_CALLBACK (definition_tag_event_cb), NULL);
 }
-
-/* TODO: This exists so that different calendars can be highlighted according to which days have entries
- * (i.e. the ones on the print dialogue). This should eventually be replaced by a custom calendar widget. */
-void
-almanah_calendar_month_changed_cb (GtkCalendar *calendar, gpointer user_data)
-{
-	/* Mark the days on the calendar which have diary entries */
-	guint i, year, month, num_days;
-	gboolean *days;
-
-	gtk_calendar_get_date (calendar, &year, &month, NULL);
-	month++;
-	days = almanah_storage_manager_get_month_marked_days (almanah->storage_manager, year, month, &num_days);
-
-	gtk_calendar_clear_marks (calendar);
-	for (i = 0; i < num_days; i++) {
-		if (days[i] == TRUE)
-			gtk_calendar_mark_day (calendar, i + 1);
-		else
-			gtk_calendar_unmark_day (calendar, i + 1);
-	}
-
-	g_free (days);
-}
diff --git a/src/main-window.c b/src/main-window.c
index 1f2888e..5832b5f 100644
--- a/src/main-window.c
+++ b/src/main-window.c
@@ -41,6 +41,7 @@
 #include "definition.h"
 #include "definition-manager-window.h"
 #include "import-dialog.h"
+#include "widgets/calendar.h"
 
 static void almanah_main_window_dispose (GObject *object);
 static void save_window_state (AlmanahMainWindow *self);
@@ -87,7 +88,7 @@ void mw_view_button_clicked_cb (GtkButton *button, AlmanahMainWindow *main_windo
 struct _AlmanahMainWindowPrivate {
 	GtkTextView *entry_view;
 	GtkTextBuffer *entry_buffer;
-	GtkCalendar *calendar;
+	AlmanahCalendar *calendar;
 	GtkLabel *date_label;
 	GtkButton *view_button;
 	GtkAction *add_action;
@@ -194,7 +195,7 @@ almanah_main_window_new (void)
 	/* Grab our child widgets */
 	priv->entry_view = GTK_TEXT_VIEW (gtk_builder_get_object (builder, "almanah_mw_entry_view"));
 	priv->entry_buffer = gtk_text_view_get_buffer (priv->entry_view);
-	priv->calendar = GTK_CALENDAR (gtk_builder_get_object (builder, "almanah_mw_calendar"));
+	priv->calendar = ALMANAH_CALENDAR (gtk_builder_get_object (builder, "almanah_mw_calendar"));
 	priv->date_label = GTK_LABEL (gtk_builder_get_object (builder, "almanah_mw_date_label"));
 	priv->view_button = GTK_BUTTON (gtk_builder_get_object (builder, "almanah_mw_view_button"));
 	priv->add_action = GTK_ACTION (gtk_builder_get_object (builder, "almanah_ui_add_definition"));
@@ -247,8 +248,7 @@ almanah_main_window_new (void)
 	g_signal_connect (almanah->storage_manager, "definition-removed", G_CALLBACK (mw_definition_removed_cb), main_window);
 
 	/* Select the current day and month */
-	almanah_calendar_month_changed_cb (priv->calendar, NULL);
-	mw_calendar_day_selected_cb (priv->calendar, main_window);
+	mw_jump_to_today_activate_cb (NULL, main_window);
 
 	/* Set up the treeview */
 	g_signal_connect (priv->events_selection, "changed", G_CALLBACK (mw_events_selection_changed_cb), main_window);
@@ -420,26 +420,16 @@ save_current_entry (AlmanahMainWindow *self)
 	/* Mark the day on the calendar if the entry was non-empty (and deleted)
 	 * and update the state of the add definition action. */
 	if (entry_is_empty == TRUE) {
-		gtk_calendar_unmark_day (priv->calendar, g_date_get_day (&date));
+		gtk_calendar_unmark_day (GTK_CALENDAR (priv->calendar), g_date_get_day (&date));
 
 		/* Since the entry is empty, remove all the events from the treeview */
 		gtk_list_store_clear (priv->event_store);
 	} else {
-		gtk_calendar_mark_day (priv->calendar, g_date_get_day (&date));
+		gtk_calendar_mark_day (GTK_CALENDAR (priv->calendar), g_date_get_day (&date));
 	}
 }
 
 static void
-get_selected_date (AlmanahMainWindow *self, GDate *date)
-{
-	guint year, month, day;
-
-	gtk_calendar_get_date (self->priv->calendar, &year, &month, &day);
-	month++;
-	g_date_set_dmy (date, day, month, year);
-}
-
-static void
 add_definition_to_current_entry (AlmanahMainWindow *self)
 {
 	AlmanahMainWindowPrivate *priv = self->priv;
@@ -533,8 +523,7 @@ remove_definition_from_current_entry (AlmanahMainWindow *self)
 void
 almanah_main_window_select_date (AlmanahMainWindow *self, GDate *date)
 {
-	gtk_calendar_select_month (self->priv->calendar, g_date_get_month (date) - 1, g_date_get_year (date));
-	gtk_calendar_select_day (self->priv->calendar, g_date_get_day (date));
+	almanah_calendar_select_date (self->priv->calendar, date);
 }
 
 static void
@@ -980,7 +969,7 @@ mw_events_updated_cb (AlmanahEventManager *event_manager, AlmanahEventFactoryTyp
 	GSList *_events, *events;
 	GDate date;
 
-	get_selected_date (main_window, &date);
+	almanah_calendar_get_date (main_window->priv->calendar, &date);
 	_events = almanah_event_manager_get_events (event_manager, type_id, &date);
 
 	/* Clear all the events generated by this factory out of the list store first */
@@ -1023,7 +1012,7 @@ mw_calendar_day_selected_cb (GtkCalendar *calendar, AlmanahMainWindow *main_wind
 	AlmanahMainWindowPrivate *priv = main_window->priv;
 
 	/* Update the date label */
-	get_selected_date (main_window, &calendar_date);
+	almanah_calendar_get_date (main_window->priv->calendar, &calendar_date);
 
 	/* Translators: This is a strftime()-format string for the date displayed at the top of the main window. */
 	g_date_strftime (calendar_string, sizeof (calendar_string), _("%A, %e %B %Y"), &calendar_date);
@@ -1158,7 +1147,7 @@ mw_definition_removed_cb (AlmanahStorageManager *storage_manager, const gchar *d
 {
 	/* We need to remove any definition tags in the current entry which match @definition_text. It's
 	 * probably easier to just reload the current entry, though. */
-	mw_calendar_day_selected_cb (main_window->priv->calendar, main_window);
+	mw_calendar_day_selected_cb (GTK_CALENDAR (main_window->priv->calendar), main_window);
 }
 
 #ifdef ENABLE_SPELL_CHECKING
diff --git a/src/printing.c b/src/printing.c
index 46fd428..69524cd 100644
--- a/src/printing.c
+++ b/src/printing.c
@@ -25,6 +25,7 @@
 #include "interface.h"
 #include "main.h"
 #include "printing.h"
+#include "widgets/calendar.h"
 
 #define TITLE_MARGIN_BOTTOM 15 /* margin under the title, in pixels */
 #define ENTRY_MARGIN_BOTTOM 10 /* margin under the entry, in pixels */
@@ -36,8 +37,8 @@ typedef struct {
 	GDate *start_date;
 	GDate *end_date;
 	GDate *current_date;
-	GtkCalendar *start_calendar;
-	GtkCalendar *end_calendar;
+	AlmanahCalendar *start_calendar;
+	AlmanahCalendar *end_calendar;
 	GtkSpinButton *line_spacing_spin_button;
 	gdouble line_spacing;
 	guint current_line;
@@ -411,10 +412,8 @@ create_custom_widget_cb (GtkPrintOperation *operation, AlmanahPrintOperation *al
 	GtkBox *vbox, *hbox;
 
 	/* Start and end calendars */
-	start_calendar = gtk_calendar_new ();
-	g_signal_connect (start_calendar, "month-changed", G_CALLBACK (almanah_calendar_month_changed_cb), NULL);
-	end_calendar = gtk_calendar_new ();
-	g_signal_connect (end_calendar, "month-changed", G_CALLBACK (almanah_calendar_month_changed_cb), NULL);
+	start_calendar = almanah_calendar_new ();
+	end_calendar = almanah_calendar_new ();
 
 	start_label = GTK_LABEL (gtk_label_new (_("Start date:")));
 	gtk_misc_set_alignment (GTK_MISC (start_label), 0.0, 0.5);
@@ -430,8 +429,8 @@ create_custom_widget_cb (GtkPrintOperation *operation, AlmanahPrintOperation *al
 	gtk_table_attach (table, GTK_WIDGET (start_label), 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
 	gtk_table_attach (table, GTK_WIDGET (end_label), 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
 
-	almanah_operation->start_calendar = GTK_CALENDAR (start_calendar);
-	almanah_operation->end_calendar = GTK_CALENDAR (end_calendar);
+	almanah_operation->start_calendar = ALMANAH_CALENDAR (start_calendar);
+	almanah_operation->end_calendar = ALMANAH_CALENDAR (end_calendar);
 
 	/* Line spacing */
 	line_spacing_label = GTK_LABEL (gtk_label_new (_("Line spacing:")));
@@ -450,8 +449,8 @@ create_custom_widget_cb (GtkPrintOperation *operation, AlmanahPrintOperation *al
 	gtk_widget_show_all (GTK_WIDGET (vbox));
 
 	/* Make sure they have the dates with entries marked */
-	almanah_calendar_month_changed_cb (GTK_CALENDAR (start_calendar), NULL);
-	almanah_calendar_month_changed_cb (GTK_CALENDAR (end_calendar), NULL);
+	almanah_calendar_select_today (almanah_operation->start_calendar);
+	almanah_calendar_select_today (almanah_operation->end_calendar);
 
 	return GTK_WIDGET (vbox);
 }
@@ -459,16 +458,12 @@ create_custom_widget_cb (GtkPrintOperation *operation, AlmanahPrintOperation *al
 static void
 custom_widget_apply_cb (GtkPrintOperation *operation, GtkWidget *widget, AlmanahPrintOperation *almanah_operation)
 {
-	guint year, month, day;
-
 	/* Start date */
-	gtk_calendar_get_date (almanah_operation->start_calendar, &year, &month, &day);
-	g_date_set_dmy (almanah_operation->start_date, day, month + 1, year);
-	g_date_set_dmy (almanah_operation->current_date, day, month + 1, year);
+	almanah_calendar_get_date (almanah_operation->start_calendar, almanah_operation->start_date);
+	almanah_calendar_get_date (almanah_operation->start_calendar, almanah_operation->current_date);
 
 	/* End date */
-	gtk_calendar_get_date (almanah_operation->end_calendar, &year, &month, &day);
-	g_date_set_dmy (almanah_operation->end_date, day, month + 1, year);
+	almanah_calendar_get_date (almanah_operation->end_calendar, almanah_operation->end_date);
 
 	/* Ensure they're in order */
 	if (g_date_compare (almanah_operation->start_date, almanah_operation->end_date) > 0) {
diff --git a/src/storage-manager.c b/src/storage-manager.c
index c0b4659..8706786 100644
--- a/src/storage-manager.c
+++ b/src/storage-manager.c
@@ -1007,6 +1007,34 @@ almanah_storage_manager_get_month_marked_days (AlmanahStorageManager *self, GDat
 	return days;
 }
 
+/* NOTE: Free results with g_free. Return value is 0-based. */
+gboolean *
+almanah_storage_manager_get_month_important_days (AlmanahStorageManager *self, GDateYear year, GDateMonth month, guint *num_days)
+{
+	AlmanahQueryResults *results;
+	gint i;
+	gboolean *days;
+
+	i = g_date_get_days_in_month (month, year);
+	if (num_days != NULL)
+		*num_days = i;
+	days = g_malloc0 (sizeof (gboolean) * i);
+
+	results = almanah_storage_manager_query (self, "SELECT day FROM entries WHERE year = %u AND month = %u AND is_important = 1", NULL,
+	                                         year,
+	                                         month);
+
+	if (results == NULL)
+		return days;
+
+	for (i = 1; i <= results->rows; i++)
+		days[atoi (results->data[i]) - 1] = TRUE;
+
+	almanah_storage_manager_free_results (results);
+
+	return days;
+}
+
 /**
  * almanah_storage_manager_get_definitions:
  * @self: an #AlmanahStorageManager
diff --git a/src/storage-manager.h b/src/storage-manager.h
index de14656..e572fa3 100644
--- a/src/storage-manager.h
+++ b/src/storage-manager.h
@@ -86,6 +86,7 @@ gint almanah_storage_manager_search_entries (AlmanahStorageManager *self, const
 GSList *almanah_storage_manager_get_entries (AlmanahStorageManager *self) G_GNUC_WARN_UNUSED_RESULT;
 
 gboolean *almanah_storage_manager_get_month_marked_days (AlmanahStorageManager *self, GDateYear year, GDateMonth month, guint *num_days);
+gboolean *almanah_storage_manager_get_month_important_days (AlmanahStorageManager *self, GDateYear year, GDateMonth month, guint *num_days);
 
 GSList *almanah_storage_manager_get_definitions (AlmanahStorageManager *self);
 AlmanahDefinition *almanah_storage_manager_get_definition (AlmanahStorageManager *self, const gchar *definition_text);
diff --git a/src/widgets/calendar.c b/src/widgets/calendar.c
new file mode 100644
index 0000000..44a147d
--- /dev/null
+++ b/src/widgets/calendar.c
@@ -0,0 +1,152 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Almanah
+ * Copyright (C) Philip Withnall 2010 <philip tecnocode co uk>
+ * 
+ * Almanah 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.
+ *
+ * Almanah 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 Almanah.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include "calendar.h"
+#include "storage-manager.h"
+#include "main.h"
+
+static void almanah_calendar_finalize (GObject *object);
+static void almanah_calendar_month_changed (GtkCalendar *calendar);
+static gchar *almanah_calendar_detail_func (GtkCalendar *calendar, guint year, guint month, guint day, gpointer user_data);
+
+struct _AlmanahCalendarPrivate {
+	gboolean *important_days;
+};
+
+G_DEFINE_TYPE (AlmanahCalendar, almanah_calendar, GTK_TYPE_CALENDAR)
+
+static void
+almanah_calendar_class_init (AlmanahCalendarClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+	GtkCalendarClass *calendar_class = GTK_CALENDAR_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (AlmanahCalendarPrivate));
+
+	gobject_class->finalize = almanah_calendar_finalize;
+
+	calendar_class->month_changed = almanah_calendar_month_changed;
+}
+
+static void
+almanah_calendar_init (AlmanahCalendar *self)
+{
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, ALMANAH_TYPE_CALENDAR, AlmanahCalendarPrivate);
+	gtk_calendar_set_detail_func (GTK_CALENDAR (self), almanah_calendar_detail_func, NULL, NULL);
+}
+
+static void
+almanah_calendar_finalize (GObject *object)
+{
+	AlmanahCalendarPrivate *priv = ALMANAH_CALENDAR (object)->priv;
+
+	g_free (priv->important_days);
+
+	/* Chain up to the parent class */
+	G_OBJECT_CLASS (almanah_calendar_parent_class)->finalize (object);
+}
+
+static void
+almanah_calendar_month_changed (GtkCalendar *calendar)
+{
+	AlmanahCalendarPrivate *priv = ALMANAH_CALENDAR (calendar)->priv;
+	guint i, year, month, num_days;
+	gboolean *days;
+
+	/* Mark the days on the calendar which have diary entries */
+	gtk_calendar_get_date (calendar, &year, &month, NULL);
+	month++;
+	days = almanah_storage_manager_get_month_marked_days (almanah->storage_manager, year, month, &num_days);
+
+	gtk_calendar_clear_marks (calendar);
+	for (i = 0; i < num_days; i++) {
+		if (days[i] == TRUE)
+			gtk_calendar_mark_day (calendar, i + 1);
+		else
+			gtk_calendar_unmark_day (calendar, i + 1);
+	}
+
+	g_free (days);
+
+	/* Cache the days which are important, so that the detail function isn't hideously slow */
+	g_free (priv->important_days);
+	priv->important_days = almanah_storage_manager_get_month_important_days (almanah->storage_manager, year, month, &num_days);
+}
+
+static gchar *
+almanah_calendar_detail_func (GtkCalendar *calendar, guint year, guint month, guint day, gpointer user_data)
+{
+	AlmanahCalendarPrivate *priv = ALMANAH_CALENDAR (calendar)->priv;
+	guint calendar_year, calendar_month;
+
+	gtk_calendar_get_date (calendar, &calendar_year, &calendar_month, NULL);
+
+	/* Check we actually have the data available for the requested month */
+	if (priv->important_days == NULL || year != calendar_year || month != calendar_month)
+		return NULL;
+
+	/* Display markup if the day is important; don't otherwise */
+	if (priv->important_days[day - 1] == TRUE) {
+		/* Translators: This is the detail string for important days as displayed in the calendar. */
+		return g_strdup (_("Important!"));
+	}
+	return NULL;
+}
+
+GtkWidget *
+almanah_calendar_new (void)
+{
+	return g_object_new (ALMANAH_TYPE_CALENDAR, NULL);
+}
+
+void
+almanah_calendar_select_date (AlmanahCalendar *self, GDate *date)
+{
+	g_return_if_fail (ALMANAH_IS_CALENDAR (self));
+	g_return_if_fail (date != NULL);
+
+	gtk_calendar_select_month (GTK_CALENDAR (self), g_date_get_month (date) - 1, g_date_get_year (date));
+	gtk_calendar_select_day (GTK_CALENDAR (self), g_date_get_day (date));
+}
+
+void
+almanah_calendar_select_today (AlmanahCalendar *self)
+{
+	GDate current_date;
+
+	g_return_if_fail (ALMANAH_IS_CALENDAR (self));
+
+	g_date_set_time_t (&current_date, time (NULL));
+	almanah_calendar_select_date (self, &current_date);
+}
+
+void
+almanah_calendar_get_date (AlmanahCalendar *self, GDate *date)
+{
+	guint year, month, day;
+
+	g_return_if_fail (ALMANAH_IS_CALENDAR (self));
+	g_return_if_fail (date != NULL);
+
+	gtk_calendar_get_date (GTK_CALENDAR (self), &year, &month, &day);
+	g_date_set_dmy (date, day, month + 1, year);
+}
diff --git a/src/widgets/calendar.h b/src/widgets/calendar.h
new file mode 100644
index 0000000..492f440
--- /dev/null
+++ b/src/widgets/calendar.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Almanah
+ * Copyright (C) Philip Withnall 2010 <philip tecnocode co uk>
+ * 
+ * Almanah 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.
+ *
+ * Almanah 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 Almanah.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ALMANAH_CALENDAR_H
+#define ALMANAH_CALENDAR_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define ALMANAH_TYPE_CALENDAR		(almanah_calendar_get_type ())
+#define ALMANAH_CALENDAR(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), ALMANAH_TYPE_CALENDAR, AlmanahCalendar))
+#define ALMANAH_CALENDAR_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), ALMANAH_TYPE_CALENDAR, AlmanahCalendarClass))
+#define ALMANAH_IS_CALENDAR(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), ALMANAH_TYPE_CALENDAR))
+#define ALMANAH_IS_CALENDAR_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), ALMANAH_TYPE_CALENDAR))
+#define ALMANAH_CALENDAR_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), ALMANAH_TYPE_CALENDAR, AlmanahCalendarClass))
+
+typedef struct _AlmanahCalendarPrivate	AlmanahCalendarPrivate;
+
+typedef struct {
+	GtkCalendar parent;
+	AlmanahCalendarPrivate *priv;
+} AlmanahCalendar;
+
+typedef struct {
+	GtkCalendarClass parent;
+} AlmanahCalendarClass;
+
+GType almanah_calendar_get_type (void) G_GNUC_CONST;
+
+GtkWidget *almanah_calendar_new (void) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+void almanah_calendar_select_date (AlmanahCalendar *self, GDate *date);
+void almanah_calendar_select_today (AlmanahCalendar *self);
+void almanah_calendar_get_date (AlmanahCalendar *self, GDate *date);
+
+G_END_DECLS
+
+#endif /* !ALMANAH_CALENDAR_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]