[libgda] UI: improved date and time entry widgets
- From: Vivien Malerba <vivien src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [libgda] UI: improved date and time entry widgets
- Date: Tue, 29 Sep 2009 19:28:08 +0000 (UTC)
commit 44824f5d50b3628ef1e47c54ba6c4c94a0dc278a
Author: Vivien Malerba <malerba gnome-db org>
Date: Tue Sep 29 21:26:45 2009 +0200
UI: improved date and time entry widgets
if not date is set, then sets the current date,
using '+' or '-' now adds or removes a day to the current
date. For the time entry, pressing SPACE sets the current
time.
libgda-ui/data-entries/gdaui-entry-common-time.c | 125 +++++++++++++++++++++-
libgda-ui/data-entries/gdaui-entry.c | 1 +
libgda-ui/data-entries/gdaui-formatted-entry.c | 36 ++++++-
libgda-ui/data-entries/gdaui-formatted-entry.h | 6 +
4 files changed, 166 insertions(+), 2 deletions(-)
---
diff --git a/libgda-ui/data-entries/gdaui-entry-common-time.c b/libgda-ui/data-entries/gdaui-entry-common-time.c
index 1cabe04..35cd463 100644
--- a/libgda-ui/data-entries/gdaui-entry-common-time.c
+++ b/libgda-ui/data-entries/gdaui-entry-common-time.c
@@ -547,7 +547,6 @@ grab_focus (GdauiEntryWrapper *mgwrap)
/*
* callbacks for the date
*/
-
static void internal_set_time (GtkWidget *widget, GdauiEntryCommonTime *mgtim);
static gint date_delete_popup (GtkWidget *widget, GdauiEntryCommonTime *mgtim);
static gint date_key_press_popup (GtkWidget *widget, GdkEventKey *event, GdauiEntryCommonTime *mgtim);
@@ -556,6 +555,8 @@ static void date_day_selected (GtkCalendar *calendar, GdauiEntryCommonTime *mgti
static void date_day_selected_double_click (GtkCalendar *calendar, GdauiEntryCommonTime *mgtim);
static void date_calendar_choose_cb (GtkWidget *button, GdauiEntryCommonTime *mgtim);
+static void entry_date_insert_func (GdauiFormattedEntry *fentry, gunichar insert_char, gint virt_pos, gpointer data);
+
static GtkWidget *
create_entry_date (GdauiEntryCommonTime *mgtim)
{
@@ -578,6 +579,9 @@ create_entry_date (GdauiEntryCommonTime *mgtim)
wid = gdaui_formatted_entry_new (str, mask);
g_free (str);
g_free (mask);
+
+ gdaui_formatted_entry_set_insert_func (GDAUI_FORMATTED_ENTRY (wid), entry_date_insert_func,
+ mgtim);
}
else
wid = gdaui_entry_new (NULL, NULL);
@@ -628,6 +632,85 @@ create_entry_date (GdauiEntryCommonTime *mgtim)
}
static void
+entry_date_insert_func (GdauiFormattedEntry *fentry, gunichar insert_char, gint virt_pos, gpointer data)
+{
+ GValue *value;
+ GType type;
+
+ type = gdaui_data_entry_get_value_type (GDAUI_DATA_ENTRY (data));
+ value = real_get_value (GDAUI_ENTRY_WRAPPER (data));
+ if (!value)
+ return;
+
+ if (G_VALUE_TYPE (value) == GDA_TYPE_NULL) {
+ if (type == G_TYPE_DATE) {
+ /* set current date, whatever @insert_char is */
+ GDate *ndate;
+ ndate = g_new0 (GDate, 1);
+ g_date_set_time_t (ndate, time (NULL));
+
+ gda_value_reset_with_type (value, type);
+ g_value_take_boxed (value, ndate);
+ real_set_value (GDAUI_ENTRY_WRAPPER (data), value);
+ }
+ else if (type == GDA_TYPE_TIMESTAMP) {
+ GValue *tsvalue;
+ tsvalue = gda_value_new_timestamp_from_timet (time (NULL));
+ real_set_value (GDAUI_ENTRY_WRAPPER (data), tsvalue);
+ gda_value_free (tsvalue);
+ }
+ }
+ else {
+ GDate *date = NULL;
+ if (type == G_TYPE_DATE) {
+ date = (GDate*) g_value_get_boxed (value);
+ }
+ else if (type == GDA_TYPE_TIMESTAMP) {
+ const GdaTimestamp *ts;
+ ts = gda_value_get_timestamp (value);
+ date = g_date_new_dmy (ts->day, ts->month, ts->year);
+ }
+
+ if (date) {
+ GDate *ndate;
+ gboolean changed = FALSE;
+
+ ndate = g_new (GDate, 1);
+ *ndate = *date;
+ if ((insert_char == g_utf8_get_char ("+")) ||
+ (insert_char == g_utf8_get_char ("="))) {
+ g_date_add_days (ndate, 1);
+ changed = TRUE;
+ }
+ else if ((insert_char == g_utf8_get_char ("-")) ||
+ (insert_char == g_utf8_get_char ("6"))) {
+ g_date_subtract_days (ndate, 1);
+ changed = TRUE;
+ }
+
+ if (changed) {
+ if (type == G_TYPE_DATE) {
+ g_value_take_boxed (value, ndate);
+ }
+ else if (type == GDA_TYPE_TIMESTAMP) {
+ GdaTimestamp *ts;
+ ts = (GdaTimestamp*) gda_timestamp_copy ((gpointer) gda_value_get_timestamp (value));
+ ts->day = g_date_get_day (ndate);
+ ts->month = g_date_get_month (ndate);
+ ts->year = g_date_get_year (ndate);
+ g_date_free (date);
+ g_date_free (ndate);
+ gda_value_set_timestamp (value, ts);
+ gda_timestamp_free (ts);
+ }
+ real_set_value (GDAUI_ENTRY_WRAPPER (data), value);
+ }
+ }
+ }
+ gda_value_free (value);
+}
+
+static void
internal_set_time (GtkWidget *widget, GdauiEntryCommonTime *mgtim)
{
/* the aim is that when the mode is TIMESTAMP, when the user sets a date,
@@ -902,6 +985,8 @@ position_popup (GdauiEntryCommonTime *mgtim)
/*
* callbacks for the time
*/
+static void entry_time_insert_func (GdauiFormattedEntry *fentry, gunichar insert_char, gint virt_pos, gpointer data);
+
static GtkWidget *
create_entry_time (GdauiEntryCommonTime *mgtim)
{
@@ -921,6 +1006,9 @@ create_entry_time (GdauiEntryCommonTime *mgtim)
wid = gdaui_formatted_entry_new (str, mask);
g_free (str);
g_free (mask);
+
+ gdaui_formatted_entry_set_insert_func (GDAUI_FORMATTED_ENTRY (wid), entry_time_insert_func,
+ mgtim);
}
else
wid = gdaui_entry_new (NULL, NULL);
@@ -932,6 +1020,41 @@ create_entry_time (GdauiEntryCommonTime *mgtim)
return wid;
}
+static void
+entry_time_insert_func (GdauiFormattedEntry *fentry, gunichar insert_char, gint virt_pos, gpointer data)
+{
+ GValue *value;
+ GType type;
+
+ type = gdaui_data_entry_get_value_type (GDAUI_DATA_ENTRY (data));
+ value = real_get_value (GDAUI_ENTRY_WRAPPER (data));
+ if (!value)
+ return;
+
+ if ((type == GDA_TYPE_TIME) &&
+ (insert_char == g_utf8_get_char (" "))) {
+ /* set current time */
+ gda_value_reset_with_type (value, type);
+ struct tm *ltm;
+ time_t val;
+
+ val = time (NULL);
+ ltm = localtime ((const time_t *) &val);
+ if (ltm) {
+ GdaTime tim;
+ memset (&tim, 0, sizeof (GdaTime));
+ tim.hour = ltm->tm_hour;
+ tim.minute = ltm->tm_min;
+ tim.second = ltm->tm_sec;
+ tim.fraction = 0;
+ tim.timezone = GDA_TIMEZONE_INVALID;
+ gda_value_set_time (value, (const GdaTime *) &tim);
+ real_set_value (GDAUI_ENTRY_WRAPPER (data), value);
+ }
+ }
+
+ gda_value_free (value);
+}
/*
* callbacks for the timestamp
diff --git a/libgda-ui/data-entries/gdaui-entry.c b/libgda-ui/data-entries/gdaui-entry.c
index a333cd3..5eb87fd 100644
--- a/libgda-ui/data-entries/gdaui-entry.c
+++ b/libgda-ui/data-entries/gdaui-entry.c
@@ -435,6 +435,7 @@ gdaui_entry_set_text (GdauiEntry *entry, const gchar *text)
signal_handlers_unblock (entry);
ENTER_INTERNAL_CHANGES(entry);
gtk_entry_set_text (GTK_ENTRY (entry), text); /* emits the "insert-text" signal which is treated */
+ entry->priv->isnull = FALSE; /* in case it has not been set */
LEAVE_INTERNAL_CHANGES(entry);
g_signal_emit_by_name (entry, "changed");
}
diff --git a/libgda-ui/data-entries/gdaui-formatted-entry.c b/libgda-ui/data-entries/gdaui-formatted-entry.c
index c48c7e6..701a0f6 100644
--- a/libgda-ui/data-entries/gdaui-formatted-entry.c
+++ b/libgda-ui/data-entries/gdaui-formatted-entry.c
@@ -30,6 +30,9 @@ struct _GdauiFormattedEntryPrivate {
gint format_clen; /* in characters, not gchar */
gchar *mask; /* ASCII! */
gint mask_len; /* in gchar */
+
+ GdauiFormattedEntryInsertFunc insert_func;
+ gpointer insert_func_data;
};
static void gdaui_formatted_entry_class_init (GdauiFormattedEntryClass *klass);
@@ -111,6 +114,8 @@ gdaui_formatted_entry_init (GdauiFormattedEntry *entry)
entry->priv = g_new0 (GdauiFormattedEntryPrivate, 1);
entry->priv->format = NULL;
entry->priv->mask = NULL;
+ entry->priv->insert_func = NULL;
+ entry->priv->insert_func_data = NULL;
}
static void
@@ -319,6 +324,8 @@ gdaui_formatted_entry_assume_insert (GdauiEntry *entry, const gchar *text, gint
return;
_gdaui_entry_block_changes (entry);
+ gboolean inserted = FALSE;
+ gunichar wc;
for (ptr = text, i = 0; ptr && *ptr && *fptr; ptr = g_utf8_next_char (ptr)) {
while ((pos < fentry->priv->format_clen) &&
!is_writable (fentry, pos, fptr)) {
@@ -328,7 +335,6 @@ gdaui_formatted_entry_assume_insert (GdauiEntry *entry, const gchar *text, gint
pos++;
}
- gunichar wc;
wc = g_utf8_get_char (ptr);
if ((pos < fentry->priv->format_clen) &&
is_allowed (fentry, fptr, wc, &wc)){
@@ -340,12 +346,21 @@ gdaui_formatted_entry_assume_insert (GdauiEntry *entry, const gchar *text, gint
usize = g_unichar_to_utf8 (wc, buf);
gtk_editable_delete_text ((GtkEditable*) entry, rpos, rpos + 1);
gtk_editable_insert_text ((GtkEditable*) entry, buf, usize, &rpos);
+ inserted = TRUE;
pos++;
fptr = g_utf8_next_char (fptr);
}
}
_gdaui_entry_unblock_changes (entry);
*virt_pos = pos;
+
+ if (!inserted && fentry->priv->insert_func) {
+ ptr = g_utf8_next_char (text);
+ if (!*ptr) {
+ wc = g_utf8_get_char (text);
+ fentry->priv->insert_func (fentry, wc, *virt_pos, fentry->priv->insert_func_data);
+ }
+ }
}
static void
@@ -488,3 +503,22 @@ gdaui_formatted_entry_get_text (GdauiFormattedEntry *entry)
return text;
}
+
+/**
+ * gdaui_formatted_entry_set_insert_func
+ * @entry: a #GdauiFormattedEntry widget
+ * @insert_func: a #GdauiFormattedEntryInsertFunc, or %NULL
+ * @data: a pointer which will be passed to @insert_func
+ *
+ * Specifies that @entry should call @insert_func when the user wants to insert a char
+ * which is anot allowed, to perform other actions
+ */
+void
+gdaui_formatted_entry_set_insert_func (GdauiFormattedEntry *entry, GdauiFormattedEntryInsertFunc insert_func,
+ gpointer data)
+{
+ g_return_val_if_fail (GDAUI_IS_FORMATTED_ENTRY (entry), NULL);
+
+ entry->priv->insert_func = insert_func;
+ entry->priv->insert_func_data = data;
+}
diff --git a/libgda-ui/data-entries/gdaui-formatted-entry.h b/libgda-ui/data-entries/gdaui-formatted-entry.h
index 9c869d1..3fd7183 100644
--- a/libgda-ui/data-entries/gdaui-formatted-entry.h
+++ b/libgda-ui/data-entries/gdaui-formatted-entry.h
@@ -52,6 +52,12 @@ GType gdaui_formatted_entry_get_type (void) G_GNUC_CON
GtkWidget *gdaui_formatted_entry_new (const gchar *format, const gchar *mask);
gchar *gdaui_formatted_entry_get_text (GdauiFormattedEntry *entry);
+typedef void (*GdauiFormattedEntryInsertFunc) (GdauiFormattedEntry *entry, gunichar insert_char,
+ gint virt_pos, gpointer data);
+void gdaui_formatted_entry_set_insert_func (GdauiFormattedEntry *entry,
+ GdauiFormattedEntryInsertFunc insert_func,
+ gpointer data);
+
G_END_DECLS
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]