[almanah] Bug 572032 – Allow manual date entry



commit 11eaffdee9e7c78eecb25a798bb44282696c0655
Author: Philip Withnall <philip tecnocode co uk>
Date:   Sun May 10 18:54:27 2009 +0100

    Bug 572032 â?? Allow manual date entry
---
 data/almanah.ui         |   74 +++++++++++++++++-
 src/Makefile.am         |    2 +
 src/date-entry-dialog.c |  202 +++++++++++++++++++++++++++++++++++++++++++++++
 src/date-entry-dialog.h |   57 +++++++++++++
 src/main-window.c       |   18 ++++
 src/main.c              |    2 +
 src/main.h              |    1 +
 7 files changed, 355 insertions(+), 1 deletions(-)

diff --git a/data/almanah.ui b/data/almanah.ui
index 4f03a3c..2ae546a 100644
--- a/data/almanah.ui
+++ b/data/almanah.ui
@@ -78,9 +78,17 @@
 					</object>
 				</child>
 				<child>
+					<object class="GtkAction" id="almanah_ui_select_date">
+						<property name="stock-id">gtk-index</property>
+						<property name="label" translatable="yes">Select Dateâ?¦</property>
+						<property name="name">edit-select-date</property>
+						<signal name="activate" handler="mw_select_date_activate_cb"/>
+					</object>
+				</child>
+				<child>
 					<object class="GtkAction" id="almanah_ui_search">
 						<property name="stock-id">gtk-find</property>
-						<property name="label" translatable="yes">_Search</property>
+						<property name="label" translatable="yes">_Searchâ?¦</property>
 						<property name="name">edit-search</property>
 						<signal name="activate" handler="mw_search_activate_cb"/>
 					</object>
@@ -207,6 +215,7 @@
 					<menuitem action="almanah_ui_paste"/>
 					<menuitem action="almanah_ui_delete"/>
 					<separator/>
+					<menuitem action="almanah_ui_select_date"/>
 					<menuitem action="almanah_ui_search"/>
 					<separator/>
 					<menuitem action="almanah_ui_preferences"/>
@@ -831,4 +840,67 @@
 			</object>
 		</child>
 	</object>
+
+	<object class="AlmanahDateEntryDialog" id="almanah_date_entry_dialog">
+		<child internal-child="vbox">
+			<object class="GtkVBox" id="vbox1">
+				<child>
+					<object class="GtkVBox" id="almanah_ded_vbox">
+						<property name="spacing">5</property>
+						<child>
+							<object class="GtkEntry" id="almanah_ded_date_entry">
+								<property name="activates-default">True</property>
+								<signal name="notify::text" handler="ded_date_entry_notify_text_cb"/>
+								<accessibility>
+									<relation target="almanah_ded_description_label" type="described-by"/>
+								</accessibility>
+							</object>
+							<packing>
+								<property name="expand">False</property>
+							</packing>
+						</child>
+						<child>
+							<object class="GtkLabel" id="almanah_ded_description_label">
+								<property name="xalign">0</property>
+								<!-- Translators: Use two common date formats from your locale which will be parsed correctly by GLib's g_date_set_parse() function --> 
+								<property name="label" translatable="yes">e.g. "14/03/2009" or "14th March 2009".</property>
+								<accessibility>
+									<relation target="almanah_ded_date_entry" type="description-for"/>
+								</accessibility>
+								<attributes>
+									<attribute name="scale" value="0.8"/>
+								</attributes>
+							</object>
+							<packing>
+								<property name="expand">False</property>
+							</packing>
+						</child>
+					</object>
+				</child>
+				<child internal-child="action_area">
+					<object class="GtkHButtonBox" id="almanah_ded_hbuttonbox">
+						<child>
+							<object class="GtkButton" id="almanah_ded_cancel_button">
+								<property name="use-stock">True</property>
+								<property name="label">gtk-cancel</property>
+							</object>
+						</child>
+						<child>
+							<object class="GtkButton" id="almanah_ded_ok_button">
+								<property name="use-stock">True</property>
+								<property name="label">gtk-ok</property>
+								<property name="can-default">True</property>
+								<property name="has-default">True</property>
+								<property name="sensitive">False</property>
+							</object>
+						</child>
+					</object>
+				</child>
+			</object>
+		</child>
+		<action-widgets>
+			<action-widget response="-6">almanah_ded_cancel_button</action-widget><!-- GTK_RESPONSE_CANCEL -->
+			<action-widget response="-5">almanah_ded_ok_button</action-widget><!-- GTK_RESPONSE_OK -->
+		</action-widgets>
+	</object>
 </interface>
diff --git a/src/Makefile.am b/src/Makefile.am
index 92dac68..eb99cb0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -53,6 +53,8 @@ almanah_SOURCES = \
 	event-manager.h		\
 	definition.c		\
 	definition.h		\
+	date-entry-dialog.c	\
+	date-entry-dialog.h	\
 	definitions/contact.c		\
 	definitions/contact.h		\
 	definitions/file.c		\
diff --git a/src/date-entry-dialog.c b/src/date-entry-dialog.c
new file mode 100644
index 0000000..4e02130
--- /dev/null
+++ b/src/date-entry-dialog.c
@@ -0,0 +1,202 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Almanah
+ * Copyright (C) Philip Withnall 2009 <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 <config.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "date-entry-dialog.h"
+#include "main.h"
+#include "interface.h"
+
+static void almanah_date_entry_dialog_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void almanah_date_entry_dialog_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
+
+/* GtkBuilder callbacks */
+void ded_date_entry_notify_text_cb (GObject *gobject, GParamSpec *pspec, AlmanahDateEntryDialog *self);
+
+struct _AlmanahDateEntryDialogPrivate {
+	GDate date;
+	GtkWidget *ok_button;
+	GtkEntry *date_entry;
+};
+
+enum {
+	PROP_DATE = 1
+};
+
+G_DEFINE_TYPE (AlmanahDateEntryDialog, almanah_date_entry_dialog, GTK_TYPE_DIALOG)
+#define ALMANAH_DATE_ENTRY_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ALMANAH_TYPE_DATE_ENTRY_DIALOG, AlmanahDateEntryDialogPrivate))
+
+static void
+almanah_date_entry_dialog_class_init (AlmanahDateEntryDialogClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (AlmanahDateEntryDialogPrivate));
+
+	gobject_class->set_property = almanah_date_entry_dialog_set_property;
+	gobject_class->get_property = almanah_date_entry_dialog_get_property;
+
+	g_object_class_install_property (gobject_class, PROP_DATE,
+				g_param_spec_boxed ("date",
+					"Date", "The current date selected by the dialog.",
+					G_TYPE_DATE,
+					G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+}
+
+static void
+almanah_date_entry_dialog_init (AlmanahDateEntryDialog *self)
+{
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, ALMANAH_TYPE_DATE_ENTRY_DIALOG, AlmanahDateEntryDialogPrivate);
+
+	g_date_clear (&(self->priv->date), 1);
+	g_signal_connect (self, "response", G_CALLBACK (gtk_widget_hide_all), self);
+	gtk_dialog_set_has_separator (GTK_DIALOG (self), FALSE);
+	gtk_window_set_resizable (GTK_WINDOW (self), FALSE);
+	gtk_window_set_title (GTK_WINDOW (self), _("Select Date"));
+	gtk_window_set_transient_for (GTK_WINDOW (self), GTK_WINDOW (almanah->main_window));
+}
+
+static void
+almanah_date_entry_dialog_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+	AlmanahDateEntryDialogPrivate *priv = ALMANAH_DATE_ENTRY_DIALOG (object)->priv;
+
+	switch (property_id) {
+		case PROP_DATE:
+			g_value_set_boxed (value, &(priv->date));
+			break;
+		default:
+			/* We don't have any other property... */
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+			break;
+	}
+}
+
+static void
+almanah_date_entry_dialog_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+	AlmanahDateEntryDialog *self = ALMANAH_DATE_ENTRY_DIALOG (object);
+
+	switch (property_id) {
+		case PROP_DATE:
+			almanah_date_entry_dialog_set_date (self, g_value_get_boxed (value));
+			break;
+		default:
+			/* We don't have any other property... */
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+			break;
+	}
+}
+
+AlmanahDateEntryDialog *
+almanah_date_entry_dialog_new (void)
+{
+	GtkBuilder *builder;
+	AlmanahDateEntryDialog *date_entry_dialog;
+	AlmanahDateEntryDialogPrivate *priv;
+	GError *error = NULL;
+	const gchar *interface_filename = almanah_get_interface_filename ();
+	const gchar *object_names[] = {
+		"almanah_date_entry_dialog",
+		NULL
+	};
+
+	builder = gtk_builder_new ();
+
+	if (gtk_builder_add_objects_from_file (builder, interface_filename, (gchar**) object_names, &error) == FALSE) {
+		/* Show an error */
+		GtkWidget *dialog = gtk_message_dialog_new (NULL,
+				GTK_DIALOG_MODAL,
+				GTK_MESSAGE_ERROR,
+				GTK_BUTTONS_OK,
+				_("UI file \"%s\" could not be loaded"), interface_filename);
+		gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message);
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+
+		g_error_free (error);
+		g_object_unref (builder);
+
+		return NULL;
+	}
+
+	gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE);
+	date_entry_dialog = ALMANAH_DATE_ENTRY_DIALOG (gtk_builder_get_object (builder, "almanah_date_entry_dialog"));
+	gtk_builder_connect_signals (builder, date_entry_dialog);
+
+	if (date_entry_dialog == NULL) {
+		g_object_unref (builder);
+		return NULL;
+	}
+
+	priv = date_entry_dialog->priv;
+
+	/* Grab widgets */
+	priv->ok_button = GTK_WIDGET (gtk_builder_get_object (builder, "almanah_ded_ok_button"));
+	priv->date_entry = GTK_ENTRY (gtk_builder_get_object (builder, "almanah_ded_date_entry"));
+
+	g_object_unref (builder);
+
+	return date_entry_dialog;
+}
+
+gboolean
+almanah_date_entry_dialog_run (AlmanahDateEntryDialog *self)
+{
+	/* Reset the date, entry and consequently the OK button */
+	gtk_entry_set_text (self->priv->date_entry, "");
+	g_date_clear (&(self->priv->date), 1);
+
+	return (gtk_dialog_run (GTK_DIALOG (self)) == GTK_RESPONSE_OK) ? TRUE : FALSE;
+}
+
+void
+ded_date_entry_notify_text_cb (GObject *gobject, GParamSpec *param_spec, AlmanahDateEntryDialog *self)
+{
+	AlmanahDateEntryDialogPrivate *priv = self->priv;
+	GDate new_date;
+
+	/* Enable/Disable the OK button based on whether the current date is valid */
+	g_date_set_parse (&new_date, gtk_entry_get_text (priv->date_entry));
+
+	if (g_date_valid (&new_date) == TRUE) {
+		/* The date was parsed successfully; update priv->date and enable the OK button */
+		priv->date = new_date;
+		gtk_widget_set_sensitive (priv->ok_button, TRUE);
+	} else {
+		/* Failure due to the date entered being invalid; disable the OK button */
+		gtk_widget_set_sensitive (priv->ok_button, FALSE);
+	}
+}
+
+void
+almanah_date_entry_dialog_get_date (AlmanahDateEntryDialog *self, GDate *date)
+{
+	*date = self->priv->date;
+}
+
+void
+almanah_date_entry_dialog_set_date (AlmanahDateEntryDialog *self, GDate *date)
+{
+	self->priv->date = *date;
+	g_object_notify (G_OBJECT (self), "date");
+}
diff --git a/src/date-entry-dialog.h b/src/date-entry-dialog.h
new file mode 100644
index 0000000..918feb8
--- /dev/null
+++ b/src/date-entry-dialog.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Almanah
+ * Copyright (C) Philip Withnall 2009 <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_DATE_ENTRY_DIALOG_H
+#define ALMANAH_DATE_ENTRY_DIALOG_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define ALMANAH_TYPE_DATE_ENTRY_DIALOG		(almanah_date_entry_dialog_get_type ())
+#define ALMANAH_DATE_ENTRY_DIALOG(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), ALMANAH_TYPE_DATE_ENTRY_DIALOG, AlmanahDateEntryDialog))
+#define ALMANAH_DATE_ENTRY_DIALOG_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), ALMANAH_TYPE_DATE_ENTRY_DIALOG, AlmanahDateEntryDialogClass))
+#define ALMANAH_IS_DATE_ENTRY_DIALOG(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), ALMANAH_TYPE_DATE_ENTRY_DIALOG))
+#define ALMANAH_IS_DATE_ENTRY_DIALOG_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), ALMANAH_TYPE_DATE_ENTRY_DIALOG))
+#define ALMANAH_DATE_ENTRY_DIALOG_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), ALMANAH_TYPE_DATE_ENTRY_DIALOG, AlmanahDateEntryDialogClass))
+
+typedef struct _AlmanahDateEntryDialogPrivate	AlmanahDateEntryDialogPrivate;
+
+typedef struct {
+	GtkDialog parent;
+	AlmanahDateEntryDialogPrivate *priv;
+} AlmanahDateEntryDialog;
+
+typedef struct {
+	GtkDialogClass parent;
+} AlmanahDateEntryDialogClass;
+
+GType almanah_date_entry_dialog_get_type (void);
+
+AlmanahDateEntryDialog *almanah_date_entry_dialog_new (void);
+gboolean almanah_date_entry_dialog_run (AlmanahDateEntryDialog *self);
+
+void almanah_date_entry_dialog_get_date (AlmanahDateEntryDialog *self, GDate *date);
+void almanah_date_entry_dialog_set_date (AlmanahDateEntryDialog *self, GDate *date);
+
+G_END_DECLS
+
+#endif /* !ALMANAH_DATE_ENTRY_DIALOG_H */
diff --git a/src/main-window.c b/src/main-window.c
index 9bbfcc4..09bd645 100644
--- a/src/main-window.c
+++ b/src/main-window.c
@@ -33,6 +33,7 @@
 #include "add-definition-dialog.h"
 #include "preferences-dialog.h"
 #include "search-dialog.h"
+#include "date-entry-dialog.h"
 #include "printing.h"
 #include "entry.h"
 #include "storage-manager.h"
@@ -69,6 +70,7 @@ void mw_paste_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
 void mw_delete_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
 void mw_insert_time_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
 void mw_important_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
+void mw_select_date_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
 void mw_search_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
 void mw_preferences_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
 void mw_about_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
@@ -768,6 +770,22 @@ mw_important_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
 }
 
 void
+mw_select_date_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
+{
+	if (almanah->date_entry_dialog == NULL)
+		almanah->date_entry_dialog = GTK_WIDGET (almanah_date_entry_dialog_new ());
+
+	gtk_widget_show_all (almanah->date_entry_dialog);
+	if (almanah_date_entry_dialog_run (ALMANAH_DATE_ENTRY_DIALOG (almanah->date_entry_dialog)) == TRUE) {
+		GDate new_date;
+
+		/* Switch to the specified date */
+		almanah_date_entry_dialog_get_date (ALMANAH_DATE_ENTRY_DIALOG (almanah->date_entry_dialog), &new_date);
+		almanah_main_window_select_date (main_window, &new_date);
+	}
+}
+
+void
 mw_search_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
 {
 	if (almanah->search_dialog == NULL)
diff --git a/src/main.c b/src/main.c
index aeefdd0..ac1db72 100644
--- a/src/main.c
+++ b/src/main.c
@@ -71,6 +71,8 @@ almanah_quit (void)
 		gtk_widget_destroy (almanah->add_definition_dialog);
 	if (almanah->search_dialog != NULL)
 		gtk_widget_destroy (almanah->search_dialog);
+	if (almanah->date_entry_dialog != NULL)
+		gtk_widget_destroy (almanah->date_entry_dialog);
 #ifdef ENABLE_ENCRYPTION
 	if (almanah->preferences_dialog != NULL)
 		gtk_widget_destroy (almanah->preferences_dialog);
diff --git a/src/main.h b/src/main.h
index 77d7b73..08f9d50 100644
--- a/src/main.h
+++ b/src/main.h
@@ -44,6 +44,7 @@ typedef struct {
 	GtkWidget *main_window;
 	GtkWidget *add_definition_dialog;
 	GtkWidget *search_dialog;
+	GtkWidget *date_entry_dialog;
 	GtkWidget *definition_manager_window;
 #ifdef ENABLE_ENCRYPTION
 	GtkWidget *preferences_dialog;



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