aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gncal-full-day.c
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/gncal-full-day.c')
-rw-r--r--calendar/gncal-full-day.c157
1 files changed, 123 insertions, 34 deletions
diff --git a/calendar/gncal-full-day.c b/calendar/gncal-full-day.c
index 9a14230f92..398472a576 100644
--- a/calendar/gncal-full-day.c
+++ b/calendar/gncal-full-day.c
@@ -6,6 +6,7 @@
*/
#include <string.h>
+#include <gdk/gdkkeysyms.h>
#include <gtk/gtkdrawingarea.h>
#include <gtk/gtktext.h>
#include "gncal-full-day.h"
@@ -47,10 +48,20 @@ struct drag_info {
Child *child;
int start_row;
int rows_used;
+
+ int sel_click_row;
+ int sel_start_row;
+ int sel_rows_used;
guint32 click_time;
};
+enum {
+ RANGE_ACTIVATED,
+ LAST_SIGNAL
+};
+
+
static void gncal_full_day_class_init (GncalFullDayClass *class);
static void gncal_full_day_init (GncalFullDay *fullday);
static void gncal_full_day_destroy (GtkObject *object);
@@ -73,6 +84,8 @@ static gint gncal_full_day_motion (GtkWidget *widget,
GdkEventMotion *event);
static gint gncal_full_day_expose (GtkWidget *widget,
GdkEventExpose *event);
+static gint gncal_full_day_key_press (GtkWidget *widget,
+ GdkEventKey *event);
static gint gncal_full_day_focus_in (GtkWidget *widget,
GdkEventFocus *event);
static gint gncal_full_day_focus_out (GtkWidget *widget,
@@ -81,9 +94,13 @@ static void gncal_full_day_foreach (GtkContainer *container,
GtkCallback callback,
gpointer callback_data);
+static void range_activated (GncalFullDay *fullday);
+
static GtkContainerClass *parent_class;
+static fullday_signals[LAST_SIGNAL] = { 0 };
+
static void
get_tm_range (GncalFullDay *fullday,
@@ -186,7 +203,8 @@ child_realize (GncalFullDay *fullday, Child *child)
| GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK
| GDK_BUTTON_MOTION_MASK
- | GDK_POINTER_MOTION_HINT_MASK);
+ | GDK_POINTER_MOTION_HINT_MASK
+ | GDK_KEY_PRESS_MASK);
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_CURSOR;
@@ -559,6 +577,16 @@ gncal_full_day_class_init (GncalFullDayClass *class)
parent_class = gtk_type_class (gtk_container_get_type ());
+ fullday_signals[RANGE_ACTIVATED] =
+ gtk_signal_new ("range_activated",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GncalFullDayClass, range_activated),
+ gtk_signal_default_marshaller,
+ GTK_TYPE_NONE, 0);
+
+ gtk_object_class_add_signals (object_class, fullday_signals, LAST_SIGNAL);
+
object_class->destroy = gncal_full_day_destroy;
widget_class->map = gncal_full_day_map;
@@ -573,10 +601,13 @@ gncal_full_day_class_init (GncalFullDayClass *class)
widget_class->button_release_event = gncal_full_day_button_release;
widget_class->motion_notify_event = gncal_full_day_motion;
widget_class->expose_event = gncal_full_day_expose;
+ widget_class->key_press_event = gncal_full_day_key_press;
widget_class->focus_in_event = gncal_full_day_focus_in;
widget_class->focus_out_event = gncal_full_day_focus_out;
container_class->foreach = gncal_full_day_foreach;
+
+ class->range_activated = range_activated;
}
static void
@@ -807,11 +838,11 @@ paint_back (GncalFullDay *fullday, GdkRectangle *area)
row_height = calc_row_height (fullday);
- if (di->rows_used != 0) {
+ if (di->sel_rows_used != 0) {
rect.x = x1;
- rect.y = y1 + row_height * di->start_row;
+ rect.y = y1 + row_height * di->sel_start_row;
rect.width = width;
- rect.height = row_height * di->rows_used;
+ rect.height = row_height * di->sel_rows_used;
if (gdk_rectangle_intersect (&rect, area, &dest))
gdk_draw_rectangle (widget->window,
@@ -1093,8 +1124,9 @@ gncal_full_day_button_press (GtkWidget *widget, GdkEventButton *event)
di->drag_mode = DRAG_SELECT;
- di->start_row = get_row_from_y (fullday, event->y, FALSE);
- di->rows_used = 1;
+ di->sel_click_row = get_row_from_y (fullday, event->y, FALSE);
+ di->sel_start_row = di->sel_click_row;
+ di->sel_rows_used = 1;
di->click_time = event->time;
@@ -1165,11 +1197,13 @@ recompute_motion (GncalFullDay *fullday, int y)
if (row >= f_rows)
row = f_rows - 1;
- if (row < di->start_row) {
- di->rows_used = di->start_row - row + 1;
- di->start_row = row;
- } else
- di->rows_used = row - di->start_row + 1;
+ if (row < di->sel_click_row) {
+ di->sel_start_row = row;
+ di->sel_rows_used = di->sel_click_row - row + 1;
+ } else {
+ di->sel_start_row = di->sel_click_row;
+ di->sel_rows_used = row - di->sel_start_row + 1;
+ }
break;
@@ -1201,26 +1235,35 @@ recompute_motion (GncalFullDay *fullday, int y)
}
static void
-update_from_drag_info (GncalFullDay *fullday)
+get_time_from_rows (GncalFullDay *fullday, int start_row, int rows_used, time_t *t_lower, time_t *t_upper)
{
- struct drag_info *di;
- GtkWidget *widget;
struct tm tm;
int row_height;
- di = fullday->drag_info;
-
- widget = GTK_WIDGET (fullday);
-
get_tm_range (fullday, fullday->lower, fullday->upper, &tm, NULL, NULL, NULL);
row_height = calc_row_height (fullday);
- tm.tm_min += fullday->interval * di->start_row;
- di->child->ico->dtstart = mktime (&tm);
+ tm.tm_min += fullday->interval * start_row;
+ *t_lower = mktime (&tm);
- tm.tm_min += fullday->interval * di->rows_used;
- di->child->ico->dtend = mktime (&tm);
+ tm.tm_min += fullday->interval * rows_used;
+ *t_upper = mktime (&tm);
+}
+
+static void
+update_from_drag_info (GncalFullDay *fullday)
+{
+ struct drag_info *di;
+ GtkWidget *widget;
+
+ di = fullday->drag_info;
+
+ widget = GTK_WIDGET (fullday);
+
+ get_time_from_rows (fullday, di->start_row, di->rows_used,
+ &di->child->ico->dtstart,
+ &di->child->ico->dtend);
child_range_changed (fullday, di->child);
@@ -1252,7 +1295,7 @@ gncal_full_day_button_release (GtkWidget *widget, GdkEventButton *event)
case DRAG_SELECT:
if ((event->time - di->click_time) < UNSELECT_TIMEOUT)
- di->rows_used = 0;
+ di->sel_rows_used = 0;
else
recompute_motion (fullday, y);
@@ -1278,9 +1321,6 @@ gncal_full_day_button_release (GtkWidget *widget, GdkEventButton *event)
g_assert_not_reached ();
}
- if (!di->child || (event->window != di->child->window))
- return FALSE;
-
di->drag_mode = DRAG_NONE;
di->child = NULL;
@@ -1360,6 +1400,31 @@ gncal_full_day_expose (GtkWidget *widget, GdkEventExpose *event)
}
static gint
+gncal_full_day_key_press (GtkWidget *widget, GdkEventKey *event)
+{
+ GncalFullDay *fullday;
+ struct drag_info *di;
+
+ g_return_val_if_fail (widget != NULL, FALSE);
+ g_return_val_if_fail (GNCAL_IS_FULL_DAY (widget), FALSE);
+ g_return_val_if_fail (event != NULL, FALSE);
+
+ fullday = GNCAL_FULL_DAY (widget);
+
+ di = fullday->drag_info;
+
+ if (di->sel_rows_used == 0)
+ return FALSE;
+
+ if (event->keyval == GDK_Return) {
+ gtk_signal_emit (GTK_OBJECT (fullday), fullday_signals [RANGE_ACTIVATED]);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gint
gncal_full_day_focus_in (GtkWidget *widget, GdkEventFocus *event)
{
g_return_val_if_fail (widget != NULL, FALSE);
@@ -1470,20 +1535,44 @@ gncal_full_day_set_bounds (GncalFullDay *fullday, time_t lower, time_t upper)
}
}
-/*
- * Returns the selected range
- */
int
gncal_full_day_selection_range (GncalFullDay *fullday, time_t *lower, time_t *upper)
{
struct drag_info *di;
+ time_t alower, aupper;
+
+ g_return_val_if_fail (fullday != NULL, FALSE);
+ g_return_val_if_fail (GNCAL_IS_FULL_DAY (fullday), FALSE);
+
+ di = fullday->drag_info;
+
+ if (di->sel_rows_used == 0)
+ return FALSE;
+
+ get_time_from_rows (fullday, di->sel_start_row, di->sel_rows_used, &alower, &aupper);
+
+ if (lower)
+ *lower = alower;
+
+ if (upper)
+ *upper= aupper;
+
+ return TRUE;
+}
+
+static void
+range_activated (GncalFullDay *fullday)
+{
+ struct drag_info *di;
- g_return_val_if_fail (fullday != NULL, 0);
- g_return_val_if_fail (GNCAL_IS_FULL_DAY (fullday), 0);
- g_return_val_if_fail (lower != NULL, 0);
- g_return_val_if_fail (upper != NULL, 0);
+ g_return_if_fail (fullday != NULL);
+ g_return_if_fail (GNCAL_IS_FULL_DAY (fullday));
di = fullday->drag_info;
- return 1;
+ /* Remove selection; at this point someone should already have added an appointment */
+
+ di->sel_rows_used = 0;
+
+ paint_back (fullday, NULL);
}