/* HomeBank -- Free, easy, personal accounting for everyone.
* Copyright (C) 1995-2014 Maxime DOYEN
*
* This file is part of HomeBank.
*
* HomeBank 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 2 of the License, or
* (at your option) any later version.
*
* HomeBank 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 this program. If not, see .
*/
#include
#include
#include
#include
#include
#include "gtk-dateentry.h"
#define MYDEBUG 0
#if MYDEBUG
#define DB(x) (x);
#else
#define DB(x);
#endif
enum {
CHANGED,
LAST_SIGNAL
};
enum {
PROPERTY_DATE = 5,
};
static void gtk_dateentry_class_init (GtkDateEntryClass *klass);
static void gtk_dateentry_init (GtkDateEntry *dateentry);
static void gtk_dateentry_destroy (GtkObject *dateentry);
static void gtk_dateentry_popup_display (GtkDateEntry *dateentry);
static gint gtk_dateentry_arrow_press (GtkWidget * widget,
GtkDateEntry * dateentry);
static gint gtk_dateentry_button_press (GtkWidget *widget,
GdkEvent *event,
gpointer data);
static void gtk_dateentry_entry_parse(GtkWidget * calendar, gpointer user_data);
static gint gtk_dateentry_entry_key (GtkWidget *widget, GdkEventKey *event, gpointer user_data);
static void gtk_dateentry_calendar_getfrom(GtkWidget * calendar, GtkDateEntry * dateentry);
static gint gtk_dateentry_calendar_select(GtkWidget * calendar, gpointer user_data);
static void gtk_dateentry_calendar_year(GtkWidget * calendar, GtkDateEntry * dateentry);
static void gtk_dateentry_hide_popdown_window(GtkDateEntry *dateentry);
static gint gtk_dateentry_arrow_press (GtkWidget * widget, GtkDateEntry * dateentry);
static gint key_press_popup (GtkWidget *widget, GdkEventKey *event, gpointer user_data);
static gint gtk_dateentry_button_press (GtkWidget * widget, GdkEvent * event, gpointer data);
static void gtk_dateentry_entry_set_text(GtkDateEntry * dateentry);
/*
static void
gtk_dateentry_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void
gtk_dateentry_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
*/
static GtkHBoxClass *parent_class = NULL;
static guint dateentry_signals[LAST_SIGNAL] = {0,};
// todo:finish this
// this is to be able to seizure d or d/m or m/d in the gtkdateentry
/* order of these in the current locale */
static GDateDMY dmy_order[3] =
{
G_DATE_DAY, G_DATE_MONTH, G_DATE_YEAR
};
struct _GDateParseTokens {
gint num_ints;
gint n[3];
guint month;
};
typedef struct _GDateParseTokens GDateParseTokens;
#define NUM_LEN 10
static void
g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
{
gchar num[4][NUM_LEN+1];
gint i;
const guchar *s;
DB( g_print("\n[dateentry] fill parse token\n") );
/* We count 4, but store 3; so we can give an error
* if there are 4.
*/
num[0][0] = num[1][0] = num[2][0] = num[3][0] = '\0';
s = (const guchar *) str;
pt->num_ints = 0;
while (*s && pt->num_ints < 4)
{
i = 0;
while (*s && g_ascii_isdigit (*s) && i < NUM_LEN)
{
num[pt->num_ints][i] = *s;
++s;
++i;
}
if (i > 0)
{
num[pt->num_ints][i] = '\0';
++(pt->num_ints);
}
if (*s == '\0') break;
++s;
}
pt->n[0] = pt->num_ints > 0 ? atoi (num[0]) : 0;
pt->n[1] = pt->num_ints > 1 ? atoi (num[1]) : 0;
pt->n[2] = pt->num_ints > 2 ? atoi (num[2]) : 0;
}
static void g_date_determine_dmy(void)
{
GDate d;
gchar buf[128];
GDateParseTokens testpt;
gint i;
DB( g_print("\n[dateentry] determine dmy\n") );
g_date_clear (&d, 1); /* clear for scratch use */
/* had to pick a random day - don't change this, some strftimes
* are broken on some days, and this one is good so far. */
g_date_set_dmy (&d, 4, 7, 1976);
g_date_strftime (buf, 127, "%x", &d);
g_date_fill_parse_tokens (buf, &testpt);
i = 0;
while (i < testpt.num_ints)
{
switch (testpt.n[i])
{
case 7:
dmy_order[i] = G_DATE_MONTH;
break;
case 4:
dmy_order[i] = G_DATE_DAY;
break;
//case 76:
//using_twodigit_years = TRUE; /* FALL THRU */
case 1976:
dmy_order[2] = G_DATE_YEAR;
break;
}
++i;
}
DB( g_print(" dmy legend: 0=day, 1=month, 2=year\n") );
DB( g_print(" dmy is: %d %d %d\n", dmy_order[0], dmy_order[1], dmy_order[2]) );
}
//end
GType
gtk_dateentry_get_type ()
{
static GType dateentry_type = 0;
//DB( g_print("\n[dateentry] get_type\n") );
if (!dateentry_type)
{
static const GTypeInfo dateentry_info =
{
sizeof (GtkDateEntryClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) gtk_dateentry_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GtkDateEntry),
0, /* n_preallocs */
(GInstanceInitFunc) gtk_dateentry_init,
NULL
};
//dateentry_type = gtk_type_unique (gtk_hbox_get_type (), &dateentry_info);
dateentry_type = g_type_register_static (GTK_TYPE_HBOX, "GtkDateEntry",
&dateentry_info, 0);
}
return dateentry_type;
}
static void
gtk_dateentry_class_init (GtkDateEntryClass * klass)
{
//GObjectClass *gobject_class;
GtkObjectClass *object_class;
//GtkWidgetClass *widget_class;
//gobject_class = (GObjectClass*) klass;
object_class = (GtkObjectClass*) klass;
//widget_class = (GtkWidgetClass*) klass;
parent_class = g_type_class_peek_parent (klass);
DB( g_print("\n[dateentry] class_init\n") );
object_class->destroy = gtk_dateentry_destroy;
dateentry_signals[CHANGED] =
g_signal_new ("changed",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkDateEntryClass, changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
g_date_determine_dmy();
/*
gobject_class->set_property = gtk_dateentry_set_property;
gobject_class->get_property = gtk_dateentry_get_property;
g_object_class_install_property (gobject_class,
PROPERTY_DATE,
g_param_spec_uint( "date",
"Date",
"The date currently selected",
0, G_MAXUINT,
0,
(G_PARAM_READABLE | G_PARAM_WRITABLE)
)
);
*/
}
static gboolean gtk_dateentry_focus(GtkWidget *widget,
GdkEventFocus *event,
gpointer user_data)
{
GtkDateEntry *dateentry = user_data;
DB( g_print("\n[dateentry] focus-out-event %d\n", gtk_widget_is_focus(GTK_WIDGET(dateentry))) );
gtk_dateentry_entry_parse(GTK_WIDGET(dateentry), dateentry);
return FALSE;
}
static void
gtk_dateentry_init (GtkDateEntry *dateentry)
{
GtkWidget *widget;
GtkWidget *arrow;
DB( g_print("\n[dateentry] init\n") );
/* initialize datas */
dateentry->date = g_date_new();
g_date_set_time_t(dateentry->date, time(NULL));
g_date_set_dmy(&dateentry->mindate, 1, 1, 1900);
g_date_set_dmy(&dateentry->maxdate, 31, 12, 2200);
widget=GTK_WIDGET(dateentry);
gtk_box_set_homogeneous(GTK_BOX(widget), FALSE);
dateentry->entry = gtk_entry_new ();
gtk_widget_set_size_request(dateentry->entry, 90, -1);
gtk_box_pack_start (GTK_BOX (dateentry), dateentry->entry, TRUE, TRUE, 0);
dateentry->arrow = gtk_toggle_button_new ();
arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_IN);
gtk_container_add (GTK_CONTAINER (dateentry->arrow), arrow);
gtk_box_pack_end (GTK_BOX (dateentry), dateentry->arrow, FALSE, FALSE, 0);
gtk_widget_show (dateentry->entry);
gtk_widget_show (dateentry->arrow);
/* our popup window */
dateentry->popwin = gtk_window_new (GTK_WINDOW_POPUP);
gtk_widget_set_events (dateentry->popwin,
gtk_widget_get_events(dateentry->popwin) | GDK_KEY_PRESS_MASK);
dateentry->frame = gtk_frame_new (NULL);
gtk_container_add (GTK_CONTAINER (dateentry->popwin), dateentry->frame);
gtk_frame_set_shadow_type (GTK_FRAME (dateentry->frame), GTK_SHADOW_OUT);
gtk_widget_show (dateentry->frame);
dateentry->calendar = gtk_calendar_new ();
gtk_container_add (GTK_CONTAINER (dateentry->frame), dateentry->calendar);
gtk_widget_show (dateentry->calendar);
// dateentry signals
g_signal_connect (GTK_OBJECT (dateentry->entry), "activate",
G_CALLBACK (gtk_dateentry_entry_parse), dateentry);
g_signal_connect (GTK_OBJECT (dateentry->entry), "focus-out-event",
G_CALLBACK (gtk_dateentry_focus), dateentry);
g_signal_connect (GTK_OBJECT (dateentry->entry), "key_press_event",
G_CALLBACK (gtk_dateentry_entry_key), dateentry);
// arrow/popwin signals
g_signal_connect (GTK_OBJECT (dateentry->arrow), "toggled",
G_CALLBACK (gtk_dateentry_arrow_press), dateentry);
g_signal_connect (GTK_OBJECT (dateentry->popwin), "key_press_event",
G_CALLBACK (key_press_popup), dateentry);
g_signal_connect (GTK_OBJECT (dateentry->popwin), "button_press_event",
G_CALLBACK (gtk_dateentry_button_press), dateentry);
// calendar signals
g_signal_connect (GTK_OBJECT (dateentry->calendar), "prev-year",
G_CALLBACK (gtk_dateentry_calendar_year), dateentry);
g_signal_connect (GTK_OBJECT (dateentry->calendar), "next-year",
G_CALLBACK (gtk_dateentry_calendar_year), dateentry);
g_signal_connect (GTK_OBJECT (dateentry->calendar), "prev-month",
G_CALLBACK (gtk_dateentry_calendar_year), dateentry);
g_signal_connect (GTK_OBJECT (dateentry->calendar), "next-month",
G_CALLBACK (gtk_dateentry_calendar_year), dateentry);
g_signal_connect (GTK_OBJECT (dateentry->calendar), "day-selected",
G_CALLBACK (gtk_dateentry_calendar_getfrom), dateentry);
g_signal_connect (GTK_OBJECT (dateentry->calendar), "day-selected-double-click",
G_CALLBACK (gtk_dateentry_calendar_select), dateentry);
//gtk_dateentry_calendar_getfrom(NULL, dateentry);
}
GtkWidget *gtk_dateentry_new ()
{
GtkDateEntry *dateentry;
DB( g_print("\n[dateentry] new\n") );
dateentry = g_object_new (GTK_TYPE_DATE_ENTRY, NULL);
return GTK_WIDGET(dateentry);
}
static void gtk_dateentry_destroy (GtkObject * object)
{
GtkDateEntry *dateentry;
DB( g_print(" \n[dateentry] destroy\n") );
g_return_if_fail (GTK_IS_DATE_ENTRY (object));
dateentry = GTK_DATE_ENTRY (object);
DB( g_print(" free gtkentry: %p\n", dateentry->entry) );
DB( g_print(" free arrow: %p\n", dateentry->arrow) );
DB( g_print(" free popwin: %p\n", dateentry->popwin) );
DB( g_print(" free dateentry: %p\n", dateentry) );
if(dateentry->popwin)
gtk_widget_destroy (dateentry->popwin);
dateentry->popwin = NULL;
if(dateentry->date)
g_date_free(dateentry->date);
dateentry->date = NULL;
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
/*
**
*/
void gtk_dateentry_set_date(GtkDateEntry *dateentry, guint32 julian_days)
{
DB( g_print(" \n[dateentry] set date\n") );
g_return_if_fail (GTK_IS_DATE_ENTRY (dateentry));
if(g_date_valid_julian(julian_days))
{
g_date_set_julian (dateentry->date, julian_days);
}
else
{
g_date_set_time_t(dateentry->date, time(NULL));
}
gtk_dateentry_entry_set_text(dateentry);
}
/*
**
*/
void gtk_dateentry_set_mindate(GtkDateEntry *dateentry, guint32 julian_days)
{
DB( g_print(" \n[dateentry] set date\n") );
g_return_if_fail (GTK_IS_DATE_ENTRY (dateentry));
if(g_date_valid_julian(julian_days))
{
g_date_set_julian (&dateentry->mindate, julian_days);
}
}
/*
**
*/
void gtk_dateentry_set_maxdate(GtkDateEntry *dateentry, guint32 julian_days)
{
DB( g_print(" \n[dateentry] set date\n") );
g_return_if_fail (GTK_IS_DATE_ENTRY (dateentry));
if(g_date_valid_julian(julian_days))
{
g_date_set_julian (&dateentry->maxdate, julian_days);
}
}
/*
**
*/
guint32 gtk_dateentry_get_date(GtkDateEntry * dateentry)
{
DB( g_print(" \n[dateentry] get date\n") );
g_return_val_if_fail (GTK_IS_DATE_ENTRY (dateentry), 0);
return(g_date_get_julian(dateentry->date));
}
/*
static void
gtk_dateentry_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkDateEntry *dateentry = GTK_DATE_ENTRY (object);
DB( g_print("\n[dateentry] set %d\n", prop_id) );
switch (prop_id)
{
case PROPERTY_DATE:
DB( g_print(" -> date to %d\n", g_value_get_uint (value)) );
g_date_set_julian (dateentry->date, g_value_get_uint (value));
gtk_dateentry_entry_set_text(dateentry);
break;
default:
//G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_dateentry_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkDateEntry *dateentry = GTK_DATE_ENTRY (object);
DB( g_print("\n[dateentry] get\n") );
switch (prop_id)
{
case PROPERTY_DATE:
DB( g_print(" -> date is %d\n", 0) );
g_value_set_uint (value, g_date_get_julian(dateentry->date));
break;
default:
//G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
*/
/*
** fill in our gtkentry from our GDate
*/
static void gtk_dateentry_entry_set_text(GtkDateEntry * dateentry)
{
gchar buffer[256];
DB( g_print("\n[dateentry] date2entry\n") );
g_date_clamp(dateentry->date, &dateentry->mindate, &dateentry->maxdate);
if(g_date_valid(dateentry->date) == TRUE)
{
g_date_strftime (buffer, 256 - 1, "%x", dateentry->date);
gtk_entry_set_text (GTK_ENTRY (dateentry->entry), buffer);
DB( g_print(" = %s\n", buffer) );
}
else
gtk_entry_set_text (GTK_ENTRY (dateentry->entry), "??");
/* emit the signal */
if(dateentry->lastdate != g_date_get_julian(dateentry->date))
{
DB( g_print(" **emit 'changed' signal**\n") );
g_signal_emit_by_name (dateentry, "changed", NULL, NULL);
}
dateentry->lastdate = g_date_get_julian(dateentry->date);
}
static void gtk_dateentry_tokens(GtkWidget *gtkentry, gpointer user_data)
{
GtkDateEntry *dateentry = user_data;
const gchar *str;
GDateParseTokens pt;
str = gtk_entry_get_text (GTK_ENTRY (dateentry->entry));
g_date_fill_parse_tokens(str, &pt);
DB( g_print(" -> parsetoken return is %d values :%d %d %d\n", pt.num_ints, pt.n[0], pt.n[1], pt.n[2]) );
// initialize with today's date
g_date_set_time_t(dateentry->date, time(NULL));
switch( pt.num_ints )
{
case 1:
DB( g_print(" -> seizured 1 number\n") );
if(g_date_valid_day(pt.n[0]))
g_date_set_day(dateentry->date, pt.n[0]);
break;
case 2:
DB( g_print(" -> seizured 2 numbers\n") );
if( dmy_order[0] != G_DATE_YEAR )
{
if( dmy_order[0] == G_DATE_DAY )
{
if(g_date_valid_day(pt.n[0]))
g_date_set_day(dateentry->date, pt.n[0]);
if(g_date_valid_month(pt.n[1]))
g_date_set_month(dateentry->date, pt.n[1]);
}
else
{
if(g_date_valid_day(pt.n[1]))
g_date_set_day(dateentry->date, pt.n[1]);
if(g_date_valid_month(pt.n[0]))
g_date_set_month(dateentry->date, pt.n[0]);
}
}
break;
}
}
/*
** parse the gtkentry and store the GDate
*/
static void gtk_dateentry_entry_parse(GtkWidget *gtkentry, gpointer user_data)
{
GtkDateEntry *dateentry = user_data;
const gchar *str;
DB( g_print("\n[dateentry] entry_parse\n") );
str = gtk_entry_get_text (GTK_ENTRY (dateentry->entry));
//1) we parse the string according to the locale
g_date_set_parse (dateentry->date, str);
if(g_date_valid(dateentry->date) == FALSE)
{
//2) give a try to tokens: day, day/month, month/day
gtk_dateentry_tokens(gtkentry, user_data);
}
//3) at last if date still invalid, put today's dateentry_signals
// we should consider just warn the user here
if(g_date_valid(dateentry->date) == FALSE)
{
/* today's date */
g_date_set_time_t(dateentry->date, time(NULL));
}
gtk_dateentry_entry_set_text(dateentry);
}
static void gtk_dateentry_calendar_year(GtkWidget *calendar, GtkDateEntry *dateentry)
{
guint year, month, day;
DB( g_print(" (dateentry) year changed\n") );
gtk_calendar_get_date (GTK_CALENDAR (dateentry->calendar), &year, &month, &day);
if( year < 1900)
g_object_set(calendar, "year", 1900, NULL);
if( year > 2200)
g_object_set(calendar, "year", 2200, NULL);
}
/*
** store the calendar date to GDate, update our gtkentry
*/
static void gtk_dateentry_calendar_getfrom(GtkWidget * calendar, GtkDateEntry * dateentry)
{
guint year, month, day;
DB( g_print(" (dateentry) get from calendar\n") );
gtk_calendar_get_date (GTK_CALENDAR (dateentry->calendar), &year, &month, &day);
g_date_set_dmy (dateentry->date, day, month + 1, year);
gtk_dateentry_entry_set_text(dateentry);
}
static gint gtk_dateentry_calendar_select(GtkWidget * calendar, gpointer user_data)
{
GtkDateEntry *dateentry = user_data;
DB( g_print(" (dateentry) calendar_select\n") );
gtk_dateentry_hide_popdown_window(dateentry);
gtk_dateentry_calendar_getfrom(NULL, dateentry);
return FALSE;
}
static gint
gtk_dateentry_entry_key (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
GtkDateEntry *dateentry = user_data;
DB( g_print("\n[dateentry] entry key pressed: state=%04x, keyval=%04x\n", event->state, event->keyval) );
if( event->keyval == GDK_KEY_Up )
{
if( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) )
{
g_date_add_days (dateentry->date, 1);
gtk_dateentry_entry_set_text(dateentry);
}
else
if( event->state & GDK_SHIFT_MASK )
{
g_date_add_months (dateentry->date, 1);
gtk_dateentry_entry_set_text(dateentry);
}
else
if( event->state & GDK_CONTROL_MASK )
{
g_date_add_years (dateentry->date, 1);
gtk_dateentry_entry_set_text(dateentry);
}
return TRUE;
}
else
if( event->keyval == GDK_KEY_Down )
{
if( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) )
{
g_date_subtract_days (dateentry->date, 1);
gtk_dateentry_entry_set_text(dateentry);
}
else
if( event->state & GDK_SHIFT_MASK )
{
g_date_subtract_months (dateentry->date, 1);
gtk_dateentry_entry_set_text(dateentry);
}
else
if( event->state & GDK_CONTROL_MASK )
{
g_date_subtract_years (dateentry->date, 1);
gtk_dateentry_entry_set_text(dateentry);
}
return TRUE;
}
return FALSE;
}
static void
position_popup (GtkDateEntry * dateentry)
{
gint x, y;
gint bwidth, bheight;
GtkRequisition req;
GdkWindow *gdkwindow;
GtkAllocation allocation;
DB( g_print("\n[dateentry] position popup\n") );
gtk_widget_size_request (dateentry->popwin, &req);
gdkwindow = gtk_widget_get_window(dateentry->arrow);
gdk_window_get_origin (gdkwindow, &x, &y);
gtk_widget_get_allocation(dateentry->arrow, &allocation);
x += allocation.x;
y += allocation.y;
bwidth = allocation.width;
bheight = allocation.height;
x += bwidth - req.width;
y += bheight;
if (x < 0)
x = 0;
if (y < 0)
y = 0;
gtk_window_move (GTK_WINDOW (dateentry->popwin), x, y);
}
static void
gtk_dateentry_popup_display (GtkDateEntry * dateentry)
{
const char *str;
int month;
//gint height, width, x, y;
//gint old_width, old_height;
DB( g_print("\n[dateentry] popup_display\n****\n\n") );
//old_width = dateentry->popwin->allocation.width;
//old_height = dateentry->popwin->allocation.height;
/* update */
str = gtk_entry_get_text (GTK_ENTRY (dateentry->entry));
g_date_set_parse (dateentry->date, str);
if(g_date_valid(dateentry->date) == TRUE)
{
/* GtkCalendar expects month to be in 0-11 range (inclusive) */
month = g_date_get_month (dateentry->date) - 1;
gtk_calendar_select_month (GTK_CALENDAR (dateentry->calendar),
CLAMP (month, 0, 11),
g_date_get_year (dateentry->date));
gtk_calendar_select_day (GTK_CALENDAR (dateentry->calendar),
g_date_get_day (dateentry->date));
}
position_popup(dateentry);
gtk_widget_show (dateentry->popwin);
gtk_grab_add (dateentry->popwin);
// this close the popup */
GdkWindow *gdkwindow;
gdkwindow = gtk_widget_get_window(dateentry->popwin);
gdk_pointer_grab (gdkwindow, TRUE,
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_MASK,
NULL, NULL, GDK_CURRENT_TIME);
}
static void
gtk_dateentry_hide_popdown_window(GtkDateEntry *dateentry)
{
DB( g_print("\n[dateentry] hide_popdown_window\n") );
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dateentry->arrow), FALSE);
gtk_grab_remove(dateentry->popwin);
gdk_pointer_ungrab(GDK_CURRENT_TIME);
gtk_widget_hide(dateentry->popwin);
}
static gint
gtk_dateentry_arrow_press (GtkWidget * widget, GtkDateEntry * dateentry)
{
GtkToggleButton *button;
DB( g_print("\n[dateentry] arrow_press\n") );
button = GTK_TOGGLE_BUTTON(widget);
if(!gtk_toggle_button_get_active(button)){
gtk_widget_hide (dateentry->popwin);
gtk_grab_remove (dateentry->popwin);
gdk_pointer_ungrab (GDK_CURRENT_TIME);
gtk_dateentry_calendar_getfrom(NULL, dateentry);
return TRUE;
}
gtk_dateentry_popup_display(dateentry);
return TRUE;
}
static gint
key_press_popup (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
GtkDateEntry *dateentry = user_data;
DB( g_print("\n[dateentry] key pressed%d\n", event->keyval) );
if (event->keyval != GDK_KEY_Escape)
return FALSE;
g_signal_stop_emission_by_name (widget, "key_press_event");
gtk_dateentry_hide_popdown_window(dateentry);
return TRUE;
}
static gint
gtk_dateentry_button_press (GtkWidget * widget, GdkEvent * event, gpointer user_data)
{
GtkWidget *child;
DB( g_print("\n[dateentry] button_press\n") );
child = gtk_get_event_widget (event);
if (child != widget)
{
while (child)
{
if (child == widget)
return FALSE;
child = gtk_widget_get_parent(child);
}
}
gtk_widget_hide (widget);
gtk_grab_remove (widget);
gdk_pointer_ungrab (GDK_CURRENT_TIME);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(GTK_DATE_ENTRY(user_data)->arrow), FALSE);
return TRUE;
}