GnuCash  5.6-150-g038405b370+
gnucash-date-picker.c
1 /********************************************************************\
2  * gnucash-date-picker.c -- A popup date picker using gtk_calendar *
3  * *
4  * This program is free software; you can redistribute it and/or *
5  * modify it under the terms of the GNU General Public License as *
6  * published by the Free Software Foundation; either version 2 of *
7  * the License, or (at your option) any later version. *
8  * *
9  * This program is distributed in the hope that it will be useful, *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12  * GNU General Public License for more details. *
13  * *
14  * You should have received a copy of the GNU General Public License*
15  * along with this program; if not, contact: *
16  * *
17  * Free Software Foundation Voice: +1-617-542-5942 *
18  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
19  * Boston, MA 02110-1301, USA gnu@gnu.org *
20  * *
21 \********************************************************************/
22 
23 /*
24  * A popup date picker for the canvas using gtk_calendar.
25  */
26 
27 #include <config.h>
28 #include <gdk/gdkkeysyms.h>
29 #include "gnucash-date-picker.h"
30 
31 /* Item list signals */
32 enum
33 {
34  DATE_SELECTED,
35  DATE_PICKED,
36  LAST_SIGNAL
37 };
38 
39 static guint gnc_date_picker_signals[LAST_SIGNAL];
40 
41 G_DEFINE_TYPE (GNCDatePicker, gnc_date_picker, GTK_TYPE_BOX)
42 
43 void
44 gnc_date_picker_set_date (GNCDatePicker *date_picker,
45  guint day, guint mon, guint year)
46 {
47  g_return_if_fail (IS_GNC_DATE_PICKER (date_picker));
48  g_return_if_fail (date_picker->calendar != NULL);
49 
50  gtk_calendar_select_day (date_picker->calendar, 1);
51  gtk_calendar_select_month (date_picker->calendar, mon, year);
52  gtk_calendar_select_day (date_picker->calendar, day);
53 }
54 
55 void
56 gnc_date_picker_get_date (GNCDatePicker *date_picker,
57  guint *day, guint *mon, guint *year)
58 {
59  g_return_if_fail (IS_GNC_DATE_PICKER (date_picker));
60  g_return_if_fail (date_picker->calendar != NULL);
61 
62  gtk_calendar_get_date (date_picker->calendar, year, mon, day);
63 }
64 
65 static void
66 gnc_date_picker_init (GNCDatePicker *date_picker)
67 {
68  gtk_orientable_set_orientation (GTK_ORIENTABLE(date_picker), GTK_ORIENTATION_HORIZONTAL);
69  date_picker->calendar = NULL;
70 }
71 
72 static gboolean
73 gnc_date_picker_button_event (GtkWidget *widget, GdkEventButton *event,
74  gpointer data)
75 {
76  /* So the sheet doesn't use it. */
77  g_signal_stop_emission_by_name (widget, "button_press_event");
78 
79  return TRUE;
80 }
81 
82 static gboolean
83 gnc_date_picker_key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
84 {
85  GNCDatePicker *date_picker = GNC_DATE_PICKER (data);
86  gboolean retval;
87 
88  switch (event->keyval)
89  {
90  case GDK_KEY_Return:
91  case GDK_KEY_KP_Enter:
92  g_signal_emit (date_picker, gnc_date_picker_signals[DATE_PICKED], 0);
93  g_signal_stop_emission_by_name (widget, "key_press_event");
94 
95  return TRUE;
96 
97  case GDK_KEY_Up:
98  case GDK_KEY_Down:
99  case GDK_KEY_Left:
100  case GDK_KEY_Right:
101  case GDK_KEY_space:
102  /* these go to the calendar */
103  return FALSE;
104 
105  default:
106  break;
107  }
108 
109  /* These go to the sheet */
110  g_signal_stop_emission_by_name (widget, "key_press_event");
111 
112  g_signal_emit_by_name (date_picker, "key_press_event", event, &retval);
113 
114  return retval;
115 }
116 
117 static void
118 gnc_date_picker_class_init (GNCDatePickerClass *date_picker_class)
119 {
120  GObjectClass *object_class = G_OBJECT_CLASS (date_picker_class);
121 
122  gtk_widget_class_set_css_name (GTK_WIDGET_CLASS(date_picker_class), "gnc-id-date-picker");
123 
124  gnc_date_picker_signals[DATE_SELECTED] =
125  g_signal_new("date_selected",
126  G_TYPE_FROM_CLASS(object_class),
127  G_SIGNAL_RUN_LAST,
128  G_STRUCT_OFFSET(GNCDatePickerClass, date_selected),
129  NULL, NULL,
130  g_cclosure_marshal_VOID__VOID,
131  G_TYPE_NONE, 0);
132 
133  gnc_date_picker_signals[DATE_PICKED] =
134  g_signal_new("date_picked",
135  G_TYPE_FROM_CLASS(object_class),
136  G_SIGNAL_RUN_LAST,
137  G_STRUCT_OFFSET(GNCDatePickerClass, date_picked),
138  NULL, NULL,
139  g_cclosure_marshal_VOID__VOID,
140  G_TYPE_NONE, 0);
141 
142  date_picker_class->date_selected = NULL;
143  date_picker_class->date_picked = NULL;
144 }
145 
146 
147 static void
148 day_selected (GtkCalendar *calendar, GNCDatePicker *gdp)
149 {
150  g_signal_emit (gdp, gnc_date_picker_signals [DATE_SELECTED], 0);
151 }
152 
153 static void
154 day_selected_double_click (GtkCalendar *calendar, GNCDatePicker *gdp)
155 {
156  g_signal_emit (gdp, gnc_date_picker_signals [DATE_PICKED], 0);
157 }
158 
159 
160 GtkWidget *
161 gnc_date_picker_new (void)
162 {
163  GtkWidget *calendar;
164  GNCDatePicker *date_picker;
165  GtkAllocation allocation;
166  GtkRequisition requisition;
167 
168  date_picker = g_object_new (GNC_TYPE_DATE_PICKER,
169  "homogeneous", FALSE,
170  NULL);
171 
172  calendar = gtk_calendar_new ();
173  date_picker->calendar = GTK_CALENDAR (calendar);
174 
175  gtk_box_pack_start (GTK_BOX(date_picker), calendar, TRUE, TRUE, 0);
176 
177  gtk_widget_get_preferred_size (calendar, &requisition, NULL);
178  allocation.x = 0;
179  allocation.y = 0;
180  allocation.width = requisition.width;
181  allocation.height = requisition.height;
182  gtk_widget_size_allocate (calendar, &allocation);
183 
184  g_signal_connect_after (calendar, "button_press_event",
185  G_CALLBACK (gnc_date_picker_button_event),
186  date_picker);
187 
188  g_signal_connect (calendar, "key_press_event",
189  G_CALLBACK (gnc_date_picker_key_event),
190  date_picker);
191 
192  g_signal_connect (calendar, "day_selected",
193  G_CALLBACK (day_selected),
194  date_picker);
195 
196  g_signal_connect (calendar, "day_selected_double_click",
197  G_CALLBACK (day_selected_double_click),
198  date_picker);
199 
200  return GTK_WIDGET(date_picker);
201 }
Public declarations for GncDatePicker class.