aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/meeting-time-sel
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/meeting-time-sel')
-rw-r--r--widgets/meeting-time-sel/Makefile.am7
-rw-r--r--widgets/meeting-time-sel/e-meeting-time-sel-item.c76
-rw-r--r--widgets/meeting-time-sel/e-meeting-time-sel-item.h1
-rw-r--r--widgets/meeting-time-sel/e-meeting-time-sel-list-item.c99
-rw-r--r--widgets/meeting-time-sel/e-meeting-time-sel-list-item.h3
-rw-r--r--widgets/meeting-time-sel/e-meeting-time-sel.c307
-rw-r--r--widgets/meeting-time-sel/e-meeting-time-sel.h22
-rw-r--r--widgets/meeting-time-sel/test-meeting-time-sel.c6
8 files changed, 450 insertions, 71 deletions
diff --git a/widgets/meeting-time-sel/Makefile.am b/widgets/meeting-time-sel/Makefile.am
index fcf735c9bc..013006aaed 100644
--- a/widgets/meeting-time-sel/Makefile.am
+++ b/widgets/meeting-time-sel/Makefile.am
@@ -20,8 +20,11 @@ noinst_PROGRAMS = \
test_meeting_time_selector_SOURCES = \
test-meeting-time-sel.c
-test_meeting_time_selector_LDADD = \
- libevolutionmtsel.a $(GNOMEUI_LIBS)
+test_meeting_time_selector_LDADD = \
+ libevolutionmtsel.a \
+ $(top_builddir)/widgets/e-text/libetext.a \
+ $(top_builddir)/e-util/libeutil.la \
+ $(GNOMEUI_LIBS)
test_meeting_time_selector_LDFLAGS = $(GNOME_LIBDIR)
diff --git a/widgets/meeting-time-sel/e-meeting-time-sel-item.c b/widgets/meeting-time-sel/e-meeting-time-sel-item.c
index cb716d6f08..54cde8d319 100644
--- a/widgets/meeting-time-sel/e-meeting-time-sel-item.c
+++ b/widgets/meeting-time-sel/e-meeting-time-sel-item.c
@@ -84,6 +84,12 @@ static gint e_meeting_time_selector_item_find_first_busy_period (EMeetingTimeSel
static void e_meeting_time_selector_item_paint_attendee_busy_periods (EMeetingTimeSelectorItem *mts_item, GdkDrawable *drawable, int row, int x, int y, int width, int first_period, EMeetingTimeSelectorBusyType busy_type);
static EMeetingTimeSelectorPosition e_meeting_time_selector_item_get_drag_position (EMeetingTimeSelectorItem *mts_item, gint x, gint y);
+static gboolean e_meeting_time_selector_item_calculate_busy_range (EMeetingTimeSelector *mts,
+ gint row,
+ gint x,
+ gint width,
+ gint *start_x,
+ gint *end_x);
static GnomeCanvasItemClass *parent_class;
@@ -154,6 +160,7 @@ e_meeting_time_selector_item_init (EMeetingTimeSelectorItem *mts_item)
mts_item->mts = NULL;
mts_item->main_gc = NULL;
+ mts_item->stipple_gc = NULL;
/* Create the cursors. */
mts_item->normal_cursor = gdk_cursor_new (GDK_TOP_LEFT_ARROW);
@@ -215,6 +222,7 @@ e_meeting_time_selector_item_realize (GnomeCanvasItem *item)
window = GTK_WIDGET (canvas)->window;
mts_item->main_gc = gdk_gc_new (window);
+ mts_item->stipple_gc = gdk_gc_new (window);
}
@@ -227,6 +235,8 @@ e_meeting_time_selector_item_unrealize (GnomeCanvasItem *item)
gdk_gc_unref (mts_item->main_gc);
mts_item->main_gc = NULL;
+ gdk_gc_unref (mts_item->stipple_gc);
+ mts_item->stipple_gc = NULL;
if (GNOME_CANVAS_ITEM_CLASS (parent_class)->unrealize)
(*GNOME_CANVAS_ITEM_CLASS (parent_class)->unrealize)(item);
@@ -258,15 +268,16 @@ e_meeting_time_selector_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
EMeetingTimeSelectorItem *mts_item;
EMeetingTimeSelectorAttendee *attendee;
gint day_x, meeting_start_x, meeting_end_x, bar_y, bar_height;
- gint row, row_y;
+ gint row, row_y, start_x, end_x;
GDate date, last_date, current_date;
gboolean is_display_top, show_meeting_time;
- GdkGC *gc;
+ GdkGC *gc, *stipple_gc;
mts_item = E_MEETING_TIME_SELECTOR_ITEM (item);
mts = mts_item->mts;
g_return_if_fail (mts != NULL);
gc = mts_item->main_gc;
+ stipple_gc = mts_item->stipple_gc;
is_display_top = (GTK_WIDGET (item->canvas) == mts->display_top)
? TRUE : FALSE;
@@ -299,7 +310,7 @@ e_meeting_time_selector_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
if (is_display_top)
gdk_draw_rectangle (drawable, gc, TRUE,
meeting_start_x + 1 - x, mts->row_height * 2 - y,
- meeting_end_x - meeting_start_x - 2, height);
+ meeting_end_x - meeting_start_x - 2, mts->row_height);
else
gdk_draw_rectangle (drawable, gc, TRUE,
meeting_start_x + 1 - x, 0,
@@ -310,17 +321,33 @@ e_meeting_time_selector_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
that have no calendar information. */
if (!is_display_top) {
gdk_gc_set_foreground (gc, &mts->grid_color);
- gdk_gc_set_background (gc, &mts->stipple_bg_color);
- gdk_gc_set_stipple (gc, mts->stipple);
- gnome_canvas_set_stipple_origin (item->canvas, gc);
- gdk_gc_set_fill (gc, GDK_OPAQUE_STIPPLED);
+ gdk_gc_set_foreground (stipple_gc, &mts->grid_color);
+ gdk_gc_set_background (stipple_gc, &mts->stipple_bg_color);
+ gdk_gc_set_stipple (stipple_gc, mts->stipple);
+ gnome_canvas_set_stipple_origin (item->canvas, stipple_gc);
+ gdk_gc_set_fill (stipple_gc, GDK_OPAQUE_STIPPLED);
row = y / mts->row_height;
row_y = row * mts->row_height - y;
while (row < mts->attendees->len && row_y < height) {
attendee = &g_array_index (mts->attendees,
EMeetingTimeSelectorAttendee, row);
- if (!attendee->has_calendar_info) {
- gdk_draw_rectangle (drawable, gc, TRUE,
+ if (attendee->has_calendar_info) {
+ if (e_meeting_time_selector_item_calculate_busy_range (mts, row, x, width, &start_x, &end_x)) {
+ if (start_x >= width || end_x <= 0) {
+ gdk_draw_rectangle (drawable, stipple_gc, TRUE, 0, row_y, width, mts->row_height);
+ } else {
+ if (start_x >= 0) {
+ gdk_draw_rectangle (drawable, stipple_gc, TRUE, 0, row_y, start_x, mts->row_height);
+ gdk_draw_line (drawable, gc, start_x, row_y, start_x, row_y + mts->row_height);
+ }
+ if (end_x <= width) {
+ gdk_draw_rectangle (drawable, stipple_gc, TRUE, end_x, row_y, width - end_x, mts->row_height);
+ gdk_draw_line (drawable, gc, end_x, row_y, end_x, row_y + mts->row_height);
+ }
+ }
+ }
+ } else {
+ gdk_draw_rectangle (drawable, stipple_gc, TRUE,
0, row_y,
width, mts->row_height);
}
@@ -419,7 +446,7 @@ e_meeting_time_selector_item_paint_day_top (EMeetingTimeSelectorItem *mts_item,
grid_x < mts->day_width - mts->col_width;
grid_x += mts->col_width) {
gdk_draw_line (drawable, gc,
- x + grid_x, mts->row_height * 2 - 4,
+ x + grid_x, mts->row_height * 2 - 4 - scroll_y,
x + grid_x, height);
}
grid_x = mts->day_width - 2;
@@ -525,7 +552,7 @@ e_meeting_time_selector_item_paint_day (EMeetingTimeSelectorItem *mts_item,
grid_y < height;
grid_y += mts->row_height)
{
- if (attendee_index < mts->attendees->len) {
+ if (attendee_index <= mts->attendees->len) {
gdk_gc_set_foreground (gc, &mts->grid_color);
gdk_draw_line (drawable, gc, 0, grid_y,
width, grid_y);
@@ -922,3 +949,30 @@ e_meeting_time_selector_item_get_drag_position (EMeetingTimeSelectorItem *mts_it
return E_MEETING_TIME_SELECTOR_POS_NONE;
}
+
+static gboolean
+e_meeting_time_selector_item_calculate_busy_range (EMeetingTimeSelector *mts,
+ gint row,
+ gint x,
+ gint width,
+ gint *start_x,
+ gint *end_x)
+{
+ EMeetingTimeSelectorAttendee *attendee;
+
+ attendee = &g_array_index (mts->attendees,
+ EMeetingTimeSelectorAttendee, row);
+
+ *start_x = -1;
+ *end_x = -1;
+
+ if (!g_date_valid (&attendee->busy_periods_start.date)
+ || !g_date_valid (&attendee->busy_periods_end.date))
+ return FALSE;
+
+ *start_x = e_meeting_time_selector_calculate_time_position (mts, &attendee->busy_periods_start) - x - 1;
+
+ *end_x = e_meeting_time_selector_calculate_time_position (mts, &attendee->busy_periods_end) - x;
+
+ return TRUE;
+}
diff --git a/widgets/meeting-time-sel/e-meeting-time-sel-item.h b/widgets/meeting-time-sel/e-meeting-time-sel-item.h
index c2bd2872ce..d9fe6c6a9b 100644
--- a/widgets/meeting-time-sel/e-meeting-time-sel-item.h
+++ b/widgets/meeting-time-sel/e-meeting-time-sel-item.h
@@ -57,6 +57,7 @@ struct _EMeetingTimeSelectorItem
/* This GC is used for most of the drawing. The fg/bg colors are
changed for each bit. */
GdkGC *main_gc;
+ GdkGC *stipple_gc;
/* The normal & resize cursors. */
GdkCursor *normal_cursor;
diff --git a/widgets/meeting-time-sel/e-meeting-time-sel-list-item.c b/widgets/meeting-time-sel/e-meeting-time-sel-list-item.c
index ac4b7b9009..f9a05a29a7 100644
--- a/widgets/meeting-time-sel/e-meeting-time-sel-list-item.c
+++ b/widgets/meeting-time-sel/e-meeting-time-sel-list-item.c
@@ -25,12 +25,12 @@
/*
* EMeetingTimeSelectorListItem - A GnomeCanvasItem covering the entire attendee
* list. It just draws the grid lines between the rows and after the icon
- * column. It probably won't be needed when we switch to Miguel's new editable
- * GtkList-like widget.
+ * column.
*/
#include <config.h>
#include <time.h>
+#include "../../e-util/e-canvas.h"
#include "e-meeting-time-sel-list-item.h"
#include "e-meeting-time-sel.h"
@@ -60,6 +60,10 @@ static double e_meeting_time_selector_list_item_point (GnomeCanvasItem *item,
double x, double y,
int cx, int cy,
GnomeCanvasItem **actual_item);
+static gint e_meeting_time_selector_list_item_event (GnomeCanvasItem *item,
+ GdkEvent *event);
+static gboolean e_meeting_time_selector_list_item_button_press (EMeetingTimeSelectorListItem *mtsl_item,
+ GdkEvent *event);
static GnomeCanvasItemClass *e_meeting_time_selector_list_item_parent_class;
@@ -119,9 +123,7 @@ e_meeting_time_selector_list_item_class_init (EMeetingTimeSelectorListItemClass
item_class->update = e_meeting_time_selector_list_item_update;
item_class->draw = e_meeting_time_selector_list_item_draw;
item_class->point = e_meeting_time_selector_list_item_point;
-#if 0
item_class->event = e_meeting_time_selector_list_item_event;
-#endif
}
@@ -237,6 +239,7 @@ e_meeting_time_selector_list_item_draw (GnomeCanvasItem *item, GdkDrawable *draw
EMeetingTimeSelector *mts;
EMeetingTimeSelectorAttendee *attendee;
GdkGC *gc;
+ GdkFont *font;
gint row, row_y, icon_x, icon_y;
GdkPixmap *pixmap;
GdkBitmap *mask;
@@ -286,6 +289,18 @@ e_meeting_time_selector_list_item_draw (GnomeCanvasItem *item, GdkDrawable *draw
icon_y += mts->row_height;
}
gdk_gc_set_clip_mask (gc, NULL);
+
+ /* Draw 'Click here to add attendee' on the last dummy row. */
+ row_y = mts->attendees->len * mts->row_height;
+
+ font = GTK_WIDGET (mts)->style->font;
+ gdk_gc_set_foreground (gc, &mts->grid_unused_color);
+ gdk_draw_string (drawable, font, gc,
+ E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH
+ + E_MEETING_TIME_SELECTOR_TEXT_X_PAD - x,
+ row_y + E_MEETING_TIME_SELECTOR_TEXT_Y_PAD
+ + font->ascent + 1 - y,
+ "Click here to add attendee");
}
@@ -301,3 +316,79 @@ e_meeting_time_selector_list_item_point (GnomeCanvasItem *item,
*actual_item = item;
return 0.0;
}
+
+
+static gint
+e_meeting_time_selector_list_item_event (GnomeCanvasItem *item,
+ GdkEvent *event)
+{
+ EMeetingTimeSelectorListItem *mtsl_item;
+
+ mtsl_item = E_MEETING_TIME_SELECTOR_LIST_ITEM (item);
+
+ switch (event->type) {
+ case GDK_BUTTON_PRESS:
+ return e_meeting_time_selector_list_item_button_press (mtsl_item, event);
+ case GDK_BUTTON_RELEASE:
+ break;
+ case GDK_MOTION_NOTIFY:
+ break;
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+
+static gboolean
+e_meeting_time_selector_list_item_button_press (EMeetingTimeSelectorListItem *mtsl_item,
+ GdkEvent *event)
+{
+ EMeetingTimeSelector *mts;
+ EMeetingTimeSelectorAttendee *attendee;
+ gint row;
+ gboolean return_val;
+ GtkAdjustment *adjustment;
+
+ mts = mtsl_item->mts;
+ row = event->button.y / mts->row_height;
+
+ g_print ("In e_meeting_time_selector_list_item_button_press: %g,%g row:%i\n",
+ event->button.x, event->button.y, row);
+
+ if (event->button.x >= E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH) {
+ if (row < mts->attendees->len) {
+ attendee = &g_array_index (mts->attendees, EMeetingTimeSelectorAttendee, row);
+ gtk_signal_emit_by_name (GTK_OBJECT (attendee->text_item),
+ "event", event, &return_val);
+ return return_val;
+ } else {
+ row = e_meeting_time_selector_attendee_add (mts, "",
+ NULL);
+
+ /* Scroll down to show the last line.?? */
+#if 0
+ adjustment = GTK_LAYOUT (mts->display_main)->vadjustment;
+ adjustment->value = adjustment->upper - adjustment->page_size;
+ gtk_adjustment_value_changed (adjustment);
+#endif
+
+ attendee = &g_array_index (mts->attendees, EMeetingTimeSelectorAttendee, row);
+ e_canvas_item_grab_focus (attendee->text_item);
+ return TRUE;
+ }
+ } else {
+ attendee = &g_array_index (mts->attendees,
+ EMeetingTimeSelectorAttendee, row);
+
+ attendee->send_meeting_to = !attendee->send_meeting_to;
+
+ gnome_canvas_request_redraw (GNOME_CANVAS_ITEM (mtsl_item)->canvas,
+ 0, row * mts->row_height,
+ E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH,
+ (row + 1) * mts->row_height);
+ return TRUE;
+ }
+}
+
diff --git a/widgets/meeting-time-sel/e-meeting-time-sel-list-item.h b/widgets/meeting-time-sel/e-meeting-time-sel-list-item.h
index 9ef295ebb2..07df052c08 100644
--- a/widgets/meeting-time-sel/e-meeting-time-sel-list-item.h
+++ b/widgets/meeting-time-sel/e-meeting-time-sel-list-item.h
@@ -25,8 +25,7 @@
/*
* MeetingTimeSelectorListItem - A GnomeCanvasItem covering the entire attendee
* list. It just draws the grid lines between the rows and after the icon
- * column. It probably won't be needed when we switch to Miguel's new editable
- * GtkList-like widget.
+ * column.
*/
#ifndef _E_MEETING_TIME_SELECTOR_LIST_ITEM_H_
diff --git a/widgets/meeting-time-sel/e-meeting-time-sel.c b/widgets/meeting-time-sel/e-meeting-time-sel.c
index 86f81cc80e..0b6fd5c294 100644
--- a/widgets/meeting-time-sel/e-meeting-time-sel.c
+++ b/widgets/meeting-time-sel/e-meeting-time-sel.c
@@ -45,6 +45,7 @@
#include <libgnome/gnome-i18n.h>
#include <libgnomeui/gnome-canvas-widget.h>
+#include "../../e-util/e-canvas.h"
#include "e-meeting-time-sel.h"
#include "e-meeting-time-sel-item.h"
#include "e-meeting-time-sel-list-item.h"
@@ -59,8 +60,6 @@ const gchar *EMeetingTimeSelectorHours[24] = {
/* The number of days shown in the entire canvas. */
#define E_MEETING_TIME_SELECTOR_DAYS_SHOWN 365
-#define E_MEETING_TIME_SELECTOR_ENTRY_INNER_BORDER 2
-
/* This is the number of pixels between the mouse has to move before the
scroll speed is incremented. */
#define E_MEETING_TIME_SELECTOR_SCROLL_INCREMENT_WIDTH 10
@@ -94,6 +93,9 @@ static void e_meeting_time_selector_style_set (GtkWidget *widget,
GtkStyle *previous_style);
static gint e_meeting_time_selector_expose_event (GtkWidget *widget,
GdkEventExpose *event);
+static void e_meeting_time_selector_draw (GtkWidget *widget,
+ GdkRectangle *area);
+static void e_meeting_time_selector_draw_shadow (EMeetingTimeSelector *mts);
static void e_meeting_time_selector_hadjustment_changed (GtkAdjustment *adjustment,
EMeetingTimeSelector *mts);
static void e_meeting_time_selector_vadjustment_changed (GtkAdjustment *adjustment,
@@ -185,8 +187,13 @@ static void e_meeting_time_selector_ensure_meeting_time_shown (EMeetingTimeSelec
static void e_meeting_time_selector_update_dates_shown (EMeetingTimeSelector *mts);
static void e_meeting_time_selector_update_attendees_list_positions (EMeetingTimeSelector *mts);
+static gboolean e_meeting_time_selector_on_text_item_event (GnomeCanvasItem *item,
+ GdkEvent *event,
+ EMeetingTimeSelector *mts);
+static gint e_meeting_time_selector_find_row_from_text_item (EMeetingTimeSelector *mts,
+ GnomeCanvasItem *item);
-static GtkTableClass *e_meeting_time_selector_parent_class;
+static GtkTableClass *parent_class;
GtkType
@@ -220,7 +227,7 @@ e_meeting_time_selector_class_init (EMeetingTimeSelectorClass * klass)
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
- e_meeting_time_selector_parent_class = gtk_type_class (gtk_table_get_type());
+ parent_class = gtk_type_class (gtk_table_get_type());
object_class = (GtkObjectClass *) klass;
widget_class = (GtkWidgetClass *) klass;
@@ -231,6 +238,7 @@ e_meeting_time_selector_class_init (EMeetingTimeSelectorClass * klass)
widget_class->unrealize = e_meeting_time_selector_unrealize;
widget_class->style_set = e_meeting_time_selector_style_set;
widget_class->expose_event = e_meeting_time_selector_expose_event;
+ widget_class->draw = e_meeting_time_selector_draw;
}
@@ -250,6 +258,9 @@ e_meeting_time_selector_init (EMeetingTimeSelector * mts)
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
};
+ /* The shadow is drawn in the border so it must be >= 2 pixels. */
+ gtk_container_set_border_width (GTK_CONTAINER (mts), 2);
+
mts->accel_group = gtk_accel_group_new ();
mts->attendees = g_array_new (FALSE, FALSE,
@@ -302,7 +313,7 @@ e_meeting_time_selector_init (EMeetingTimeSelector * mts)
"expose_event",
GTK_SIGNAL_FUNC (e_meeting_time_selector_expose_title_bar), mts);
- mts->attendees_list = gnome_canvas_new ();
+ mts->attendees_list = e_canvas_new ();
/* Add some horizontal padding for the shadow around the display. */
gtk_table_attach (GTK_TABLE (mts), mts->attendees_list,
0, 1, 1, 2,
@@ -659,6 +670,7 @@ e_meeting_time_selector_init (EMeetingTimeSelector * mts)
scroll the other 2 canvases. */
gtk_signal_connect (GTK_OBJECT (GTK_LAYOUT (mts->display_main)->hadjustment), "value_changed", GTK_SIGNAL_FUNC (e_meeting_time_selector_hadjustment_changed), mts);
gtk_signal_connect (GTK_OBJECT (GTK_LAYOUT (mts->display_main)->vadjustment), "value_changed", GTK_SIGNAL_FUNC (e_meeting_time_selector_vadjustment_changed), mts);
+ gtk_signal_connect (GTK_OBJECT (GTK_LAYOUT (mts->display_main)->vadjustment), "changed", GTK_SIGNAL_FUNC (e_meeting_time_selector_vadjustment_changed), mts);
e_meeting_time_selector_recalc_grid (mts);
e_meeting_time_selector_ensure_meeting_time_shown (mts);
@@ -848,8 +860,8 @@ e_meeting_time_selector_destroy (GtkObject *object)
g_array_free (mts->attendees, TRUE);
- if (GTK_OBJECT_CLASS (e_meeting_time_selector_parent_class)->destroy)
- (*GTK_OBJECT_CLASS (e_meeting_time_selector_parent_class)->destroy)(object);
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (*GTK_OBJECT_CLASS (parent_class)->destroy)(object);
}
@@ -858,8 +870,8 @@ e_meeting_time_selector_realize (GtkWidget *widget)
{
EMeetingTimeSelector *mts;
- if (GTK_WIDGET_CLASS (e_meeting_time_selector_parent_class)->realize)
- (*GTK_WIDGET_CLASS (e_meeting_time_selector_parent_class)->realize)(widget);
+ if (GTK_WIDGET_CLASS (parent_class)->realize)
+ (*GTK_WIDGET_CLASS (parent_class)->realize)(widget);
mts = E_MEETING_TIME_SELECTOR (widget);
@@ -877,8 +889,8 @@ e_meeting_time_selector_unrealize (GtkWidget *widget)
gdk_gc_unref (mts->color_key_gc);
mts->color_key_gc = NULL;
- if (GTK_WIDGET_CLASS (e_meeting_time_selector_parent_class)->unrealize)
- (*GTK_WIDGET_CLASS (e_meeting_time_selector_parent_class)->unrealize)(widget);
+ if (GTK_WIDGET_CLASS (parent_class)->unrealize)
+ (*GTK_WIDGET_CLASS (parent_class)->unrealize)(widget);
}
@@ -891,8 +903,8 @@ e_meeting_time_selector_style_set (GtkWidget *widget,
GdkFont *font;
gint hour, max_hour_width;
- if (GTK_WIDGET_CLASS (e_meeting_time_selector_parent_class)->style_set)
- (*GTK_WIDGET_CLASS (e_meeting_time_selector_parent_class)->style_set)(widget, previous_style);
+ if (GTK_WIDGET_CLASS (parent_class)->style_set)
+ (*GTK_WIDGET_CLASS (parent_class)->style_set)(widget, previous_style);
mts = E_MEETING_TIME_SELECTOR (widget);
font = widget->style->font;
@@ -904,15 +916,8 @@ e_meeting_time_selector_style_set (GtkWidget *widget,
max_hour_width = MAX (max_hour_width, mts->hour_widths[hour]);
}
- /* The row height really depends on the requested height of the
- GtkEntry widgets in the list on the left, so we really need to
- call size_request on them, AFTER their style has been set. */
- /* FIXME: This uses the default style ythickness of 2, though it won't
- be needed when we switch to Miguel's new editable GtkCList widget
- so I won't worry about it. */
mts->row_height = font->ascent + font->descent
- + E_MEETING_TIME_SELECTOR_ENTRY_INNER_BORDER * 2
- + 2 * 2;
+ + E_MEETING_TIME_SELECTOR_TEXT_Y_PAD * 2 + 1;
mts->col_width = max_hour_width + 4;
e_meeting_time_selector_save_position (mts, &saved_time);
@@ -933,17 +938,49 @@ e_meeting_time_selector_expose_event (GtkWidget *widget,
GdkEventExpose *event)
{
EMeetingTimeSelector *mts;
- gint x, y, w, h;
mts = E_MEETING_TIME_SELECTOR (widget);
+ e_meeting_time_selector_draw_shadow (mts);
+
+ if (GTK_WIDGET_CLASS (parent_class)->expose_event)
+ (*GTK_WIDGET_CLASS (parent_class)->expose_event)(widget, event);
+
+ return FALSE;
+}
+
+
+static void
+e_meeting_time_selector_draw (GtkWidget *widget,
+ GdkRectangle *area)
+{
+ EMeetingTimeSelector *mts;
+
+ mts = E_MEETING_TIME_SELECTOR (widget);
+
+ e_meeting_time_selector_draw_shadow (mts);
+
+ if (GTK_WIDGET_CLASS (parent_class)->draw)
+ (*GTK_WIDGET_CLASS (parent_class)->draw)(widget, area);
+}
+
+
+static void
+e_meeting_time_selector_draw_shadow (EMeetingTimeSelector *mts)
+{
+ GtkWidget *widget;
+ gint x, y, w, h;
+
+ widget = GTK_WIDGET (mts);
+
/* Draw the shadow around the attendees title bar and list. */
x = mts->attendees_title_bar->allocation.x - 2;
y = mts->attendees_title_bar->allocation.y - 2;
w = mts->attendees_title_bar->allocation.width + 4;
h = mts->attendees_title_bar->allocation.height + mts->attendees_list->allocation.height + 4;
- gtk_draw_shadow (widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, x, y, w, h);
+ gtk_draw_shadow (widget->style, widget->window, GTK_STATE_NORMAL,
+ GTK_SHADOW_IN, x, y, w, h);
/* Draw the shadow around the graphical displays. */
x = mts->display_top->allocation.x - 2;
@@ -951,12 +988,8 @@ e_meeting_time_selector_expose_event (GtkWidget *widget,
w = mts->display_top->allocation.width + 4;
h = mts->display_top->allocation.height + mts->display_main->allocation.height + 4;
- gtk_draw_shadow (widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, x, y, w, h);
-
- if (GTK_WIDGET_CLASS (e_meeting_time_selector_parent_class)->expose_event)
- (*GTK_WIDGET_CLASS (e_meeting_time_selector_parent_class)->expose_event)(widget, event);
-
- return FALSE;
+ gtk_draw_shadow (widget->style, widget->window, GTK_STATE_NORMAL,
+ GTK_SHADOW_IN, x, y, w, h);
}
@@ -970,7 +1003,7 @@ e_meeting_time_selector_hadjustment_changed (GtkAdjustment *adjustment,
adj = GTK_LAYOUT (mts->display_top)->hadjustment;
if (adj->value != adjustment->value) {
adj->value = adjustment->value;
- gtk_signal_emit_by_name (GTK_OBJECT (adj), "value_changed");
+ gtk_adjustment_value_changed (adj);
}
}
@@ -984,7 +1017,7 @@ e_meeting_time_selector_vadjustment_changed (GtkAdjustment *adjustment,
adj = GTK_LAYOUT (mts->attendees_list)->vadjustment;
if (adj->value != adjustment->value) {
adj->value = adjustment->value;
- gtk_signal_emit_by_name (GTK_OBJECT (adj), "value_changed");
+ gtk_adjustment_value_changed (adj);
}
}
@@ -1185,8 +1218,8 @@ e_meeting_time_selector_attendee_add (EMeetingTimeSelector *mts,
gpointer data)
{
EMeetingTimeSelectorAttendee attendee;
- GtkWidget *entry;
gint list_width, item_width;
+ GdkFont *font;
g_return_val_if_fail (IS_E_MEETING_TIME_SELECTOR (mts), -1);
g_return_val_if_fail (attendee_name != NULL, -1);
@@ -1195,6 +1228,12 @@ e_meeting_time_selector_attendee_add (EMeetingTimeSelector *mts,
attendee.type = E_MEETING_TIME_SELECTOR_REQUIRED_PERSON;
attendee.has_calendar_info = FALSE;
attendee.send_meeting_to = TRUE;
+ g_date_clear (&attendee.busy_periods_start.date, 1);
+ attendee.busy_periods_start.hour = 0;
+ attendee.busy_periods_start.minute = 0;
+ g_date_clear (&attendee.busy_periods_end.date, 1);
+ attendee.busy_periods_end.hour = 0;
+ attendee.busy_periods_end.minute = 0;
attendee.busy_periods = g_array_new (FALSE, FALSE,
sizeof (EMeetingTimeSelectorPeriod));
attendee.busy_periods_sorted = TRUE;
@@ -1202,21 +1241,32 @@ e_meeting_time_selector_attendee_add (EMeetingTimeSelector *mts,
attendee.data = data;
/* Add to the list on the left. */
- entry = gtk_entry_new ();
- gtk_entry_set_text (GTK_ENTRY (entry), attendee_name);
- gtk_widget_show (entry);
list_width = GTK_WIDGET (mts->attendees_list)->allocation.width;
- item_width = MAX (1, list_width - E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH);
- attendee.text_item = gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (mts->attendees_list)->root),
- gnome_canvas_widget_get_type (),
- "GnomeCanvasWidget::widget", entry,
- "GnomeCanvasWidget::size_pixels", TRUE,
- "GnomeCanvasWidget::x", (gdouble) E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH,
- "GnomeCanvasWidget::y", (gdouble) (mts->attendees->len * mts->row_height),
- "GnomeCanvasWidget::width", (gdouble) item_width,
- "GnomeCanvasWidget::height", (gdouble) mts->row_height,
- NULL);
+ item_width = MAX (1, list_width - E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH - E_MEETING_TIME_SELECTOR_TEXT_X_PAD * 2);
+ font = GTK_WIDGET (mts)->style->font;
+ attendee.text_item = gnome_canvas_item_new
+ (GNOME_CANVAS_GROUP (GNOME_CANVAS (mts->attendees_list)->root),
+ e_text_get_type (),
+ "font_gdk", font,
+ "anchor", GTK_ANCHOR_NW,
+ "clip", TRUE,
+ "max_lines", 1,
+ "editable", TRUE,
+ "text", attendee_name ? attendee_name : "",
+ "x", (gdouble) E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH
+ + E_MEETING_TIME_SELECTOR_TEXT_X_PAD,
+ "y", (gdouble) (mts->attendees->len * mts->row_height + 1
+ + E_MEETING_TIME_SELECTOR_TEXT_Y_PAD),
+ "clip_width", (gdouble) item_width,
+ "clip_height", (gdouble) font->ascent + font->descent,
+ NULL);
+#if 0
gnome_canvas_item_hide (attendee.text_item);
+#endif
+
+ gtk_signal_connect (GTK_OBJECT (attendee.text_item), "event",
+ GTK_SIGNAL_FUNC (e_meeting_time_selector_on_text_item_event),
+ mts);
g_array_append_val (mts->attendees, attendee);
@@ -1361,6 +1411,58 @@ e_meeting_time_selector_attendee_set_send_meeting_to (EMeetingTimeSelector *mts,
}
+gboolean
+e_meeting_time_selector_attendee_set_busy_range (EMeetingTimeSelector *mts,
+ gint row,
+ gint start_year,
+ gint start_month,
+ gint start_day,
+ gint start_hour,
+ gint start_minute,
+ gint end_year,
+ gint end_month,
+ gint end_day,
+ gint end_hour,
+ gint end_minute)
+{
+ EMeetingTimeSelectorAttendee *attendee;
+
+ g_return_val_if_fail (IS_E_MEETING_TIME_SELECTOR (mts), FALSE);
+ g_return_val_if_fail (row >= 0, FALSE);
+ g_return_val_if_fail (row < mts->attendees->len, FALSE);
+
+ /* Check the dates are valid. */
+ if (!g_date_valid_dmy (start_day, start_month, start_year))
+ return FALSE;
+ if (!g_date_valid_dmy (end_day, end_month, end_year))
+ return FALSE;
+ if (start_hour < 0 || start_hour > 23)
+ return FALSE;
+ if (end_hour < 0 || end_hour > 23)
+ return FALSE;
+ if (start_minute < 0 || start_minute > 59)
+ return FALSE;
+ if (end_minute < 0 || end_minute > 59)
+ return FALSE;
+
+ attendee = &g_array_index (mts->attendees,
+ EMeetingTimeSelectorAttendee, row);
+
+ g_date_clear (&attendee->busy_periods_start.date, 1);
+ g_date_clear (&attendee->busy_periods_end.date, 1);
+ g_date_set_dmy (&attendee->busy_periods_start.date,
+ start_day, start_month, start_year);
+ g_date_set_dmy (&attendee->busy_periods_end.date,
+ end_day, end_month, end_year);
+ attendee->busy_periods_start.hour = start_hour;
+ attendee->busy_periods_start.minute = start_minute;
+ attendee->busy_periods_end.hour = end_hour;
+ attendee->busy_periods_end.minute = end_minute;
+
+ return TRUE;
+}
+
+
/* Clears all busy times for the given attendee. */
void
e_meeting_time_selector_attendee_clear_busy_periods (EMeetingTimeSelector *mts,
@@ -2542,7 +2644,7 @@ e_meeting_time_selector_update_main_canvas_scroll_region (EMeetingTimeSelector *
{
gint height, canvas_height, list_width;
- height = mts->row_height * mts->attendees->len;
+ height = mts->row_height * (mts->attendees->len + 1);
canvas_height = GTK_WIDGET (mts->display_main)->allocation.height;
list_width = GTK_WIDGET (mts->attendees_list)->allocation.width;
@@ -2935,18 +3037,24 @@ e_meeting_time_selector_update_attendees_list_positions (EMeetingTimeSelector *m
EMeetingTimeSelectorAttendee *attendee;
gint list_width, item_width;
gint row;
+ GdkFont *font;
list_width = GTK_WIDGET (mts->attendees_list)->allocation.width;
- item_width = MAX (1, list_width - E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH);
+ item_width = MAX (1, list_width - E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH - E_MEETING_TIME_SELECTOR_TEXT_X_PAD * 2);
+ font = GTK_WIDGET (mts)->style->font;
for (row = 0; row < mts->attendees->len; row++) {
attendee = &g_array_index (mts->attendees,
EMeetingTimeSelectorAttendee, row);
- gnome_canvas_item_set (attendee->text_item,
- "GnomeCanvasWidget::y", (gdouble) (row * mts->row_height),
- "GnomeCanvasWidget::width", (gdouble) item_width,
- "GnomeCanvasWidget::height", (gdouble) (mts->row_height),
- NULL);
+ gnome_canvas_item_set
+ (attendee->text_item,
+ "font_gdk", font,
+ "y", (gdouble) (row * mts->row_height + 1
+ + E_MEETING_TIME_SELECTOR_TEXT_Y_PAD),
+ "clip_width", (gdouble) item_width,
+ "clip_height", (gdouble) (font->ascent
+ + font->descent),
+ NULL);
gnome_canvas_item_show (attendee->text_item);
}
@@ -3063,3 +3171,98 @@ e_meeting_time_selector_calculate_time_position (EMeetingTimeSelector *mts,
}
+static gboolean
+e_meeting_time_selector_on_text_item_event (GnomeCanvasItem *item,
+ GdkEvent *event,
+ EMeetingTimeSelector *mts)
+{
+ EMeetingTimeSelectorAttendee *attendee;
+ gint row, min;
+ ETextEventProcessor *event_processor = NULL;
+ ETextEventProcessorCommand command;
+ GtkAdjustment *adj;
+ gchar *text;
+ gboolean empty = FALSE;
+
+ switch (event->type) {
+ case GDK_KEY_PRESS:
+ if (event && event->key.keyval == GDK_Return) {
+ row = e_meeting_time_selector_find_row_from_text_item (mts, item);
+ g_return_val_if_fail (row != -1, FALSE);
+
+ if (row == mts->attendees->len - 1)
+ row = e_meeting_time_selector_attendee_add (mts, "", NULL);
+ else
+ row++;
+
+ /* Make sure the item is visible. */
+ adj = GTK_LAYOUT (mts->display_main)->vadjustment;
+ min = ((row + 1) * mts->row_height) - adj->page_size;
+ if (adj->value < min) {
+ adj->value = min;
+ gtk_adjustment_value_changed (adj);
+ }
+
+ attendee = &g_array_index (mts->attendees, EMeetingTimeSelectorAttendee, row);
+ e_canvas_item_grab_focus (attendee->text_item);
+
+ /* Try to move the cursor to the end of the text. */
+ gtk_object_get (GTK_OBJECT (attendee->text_item),
+ "event_processor", &event_processor,
+ NULL);
+ if (event_processor) {
+ command.action = E_TEP_MOVE;
+ command.position = E_TEP_END_OF_BUFFER;
+ gtk_signal_emit_by_name (GTK_OBJECT (event_processor),
+ "command", &command);
+ }
+
+ /* Stop the signal last or we will also stop any
+ other events getting to the EText item. */
+ gtk_signal_emit_stop_by_name (GTK_OBJECT (item),
+ "event");
+ return TRUE;
+ }
+ break;
+ case GDK_FOCUS_CHANGE:
+ if (!event->focus_change.in) {
+ gtk_object_get (GTK_OBJECT (item),
+ "text", &text,
+ NULL);
+ if (!text || !text[0])
+ empty = TRUE;
+ g_free (text);
+
+ if (empty) {
+ row = e_meeting_time_selector_find_row_from_text_item (mts, item);
+ g_return_val_if_fail (row != -1, FALSE);
+ e_meeting_time_selector_attendee_remove (mts,
+ row);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+
+static gint
+e_meeting_time_selector_find_row_from_text_item (EMeetingTimeSelector *mts,
+ GnomeCanvasItem *item)
+{
+ EMeetingTimeSelectorAttendee *attendee;
+ gint row;
+
+ for (row = 0; row < mts->attendees->len; row++) {
+ attendee = &g_array_index (mts->attendees,
+ EMeetingTimeSelectorAttendee, row);
+ if (attendee->text_item == item)
+ return row;
+ }
+
+ return -1;
+}
+
diff --git a/widgets/meeting-time-sel/e-meeting-time-sel.h b/widgets/meeting-time-sel/e-meeting-time-sel.h
index 6df15fe54c..a2ad4b9cd5 100644
--- a/widgets/meeting-time-sel/e-meeting-time-sel.h
+++ b/widgets/meeting-time-sel/e-meeting-time-sel.h
@@ -26,6 +26,7 @@
#include <gtk/gtktable.h>
#include <libgnomeui/gnome-canvas.h>
+#include "../e-text/e-text.h"
#ifdef __cplusplus
extern "C" {
@@ -43,6 +44,8 @@ extern "C" {
/* This is the width of the icon column in the attendees list. */
#define E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH 24
+#define E_MEETING_TIME_SELECTOR_TEXT_Y_PAD 3
+#define E_MEETING_TIME_SELECTOR_TEXT_X_PAD 2
/* These specify the type of attendee. Either a person or a resource (e.g. a
meeting room). These are used for the Autopick options, where the user can
@@ -146,6 +149,11 @@ struct _EMeetingTimeSelectorAttendee
/* This is TRUE if the meeting request is sent to this attendee. */
gboolean send_meeting_to;
+ /* This is the period for which free/busy data for the attendee is
+ available. */
+ EMeetingTimeSelectorTime busy_periods_start;
+ EMeetingTimeSelectorTime busy_periods_end;
+
/* This is an array of EMeetingTimeSelectorPeriod elements. When it is
updated busy_periods_sorted is set to FALSE, and if a function
needs them sorted, it should call this to re-sort them if needed:
@@ -423,6 +431,20 @@ void e_meeting_time_selector_attendee_set_send_meeting_to (EMeetingTimeSelector
gint row,
gboolean send_meeting_to);
+gboolean e_meeting_time_selector_attendee_set_busy_range (EMeetingTimeSelector *mts,
+ gint row,
+ gint start_year,
+ gint start_month,
+ gint start_day,
+ gint start_hour,
+ gint start_minute,
+ gint end_year,
+ gint end_month,
+ gint end_day,
+ gint end_hour,
+ gint end_minute);
+
+
/* Clears all busy times for the given attendee. */
void e_meeting_time_selector_attendee_clear_busy_periods (EMeetingTimeSelector *mts,
gint row);
diff --git a/widgets/meeting-time-sel/test-meeting-time-sel.c b/widgets/meeting-time-sel/test-meeting-time-sel.c
index debe4e8f40..33c15ff19b 100644
--- a/widgets/meeting-time-sel/test-meeting-time-sel.c
+++ b/widgets/meeting-time-sel/test-meeting-time-sel.c
@@ -60,6 +60,12 @@ main (int argc, char *argv[])
for (i = 0; i < 20; i++) {
add_random_attendee_test_data (E_MEETING_TIME_SELECTOR (mts));
}
+
+ if (!e_meeting_time_selector_attendee_set_busy_range (E_MEETING_TIME_SELECTOR (mts), 3,
+ 2000, 5, 1, 14, 0,
+ 2000, 11, 1, 11, 30))
+ g_print ("Error setting busy range\n");
+
#else
for (i = 0; i < 1; i++) {
add_simple_attendee_test_data (E_MEETING_TIME_SELECTOR (mts));