aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/gui')
-rw-r--r--calendar/gui/e-day-view.c236
1 files changed, 232 insertions, 4 deletions
diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c
index 004904ea0d..a442c8b2b8 100644
--- a/calendar/gui/e-day-view.c
+++ b/calendar/gui/e-day-view.c
@@ -146,6 +146,21 @@ static gint e_day_view_focus_out (GtkWidget *widget,
GdkEventFocus *event);
static gboolean e_day_view_key_press (GtkWidget *widget,
GdkEventKey *event);
+static gboolean e_day_view_focus (GtkWidget *widget,
+ GtkDirectionType direction);
+static gboolean e_day_view_get_next_tab_event (EDayView *day_view,
+ GtkDirectionType direction,
+ gint *day, gint *event_num);
+static gboolean e_day_view_get_extreme_long_event (EDayView *day_view,
+ gboolean first,
+ gint *day_out,
+ gint *event_num_out);
+static gboolean e_day_view_get_extreme_event (EDayView *day_view,
+ gint start_day,
+ gint end_day,
+ gboolean first,
+ gint *day_out,
+ gint *event_num_out);
static gboolean e_day_view_do_key_press (GtkWidget *widget,
GdkEventKey *event);
static gboolean e_day_view_popup_menu (GtkWidget *widget);
@@ -514,6 +529,7 @@ e_day_view_class_init (EDayViewClass *class)
widget_class->focus_in_event = e_day_view_focus_in;
widget_class->focus_out_event = e_day_view_focus_out;
widget_class->key_press_event = e_day_view_key_press;
+ widget_class->focus = e_day_view_focus;
widget_class->popup_menu = e_day_view_popup_menu;
class->selection_changed = NULL;
@@ -5808,6 +5824,196 @@ e_day_view_cursor_key_up_shifted (EDayView *day_view, GdkEventKey *event)
gtk_widget_queue_draw (day_view->main_canvas);
}
+static gboolean
+e_day_view_focus (GtkWidget *widget, GtkDirectionType direction)
+{
+ EDayView *day_view;
+ gint new_day;
+ gint new_event_num;
+ gint start_row, end_row;
+
+ g_return_val_if_fail (widget != NULL, FALSE);
+ g_return_val_if_fail (E_IS_DAY_VIEW (widget), FALSE);
+ day_view = E_DAY_VIEW (widget);
+
+ if (!e_day_view_get_next_tab_event (day_view, direction,
+ &new_day, &new_event_num))
+ return FALSE;
+
+ if (new_day != E_DAY_VIEW_LONG_EVENT && new_day != -1) {
+ if (e_day_view_get_event_rows (day_view, new_day, new_event_num,
+ &start_row, &end_row))
+ /* ajust the scrollbar to ensure the event to be seen */
+ e_day_view_ensure_rows_visible (day_view,
+ start_row, end_row);
+ }
+ e_day_view_start_editing_event (day_view, new_day,
+ new_event_num, NULL);
+
+ return TRUE;
+}
+
+static gboolean
+e_day_view_get_extreme_event (EDayView *day_view, gint start_day,
+ gint end_day, gboolean first,
+ gint *day_out, gint *event_num_out)
+{
+ gint loop_day;
+
+ g_return_val_if_fail (day_view != NULL, FALSE);
+ g_return_val_if_fail (start_day >= 0, FALSE);
+ g_return_val_if_fail (end_day <= E_DAY_VIEW_LONG_EVENT, FALSE);
+ g_return_val_if_fail (day_out && event_num_out, FALSE);
+
+ if (start_day > end_day)
+ return FALSE;
+ if (first) {
+ for (loop_day = start_day; loop_day <= end_day; ++loop_day)
+ if (day_view->events[loop_day]->len > 0) {
+ *day_out = loop_day;
+ *event_num_out = 0;
+ return TRUE;
+ }
+ }
+ else {
+ for (loop_day = end_day; loop_day >= start_day; --loop_day)
+ if (day_view->events[loop_day]->len > 0) {
+ *day_out = loop_day;
+ *event_num_out =
+ day_view->events[loop_day]->len - 1;
+ return TRUE;
+ }
+ }
+ *day_out = -1;
+ *event_num_out = -1;
+ return FALSE;
+}
+
+static gboolean
+e_day_view_get_extreme_long_event (EDayView *day_view, gboolean first,
+ gint *day_out, gint *event_num_out)
+{
+ g_return_val_if_fail (day_view != NULL, FALSE);
+ g_return_val_if_fail (day_out && event_num_out, FALSE);
+
+ if (first && (day_view->long_events->len > 0)) {
+ *day_out = E_DAY_VIEW_LONG_EVENT;
+ *event_num_out = 0;
+ return TRUE;
+ }
+ if ((!first) && (day_view->long_events->len > 0)) {
+ *day_out = E_DAY_VIEW_LONG_EVENT;
+ *event_num_out = day_view->long_events->len - 1;
+ return TRUE;
+ }
+ *day_out = -1;
+ *event_num_out = -1;
+ return FALSE;
+}
+
+static gboolean
+e_day_view_get_next_tab_event (EDayView *day_view, GtkDirectionType direction,
+ gint *day_out, gint *event_num_out)
+{
+ gint new_day;
+ gint new_event_num;
+ gint days_shown;
+
+ g_return_val_if_fail (day_view != NULL, FALSE);
+ g_return_val_if_fail (day_out != NULL, FALSE);
+ g_return_val_if_fail (event_num_out != NULL, FALSE);
+
+ days_shown = e_day_view_get_days_shown(day_view);
+ *day_out = -1;
+ *event_num_out = -1;
+
+ g_return_val_if_fail (days_shown > 0, FALSE);
+
+ switch (direction) {
+ case GTK_DIR_TAB_BACKWARD:
+ new_event_num = day_view->editing_event_num - 1;
+ break;
+ case GTK_DIR_TAB_FORWARD:
+ new_event_num = day_view->editing_event_num + 1;
+ break;
+ default:
+ return FALSE;
+ }
+
+ new_day = day_view->editing_event_day;
+
+ /* not current editing event, set to first long event if there is one
+ */
+ if (new_day == -1) {
+ if (e_day_view_get_extreme_long_event (day_view, TRUE,
+ day_out, event_num_out))
+ return TRUE;
+
+ /* no long event, set to first normal event if there is one
+ */
+ return e_day_view_get_extreme_event (day_view, 0,
+ days_shown - 1, TRUE,
+ day_out, event_num_out);
+ }
+ /* go backward from the first long event */
+ else if ((new_day == E_DAY_VIEW_LONG_EVENT) && (new_event_num < 0)) {
+ if (e_day_view_get_extreme_event (day_view, 0,
+ days_shown - 1, FALSE,
+ day_out, event_num_out))
+ return TRUE;
+ return e_day_view_get_extreme_long_event (day_view, FALSE,
+ day_out,
+ event_num_out);
+ }
+ /* go forward from the last long event */
+ else if ((new_day == E_DAY_VIEW_LONG_EVENT) &&
+ (new_event_num >= day_view->long_events->len)) {
+ if (e_day_view_get_extreme_event (day_view, 0,
+ days_shown - 1, TRUE,
+ day_out, event_num_out))
+ return TRUE;
+ return e_day_view_get_extreme_long_event (day_view, TRUE,
+ day_out,
+ event_num_out);
+ }
+
+ /* go backward from the first event in current editting day */
+ else if ((new_day < E_DAY_VIEW_LONG_EVENT) && (new_event_num < 0)) {
+ /* try to find a event from the previous day in days shown
+ */
+ if (e_day_view_get_extreme_event (day_view, 0,
+ new_day - 1, FALSE,
+ day_out, event_num_out))
+ return TRUE;
+ else if (e_day_view_get_extreme_long_event (day_view, FALSE,
+ day_out,
+ event_num_out))
+ return TRUE;
+ return e_day_view_get_extreme_event (day_view, new_day,
+ days_shown - 1, FALSE,
+ day_out, event_num_out);
+ }
+ /* go forward from the last event in current editting day */
+ else if ((new_day < E_DAY_VIEW_LONG_EVENT) &&
+ (new_event_num >= day_view->events[new_day]->len)) {
+ /* try to find a event from the next day in days shown
+ */
+ if (e_day_view_get_extreme_event (day_view, (new_day + 1),
+ days_shown - 1, TRUE,
+ day_out, event_num_out))
+ return TRUE;
+ else if (e_day_view_get_extreme_long_event (day_view, TRUE,
+ day_out,
+ event_num_out))
+ return TRUE;
+ return e_day_view_get_extreme_event (day_view, 0,
+ new_day, TRUE,
+ day_out, event_num_out);
+ }
+ *day_out = new_day;
+ *event_num_out = new_event_num;
+ return TRUE;
+}
static void
e_day_view_cursor_key_down_shifted (EDayView *day_view, GdkEventKey *event)
@@ -6571,6 +6777,31 @@ e_day_view_auto_scroll_handler (gpointer data)
return TRUE;
}
+gboolean
+e_day_view_get_event_rows (EDayView *day_view,
+ gint day,
+ gint event_num,
+ gint *start_row_out,
+ gint *end_row_out)
+{
+ gint start_row, end_row;
+ EDayViewEvent *event;
+
+ g_return_val_if_fail (day >= 0, FALSE);
+ g_return_val_if_fail (day < E_DAY_VIEW_LONG_EVENT, FALSE);
+ g_return_val_if_fail (event_num >= 0, FALSE);
+
+ event = &g_array_index (day_view->events[day], EDayViewEvent,
+ event_num);
+ start_row = event->start_minute / day_view->mins_per_row;
+ end_row = (event->end_minute - 1) / day_view->mins_per_row;
+ if (end_row < start_row)
+ end_row = start_row;
+
+ *start_row_out = start_row;
+ *end_row_out = end_row;
+ return TRUE;
+}
gboolean
e_day_view_get_event_position (EDayView *day_view,
@@ -6591,10 +6822,7 @@ e_day_view_get_event_position (EDayView *day_view,
if (event->num_columns == 0)
return FALSE;
- start_row = event->start_minute / day_view->mins_per_row;
- end_row = (event->end_minute - 1) / day_view->mins_per_row;
- if (end_row < start_row)
- end_row = start_row;
+ e_day_view_get_event_rows(day_view, day, event_num, &start_row, &end_row);
cols_in_row = day_view->cols_per_row[day][start_row];
start_col = event->start_row_or_col;