Fixes #1245. ECalendar should be usable with the keyboard
2003-09-19 Bolian Yin <bolian.yin@sun.com> Fixes #1245. ECalendar should be usable with the keyboard *misc/e-calendar-item.c (e_calendar_item_focus): new func, focus handler. (e_calendar_item_key_press_event): new func, key press event handler (e_calendar_item_selection_add_days, e_calendar_item_stop_selecting): helpers. (e_calendar_item_ensure_days_visible, e_calendar_item_set_selection_if_emission): add the flag to control if we should emit e-calendar signals. (e_calendar_item_class_init): register focus handler. (e_calendar_item_event): add code for GDK_FOCUS_CHANGE and GDK_KEY_PRESS. *misc/e-calendar.c (e_calendar_focus): new func, focus handler (e_calendar_button_has_focus): new func, if prev/next button has focus. (e_calendar_on_next_clicked, e_calendar_on_prev_clicked): click signal handler for prev/next buttons. (e_calendar_set_focusable): set if the e-calendar is focusable *misc/e-dateedit.c (e_date_edit_show_date_popup, hide_date_popup): grab/ungrab gdk keyboard. svn path=/trunk/; revision=22632
This commit is contained in:
@ -1,3 +1,23 @@
|
||||
2003-09-19 Bolian Yin <bolian.yin@sun.com>
|
||||
|
||||
Fixes #1245. ECalendar should be usable with the keyboard
|
||||
|
||||
*misc/e-calendar-item.c (e_calendar_item_focus): new func, focus handler.
|
||||
(e_calendar_item_key_press_event): new func, key press event handler
|
||||
(e_calendar_item_selection_add_days, e_calendar_item_stop_selecting): helpers.
|
||||
(e_calendar_item_ensure_days_visible, e_calendar_item_set_selection_if_emission):
|
||||
add the flag to control if we should emit e-calendar signals.
|
||||
(e_calendar_item_class_init): register focus handler.
|
||||
(e_calendar_item_event): add code for GDK_FOCUS_CHANGE and GDK_KEY_PRESS.
|
||||
|
||||
*misc/e-calendar.c (e_calendar_focus): new func, focus handler
|
||||
(e_calendar_button_has_focus): new func, if prev/next button has focus.
|
||||
(e_calendar_on_next_clicked, e_calendar_on_prev_clicked): click signal handler
|
||||
for prev/next buttons.
|
||||
(e_calendar_set_focusable): set if the e-calendar is focusable
|
||||
|
||||
*misc/e-dateedit.c (e_date_edit_show_date_popup, hide_date_popup): grab/ungrab gdk keyboard.
|
||||
|
||||
2003-08-27 Hans Petter Jansson <hpj@ximian.com>
|
||||
|
||||
Fixes #15638.
|
||||
|
@ -3,6 +3,7 @@
|
||||
/*
|
||||
* Author :
|
||||
* Damon Chaplin <damon@ximian.com>
|
||||
* Bolian Yin <bolian.yin@sun.com>
|
||||
*
|
||||
* Copyright 2000, Ximian, Inc.
|
||||
*
|
||||
@ -41,6 +42,7 @@
|
||||
#include <gtk/gtkmenuitem.h>
|
||||
#include <gtk/gtklabel.h>
|
||||
#include <gtk/gtksignal.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <libgnome/gnome-i18n.h>
|
||||
#include <gal/util/e-util.h>
|
||||
|
||||
@ -92,6 +94,8 @@ static void e_calendar_item_get_arg (GtkObject *o,
|
||||
static void e_calendar_item_set_arg (GtkObject *o,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
static gboolean e_calendar_item_focus (GtkWidget *widget,
|
||||
GtkDirectionType direction);
|
||||
static void e_calendar_item_realize (GnomeCanvasItem *item);
|
||||
static void e_calendar_item_unrealize (GnomeCanvasItem *item);
|
||||
static void e_calendar_item_unmap (GnomeCanvasItem *item);
|
||||
@ -130,6 +134,13 @@ static double e_calendar_item_point (GnomeCanvasItem *item,
|
||||
int cx,
|
||||
int cy,
|
||||
GnomeCanvasItem **actual_item);
|
||||
static void e_calendar_item_stop_selecting (ECalendarItem *calitem,
|
||||
guint32 time);
|
||||
static void e_calendar_item_selection_add_days (ECalendarItem *calitem,
|
||||
gint n_days,
|
||||
gboolean multi_selection);
|
||||
static gint e_calendar_item_key_press_event (ECalendarItem *item,
|
||||
GdkEvent *event);
|
||||
static gint e_calendar_item_event (GnomeCanvasItem *item,
|
||||
GdkEvent *event);
|
||||
static void e_calendar_item_bounds (GnomeCanvasItem *item, double *x1, double *y1,
|
||||
@ -205,13 +216,14 @@ static gint e_calendar_item_get_inclusive_days (ECalendarItem *calitem,
|
||||
static void e_calendar_item_ensure_valid_day (ECalendarItem *calitem,
|
||||
gint *month_offset,
|
||||
gint *day);
|
||||
static gboolean e_calendar_item_ensure_days_visible (ECalendarItem *calitem,
|
||||
gint start_year,
|
||||
gint start_month,
|
||||
gint start_day,
|
||||
gint end_year,
|
||||
gint end_month,
|
||||
gint end_day);
|
||||
static gboolean e_calendar_item_ensure_days_visible (ECalendarItem *calitem,
|
||||
gint start_year,
|
||||
gint start_month,
|
||||
gint start_day,
|
||||
gint end_year,
|
||||
gint end_month,
|
||||
gint end_day,
|
||||
gboolean emission);
|
||||
static void e_calendar_item_show_popup_menu (ECalendarItem *calitem,
|
||||
GdkEventButton *event,
|
||||
gint month_offset);
|
||||
@ -225,6 +237,10 @@ static void e_calendar_item_position_menu (GtkMenu *menu,
|
||||
static void e_calendar_item_date_range_changed (ECalendarItem *calitem);
|
||||
static void e_calendar_item_queue_signal_emission (ECalendarItem *calitem);
|
||||
static gboolean e_calendar_item_signal_emission_idle_cb (gpointer data);
|
||||
static void e_calendar_item_set_selection_if_emission (ECalendarItem *calitem,
|
||||
GDate *start_date,
|
||||
GDate *end_date,
|
||||
gboolean emission);
|
||||
|
||||
/* Our arguments. */
|
||||
enum {
|
||||
@ -273,11 +289,13 @@ static void
|
||||
e_calendar_item_class_init (ECalendarItemClass *class)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
GtkWidgetClass *widget_class;
|
||||
GnomeCanvasItemClass *item_class;
|
||||
|
||||
parent_class = g_type_class_ref(gnome_canvas_item_get_type());
|
||||
|
||||
object_class = (GtkObjectClass *) class;
|
||||
widget_class = (GtkWidgetClass *) class;
|
||||
item_class = (GnomeCanvasItemClass *) class;
|
||||
|
||||
gtk_object_add_arg_type ("ECalendarItem::year",
|
||||
@ -363,6 +381,7 @@ e_calendar_item_class_init (ECalendarItemClass *class)
|
||||
object_class->get_arg = e_calendar_item_get_arg;
|
||||
object_class->set_arg = e_calendar_item_set_arg;
|
||||
|
||||
widget_class->focus = e_calendar_item_focus;
|
||||
/* GnomeCanvasItem method overrides */
|
||||
item_class->realize = e_calendar_item_realize;
|
||||
item_class->unrealize = e_calendar_item_unrealize;
|
||||
@ -416,6 +435,9 @@ e_calendar_item_init (ECalendarItem *calitem)
|
||||
calitem->x2 = 0.0;
|
||||
calitem->y2 = 0.0;
|
||||
|
||||
calitem->selecting = FALSE;
|
||||
calitem->selecting_axis = NULL;
|
||||
|
||||
calitem->selection_set = FALSE;
|
||||
|
||||
calitem->selection_changed = FALSE;
|
||||
@ -467,6 +489,8 @@ e_calendar_item_destroy (GtkObject *o)
|
||||
calitem->week_number_font_desc = NULL;
|
||||
}
|
||||
|
||||
if (calitem->selecting_axis)
|
||||
g_free (calitem->selecting_axis);
|
||||
if (GTK_OBJECT_CLASS (parent_class)->destroy)
|
||||
(* GTK_OBJECT_CLASS (parent_class)->destroy) (o);
|
||||
}
|
||||
@ -693,6 +717,18 @@ e_calendar_item_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
e_calendar_item_focus (GtkWidget *widget, GtkDirectionType direction)
|
||||
{
|
||||
ECalendarItem *calitem;
|
||||
|
||||
g_return_val_if_fail (widget != NULL, FALSE);
|
||||
g_return_val_if_fail (E_IS_CALENDAR_ITEM (widget), FALSE);
|
||||
calitem = E_CALENDAR_ITEM (widget);
|
||||
|
||||
GTK_WIDGET_CLASS (parent_class)->focus (widget, direction);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
e_calendar_item_realize (GnomeCanvasItem *item)
|
||||
@ -717,6 +753,10 @@ e_calendar_item_realize (GnomeCanvasItem *item)
|
||||
calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_FG].green = 65535;
|
||||
calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_FG].blue = 65535;
|
||||
|
||||
calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG_FOCUSED].red = 4700;
|
||||
calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG_FOCUSED].green = 4700;
|
||||
calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG_FOCUSED].blue = 65535;
|
||||
|
||||
calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG].red = 47000;
|
||||
calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG].green = 47000;
|
||||
calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG].blue = 48000;
|
||||
@ -1254,7 +1294,7 @@ e_calendar_item_draw_day_numbers (ECalendarItem *calitem,
|
||||
gint num_chars, digit;
|
||||
gint week_num, mon, days_from_week_start;
|
||||
gint years[3], months[3], days_in_month[3];
|
||||
gboolean today, selected, has_focus = FALSE, drop_target = FALSE;
|
||||
gboolean today, selected, has_focus, drop_target = FALSE;
|
||||
gboolean bold, draw_day, finished = FALSE;
|
||||
gint today_year, today_month, today_mday, month_offset;
|
||||
gchar buffer[2];
|
||||
@ -1403,6 +1443,12 @@ e_calendar_item_draw_day_numbers (ECalendarItem *calitem,
|
||||
day_style = calitem->styles[(month_offset + 1) * 32 + day_num];
|
||||
|
||||
/* Get the colors & style to use for the day.*/
|
||||
if ((GTK_WIDGET_HAS_FOCUS(item->canvas)) &&
|
||||
item->canvas->focused_item == item)
|
||||
has_focus = TRUE;
|
||||
else
|
||||
has_focus = FALSE;
|
||||
|
||||
if (calitem->style_callback)
|
||||
(*calitem->style_callback)
|
||||
(calitem,
|
||||
@ -1586,6 +1632,128 @@ e_calendar_item_point (GnomeCanvasItem *item, double x, double y,
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static void
|
||||
e_calendar_item_stop_selecting (ECalendarItem *calitem, guint32 time)
|
||||
{
|
||||
if (!calitem->selecting)
|
||||
return;
|
||||
|
||||
gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM (calitem), time);
|
||||
|
||||
calitem->selecting = FALSE;
|
||||
|
||||
/* If the user selects the grayed dates before the first month or
|
||||
after the last month, we move backwards or forwards one month.
|
||||
The set_month() call should take care of updating the selection. */
|
||||
if (calitem->selection_end_month_offset == -1)
|
||||
e_calendar_item_set_first_month (calitem, calitem->year,
|
||||
calitem->month - 1);
|
||||
else if (calitem->selection_start_month_offset == calitem->rows * calitem->cols)
|
||||
e_calendar_item_set_first_month (calitem, calitem->year,
|
||||
calitem->month + 1);
|
||||
|
||||
calitem->selection_changed = TRUE;
|
||||
if (calitem->selecting_axis) {
|
||||
g_free (calitem->selecting_axis);
|
||||
calitem->selecting_axis = NULL;
|
||||
}
|
||||
|
||||
e_calendar_item_queue_signal_emission (calitem);
|
||||
gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem));
|
||||
}
|
||||
|
||||
static void
|
||||
e_calendar_item_selection_add_days (ECalendarItem *calitem, gint n_days,
|
||||
gboolean multi_selection)
|
||||
{
|
||||
GDate gdate_start, gdate_end;
|
||||
|
||||
g_return_if_fail (E_IS_CALENDAR_ITEM (calitem));
|
||||
|
||||
if (!e_calendar_item_get_selection (calitem, &gdate_start, &gdate_end))
|
||||
return;
|
||||
if (multi_selection && calitem->max_days_selected > 1) {
|
||||
gint days_between;
|
||||
|
||||
days_between = g_date_days_between (&gdate_start, &gdate_end);
|
||||
if (!calitem->selecting_axis) {
|
||||
calitem->selecting_axis = g_new (GDate, 1);
|
||||
*(calitem->selecting_axis) = gdate_start;
|
||||
}
|
||||
if ((days_between != 0 &&
|
||||
g_date_compare (calitem->selecting_axis, &gdate_end) == 0) ||
|
||||
(days_between == 0 && n_days < 0)) {
|
||||
if (days_between - n_days > calitem->max_days_selected - 1)
|
||||
n_days = days_between + 1 - calitem->max_days_selected;
|
||||
g_date_add_days (&gdate_start, n_days);
|
||||
}
|
||||
else {
|
||||
if (days_between + n_days > calitem->max_days_selected - 1)
|
||||
n_days = calitem->max_days_selected - 1 - days_between;
|
||||
g_date_add_days (&gdate_end, n_days);
|
||||
}
|
||||
|
||||
if (g_date_compare (&gdate_end, &gdate_start) < 0) {
|
||||
GDate tmp_date;
|
||||
tmp_date = gdate_start;
|
||||
gdate_start = gdate_end;
|
||||
gdate_end = tmp_date;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* clear "selecting_axis", it is only for mulit-selecting */
|
||||
if (calitem->selecting_axis) {
|
||||
g_free (calitem->selecting_axis);
|
||||
calitem->selecting_axis = NULL;
|
||||
}
|
||||
g_date_add_days (&gdate_start, n_days);
|
||||
gdate_end = gdate_start;
|
||||
}
|
||||
|
||||
calitem->selecting = TRUE;
|
||||
|
||||
e_calendar_item_set_selection_if_emission (calitem,
|
||||
&gdate_start, &gdate_end,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
static gint
|
||||
e_calendar_item_key_press_event (ECalendarItem *calitem, GdkEvent *event)
|
||||
{
|
||||
guint keyval = event->key.keyval;
|
||||
gboolean multi_selection = FALSE;
|
||||
|
||||
if (event->key.state & GDK_CONTROL_MASK ||
|
||||
event->key.state & GDK_MOD1_MASK)
|
||||
return FALSE;
|
||||
|
||||
multi_selection = event->key.state & GDK_SHIFT_MASK;
|
||||
switch (keyval) {
|
||||
case GDK_Up:
|
||||
e_calendar_item_selection_add_days (calitem, -7,
|
||||
multi_selection);
|
||||
break;
|
||||
case GDK_Down:
|
||||
e_calendar_item_selection_add_days (calitem, 7,
|
||||
multi_selection);
|
||||
break;
|
||||
case GDK_Left:
|
||||
e_calendar_item_selection_add_days (calitem, -1,
|
||||
multi_selection);
|
||||
break;
|
||||
case GDK_Right:
|
||||
e_calendar_item_selection_add_days (calitem, 1,
|
||||
multi_selection);
|
||||
break;
|
||||
case GDK_space:
|
||||
case GDK_Return:
|
||||
e_calendar_item_stop_selecting (calitem, event->key.time);
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gint
|
||||
e_calendar_item_event (GnomeCanvasItem *item, GdkEvent *event)
|
||||
@ -1601,6 +1769,10 @@ e_calendar_item_event (GnomeCanvasItem *item, GdkEvent *event)
|
||||
return e_calendar_item_button_release (calitem, event);
|
||||
case GDK_MOTION_NOTIFY:
|
||||
return e_calendar_item_motion (calitem, event);
|
||||
case GDK_FOCUS_CHANGE:
|
||||
gnome_canvas_item_request_update (item);
|
||||
case GDK_KEY_PRESS:
|
||||
return e_calendar_item_key_press_event (calitem, event);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1752,7 +1924,11 @@ e_calendar_item_get_day_style (ECalendarItem *calitem,
|
||||
|
||||
if (selected) {
|
||||
*fg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_FG];
|
||||
*bg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG];
|
||||
if (has_focus)
|
||||
*bg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG_FOCUSED];
|
||||
else
|
||||
*bg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1840,33 +2016,11 @@ e_calendar_item_button_press (ECalendarItem *calitem,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
e_calendar_item_button_release (ECalendarItem *calitem,
|
||||
GdkEvent *event)
|
||||
{
|
||||
if (!calitem->selecting)
|
||||
return FALSE;
|
||||
|
||||
gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM (calitem),
|
||||
event->button.time);
|
||||
|
||||
calitem->selecting = FALSE;
|
||||
|
||||
/* If the user selects the grayed dates before the first month or
|
||||
after the last month, we move backwards or forwards one month.
|
||||
The set_month() call should take care of updating the selection. */
|
||||
if (calitem->selection_end_month_offset == -1)
|
||||
e_calendar_item_set_first_month (calitem, calitem->year,
|
||||
calitem->month - 1);
|
||||
else if (calitem->selection_start_month_offset == calitem->rows * calitem->cols)
|
||||
e_calendar_item_set_first_month (calitem, calitem->year,
|
||||
calitem->month + 1);
|
||||
|
||||
calitem->selection_changed = TRUE;
|
||||
e_calendar_item_queue_signal_emission (calitem);
|
||||
gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem));
|
||||
|
||||
e_calendar_item_stop_selecting (calitem, event->button.time);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -2727,10 +2881,11 @@ e_calendar_item_get_selection (ECalendarItem *calitem,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
e_calendar_item_set_selection (ECalendarItem *calitem,
|
||||
GDate *start_date,
|
||||
GDate *end_date)
|
||||
static void
|
||||
e_calendar_item_set_selection_if_emission (ECalendarItem *calitem,
|
||||
GDate *start_date,
|
||||
GDate *end_date,
|
||||
gboolean emission)
|
||||
{
|
||||
gint start_year, start_month, start_day;
|
||||
gint end_year, end_month, end_day;
|
||||
@ -2740,13 +2895,6 @@ e_calendar_item_set_selection (ECalendarItem *calitem,
|
||||
|
||||
g_return_if_fail (E_IS_CALENDAR_ITEM (calitem));
|
||||
|
||||
/* If the user is in the middle of a selection, we must abort it. */
|
||||
if (calitem->selecting) {
|
||||
gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM (calitem),
|
||||
GDK_CURRENT_TIME);
|
||||
calitem->selecting = FALSE;
|
||||
}
|
||||
|
||||
/* If start_date is NULL, we clear the selection without changing the
|
||||
month shown. */
|
||||
if (start_date == NULL) {
|
||||
@ -2759,9 +2907,9 @@ e_calendar_item_set_selection (ECalendarItem *calitem,
|
||||
|
||||
if (end_date == NULL)
|
||||
end_date = start_date;
|
||||
|
||||
|
||||
g_return_if_fail (g_date_compare (start_date, end_date) <= 0);
|
||||
|
||||
|
||||
start_year = g_date_get_year (start_date);
|
||||
start_month = g_date_get_month (start_date) - 1;
|
||||
start_day = g_date_get_day (start_date);
|
||||
@ -2775,7 +2923,8 @@ e_calendar_item_set_selection (ECalendarItem *calitem,
|
||||
start_day,
|
||||
end_year,
|
||||
end_month,
|
||||
end_day);
|
||||
end_day,
|
||||
emission);
|
||||
|
||||
new_start_month_offset = (start_year - calitem->year) * 12
|
||||
+ start_month - calitem->month;
|
||||
@ -2794,7 +2943,8 @@ e_calendar_item_set_selection (ECalendarItem *calitem,
|
||||
|| calitem->selection_end_day != new_end_day) {
|
||||
need_update = TRUE;
|
||||
calitem->selection_changed = TRUE;
|
||||
e_calendar_item_queue_signal_emission (calitem);
|
||||
if (emission)
|
||||
e_calendar_item_queue_signal_emission (calitem);
|
||||
calitem->selection_set = TRUE;
|
||||
calitem->selection_start_month_offset = new_start_month_offset;
|
||||
calitem->selection_start_day = new_start_day;
|
||||
@ -2810,6 +2960,22 @@ e_calendar_item_set_selection (ECalendarItem *calitem,
|
||||
gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem));
|
||||
}
|
||||
|
||||
void
|
||||
e_calendar_item_set_selection (ECalendarItem *calitem,
|
||||
GDate *start_date,
|
||||
GDate *end_date)
|
||||
{
|
||||
/* If the user is in the middle of a selection, we must abort it. */
|
||||
if (calitem->selecting) {
|
||||
gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM (calitem),
|
||||
GDK_CURRENT_TIME);
|
||||
calitem->selecting = FALSE;
|
||||
}
|
||||
|
||||
e_calendar_item_set_selection_if_emission (calitem,
|
||||
start_date, end_date,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
/* This tries to ensure that the given time range is visible. If the range
|
||||
given is longer than we can show, only the start of it will be visible.
|
||||
@ -2822,7 +2988,8 @@ e_calendar_item_ensure_days_visible (ECalendarItem *calitem,
|
||||
gint start_day,
|
||||
gint end_year,
|
||||
gint end_month,
|
||||
gint end_day)
|
||||
gint end_day,
|
||||
gboolean emission)
|
||||
{
|
||||
gint current_end_year, current_end_month;
|
||||
gint months_shown, months;
|
||||
@ -2903,7 +3070,7 @@ e_calendar_item_ensure_days_visible (ECalendarItem *calitem,
|
||||
}
|
||||
}
|
||||
|
||||
if (need_update)
|
||||
if (need_update && emission)
|
||||
e_calendar_item_date_range_changed (calitem);
|
||||
|
||||
return need_update;
|
||||
|
@ -45,6 +45,7 @@ typedef enum
|
||||
{
|
||||
E_CALENDAR_ITEM_COLOR_TODAY_BOX,
|
||||
E_CALENDAR_ITEM_COLOR_SELECTION_FG,
|
||||
E_CALENDAR_ITEM_COLOR_SELECTION_BG_FOCUSED,
|
||||
E_CALENDAR_ITEM_COLOR_SELECTION_BG,
|
||||
E_CALENDAR_ITEM_COLOR_PREV_OR_NEXT_MONTH_FG,
|
||||
|
||||
@ -174,6 +175,7 @@ struct _ECalendarItem
|
||||
top-left calendar month view. Note that -1 is used for the last days
|
||||
from the previous month. The days are real month days. */
|
||||
gboolean selecting;
|
||||
GDate *selecting_axis;
|
||||
gboolean selection_dragging_end;
|
||||
gboolean selection_from_full_week;
|
||||
gboolean selection_set;
|
||||
|
@ -3,6 +3,7 @@
|
||||
/*
|
||||
* Author :
|
||||
* Damon Chaplin <damon@ximian.com>
|
||||
* Bolian Yin <bolian.yin@sun.com>
|
||||
*
|
||||
* Copyright 2000, Ximian, Inc.
|
||||
*
|
||||
@ -86,11 +87,16 @@ static gint e_calendar_drag_motion (GtkWidget *widget,
|
||||
static void e_calendar_drag_leave (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
guint time);
|
||||
static gboolean e_calendar_button_has_focus (ECalendar *cal);
|
||||
static gboolean e_calendar_focus (GtkWidget *widget,
|
||||
GtkDirectionType direction);
|
||||
|
||||
static void e_calendar_on_prev_pressed (ECalendar *cal);
|
||||
static void e_calendar_on_prev_released (ECalendar *cal);
|
||||
static void e_calendar_on_prev_clicked (ECalendar *cal);
|
||||
static void e_calendar_on_next_pressed (ECalendar *cal);
|
||||
static void e_calendar_on_next_released (ECalendar *cal);
|
||||
static void e_calendar_on_next_clicked (ECalendar *cal);
|
||||
|
||||
static void e_calendar_start_auto_move (ECalendar *cal,
|
||||
gboolean moving_forward);
|
||||
@ -124,6 +130,7 @@ e_calendar_class_init (ECalendarClass *class)
|
||||
widget_class->size_allocate = e_calendar_size_allocate;
|
||||
widget_class->drag_motion = e_calendar_drag_motion;
|
||||
widget_class->drag_leave = e_calendar_drag_leave;
|
||||
widget_class->focus = e_calendar_focus;
|
||||
}
|
||||
|
||||
|
||||
@ -134,8 +141,6 @@ e_calendar_init (ECalendar *cal)
|
||||
PangoFontDescription *small_font_desc;
|
||||
GtkWidget *button, *pixmap;
|
||||
|
||||
GTK_WIDGET_UNSET_FLAGS (cal, GTK_CAN_FOCUS);
|
||||
|
||||
/* Create the small font. */
|
||||
|
||||
small_font_desc =
|
||||
@ -154,7 +159,6 @@ e_calendar_init (ECalendar *cal)
|
||||
|
||||
/* Create the arrow buttons to move to the previous/next month. */
|
||||
button = gtk_button_new ();
|
||||
GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
|
||||
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
|
||||
gtk_widget_show (button);
|
||||
gtk_signal_connect_object (GTK_OBJECT (button), "pressed",
|
||||
@ -163,6 +167,9 @@ e_calendar_init (ECalendar *cal)
|
||||
gtk_signal_connect_object (GTK_OBJECT (button), "released",
|
||||
G_CALLBACK (e_calendar_on_prev_released),
|
||||
GTK_OBJECT (cal));
|
||||
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
|
||||
G_CALLBACK (e_calendar_on_prev_clicked),
|
||||
GTK_OBJECT (cal));
|
||||
|
||||
pixmap = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_NONE);
|
||||
gtk_widget_show (pixmap);
|
||||
@ -174,7 +181,6 @@ e_calendar_init (ECalendar *cal)
|
||||
NULL);
|
||||
|
||||
button = gtk_button_new ();
|
||||
GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
|
||||
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
|
||||
gtk_widget_show (button);
|
||||
gtk_signal_connect_object (GTK_OBJECT (button), "pressed",
|
||||
@ -183,6 +189,9 @@ e_calendar_init (ECalendar *cal)
|
||||
gtk_signal_connect_object (GTK_OBJECT (button), "released",
|
||||
G_CALLBACK (e_calendar_on_next_released),
|
||||
GTK_OBJECT (cal));
|
||||
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
|
||||
G_CALLBACK (e_calendar_on_next_clicked),
|
||||
GTK_OBJECT (cal));
|
||||
|
||||
pixmap = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
|
||||
gtk_widget_show (pixmap);
|
||||
@ -431,6 +440,12 @@ e_calendar_on_prev_pressed (ECalendar *cal)
|
||||
e_calendar_start_auto_move (cal, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
e_calendar_on_prev_clicked (ECalendar *cal)
|
||||
{
|
||||
e_calendar_item_set_first_month (cal->calitem, cal->calitem->year,
|
||||
cal->calitem->month - 1);
|
||||
}
|
||||
|
||||
static void
|
||||
e_calendar_on_next_pressed (ECalendar *cal)
|
||||
@ -438,6 +453,12 @@ e_calendar_on_next_pressed (ECalendar *cal)
|
||||
e_calendar_start_auto_move (cal, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
e_calendar_on_next_clicked (ECalendar *cal)
|
||||
{
|
||||
e_calendar_item_set_first_month (cal->calitem, cal->calitem->year,
|
||||
cal->calitem->month + 1);
|
||||
}
|
||||
|
||||
static void
|
||||
e_calendar_start_auto_move (ECalendar *cal,
|
||||
@ -549,3 +570,99 @@ e_calendar_drag_leave (GtkWidget *widget,
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
e_calendar_button_has_focus (ECalendar *cal)
|
||||
{
|
||||
GtkWidget *prev_widget, *next_widget;
|
||||
gboolean ret_val;
|
||||
|
||||
g_return_val_if_fail (E_IS_CALENDAR (cal), FALSE);
|
||||
|
||||
prev_widget = GNOME_CANVAS_WIDGET(cal->prev_item)->widget;
|
||||
next_widget = GNOME_CANVAS_WIDGET(cal->next_item)->widget;
|
||||
ret_val = GTK_WIDGET_HAS_FOCUS (prev_widget) ||
|
||||
GTK_WIDGET_HAS_FOCUS (next_widget);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
e_calendar_focus (GtkWidget *widget, GtkDirectionType direction)
|
||||
{
|
||||
#define E_CALENDAR_FOCUS_CHILDREN_NUM 3
|
||||
ECalendar *cal;
|
||||
GnomeCanvas *canvas;
|
||||
GnomeCanvasItem *children[E_CALENDAR_FOCUS_CHILDREN_NUM];
|
||||
gint focused_index = -1;
|
||||
gint index;
|
||||
|
||||
g_return_val_if_fail (widget != NULL, FALSE);
|
||||
g_return_val_if_fail (E_IS_CALENDAR (widget), FALSE);
|
||||
cal = E_CALENDAR (widget);
|
||||
canvas = GNOME_CANVAS (widget);
|
||||
|
||||
if (!GTK_WIDGET_CAN_FOCUS (widget))
|
||||
return FALSE;
|
||||
|
||||
children[0] = GNOME_CANVAS_ITEM (cal->calitem);
|
||||
children[1] = cal->prev_item;
|
||||
children[2] = cal->next_item;
|
||||
|
||||
/* get current focused item, if e-calendar has had focus */
|
||||
if (GTK_WIDGET_HAS_FOCUS (widget) || e_calendar_button_has_focus (cal))
|
||||
for (index = 0; canvas->focused_item && index < E_CALENDAR_FOCUS_CHILDREN_NUM; ++index) {
|
||||
if (children[index] == canvas->focused_item) {
|
||||
focused_index = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (focused_index == -1)
|
||||
if (direction == GTK_DIR_TAB_FORWARD)
|
||||
focused_index = 0;
|
||||
else
|
||||
focused_index = E_CALENDAR_FOCUS_CHILDREN_NUM - 1;
|
||||
else
|
||||
if (direction == GTK_DIR_TAB_FORWARD)
|
||||
++focused_index;
|
||||
else
|
||||
--focused_index;
|
||||
|
||||
if (focused_index < 0 ||
|
||||
focused_index >= E_CALENDAR_FOCUS_CHILDREN_NUM)
|
||||
/* move out of e-calendar */
|
||||
return FALSE;
|
||||
gnome_canvas_item_grab_focus (children[focused_index]);
|
||||
if (GNOME_IS_CANVAS_WIDGET (children[focused_index])) {
|
||||
GtkWidget *widget;
|
||||
widget = GNOME_CANVAS_WIDGET (children[focused_index])->widget;
|
||||
gtk_widget_grab_focus (widget);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
e_calendar_set_focusable (ECalendar *cal, gboolean focusable)
|
||||
{
|
||||
GtkWidget *prev_widget, *next_widget;
|
||||
|
||||
g_return_if_fail (E_IS_CALENDAR (cal));
|
||||
|
||||
prev_widget = GNOME_CANVAS_WIDGET(cal->prev_item)->widget;
|
||||
next_widget = GNOME_CANVAS_WIDGET(cal->next_item)->widget;
|
||||
|
||||
if (focusable) {
|
||||
GTK_WIDGET_SET_FLAGS (cal, GTK_CAN_FOCUS);
|
||||
GTK_WIDGET_SET_FLAGS (prev_widget, GTK_CAN_FOCUS);
|
||||
GTK_WIDGET_SET_FLAGS (next_widget, GTK_CAN_FOCUS);
|
||||
}
|
||||
else {
|
||||
if (GTK_WIDGET_HAS_FOCUS (cal) || e_calendar_button_has_focus (cal)) {
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (cal));
|
||||
if (toplevel)
|
||||
gtk_widget_grab_focus (toplevel);
|
||||
}
|
||||
GTK_WIDGET_UNSET_FLAGS (cal, GTK_CAN_FOCUS);
|
||||
GTK_WIDGET_UNSET_FLAGS (prev_widget, GTK_CAN_FOCUS);
|
||||
GTK_WIDGET_UNSET_FLAGS (next_widget, GTK_CAN_FOCUS);
|
||||
}
|
||||
}
|
||||
|
@ -93,6 +93,7 @@ void e_calendar_get_border_size (ECalendar *cal,
|
||||
gint *left,
|
||||
gint *right);
|
||||
|
||||
void e_calendar_set_focusable (ECalendar *cal, gboolean focusable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1180,6 +1180,7 @@ e_date_edit_show_date_popup (EDateEdit *dedit)
|
||||
|
||||
position_date_popup (dedit);
|
||||
gtk_widget_show (priv->cal_popup);
|
||||
gdk_keyboard_grab (priv->cal_popup->window, TRUE, GDK_CURRENT_TIME);
|
||||
gtk_widget_grab_focus (priv->cal_popup);
|
||||
gtk_grab_add (priv->cal_popup);
|
||||
gdk_pointer_grab (priv->cal_popup->window, TRUE,
|
||||
@ -1365,6 +1366,7 @@ hide_date_popup (EDateEdit *dedit)
|
||||
gtk_widget_hide (dedit->priv->cal_popup);
|
||||
gtk_grab_remove (dedit->priv->cal_popup);
|
||||
gdk_pointer_ungrab (GDK_CURRENT_TIME);
|
||||
gdk_keyboard_ungrab (GDK_CURRENT_TIME);
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user