Bug 793125 - Crash due to popup menus left attached too long
[evolution.git] / src / calendar / gui / e-meeting-time-sel.h
blobb3e0c9b47145fc9c9cf299919c76d55da17b1d35
1 /*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU Lesser General Public License as published by
4 * the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful, but
7 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
8 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9 * for more details.
11 * You should have received a copy of the GNU Lesser General Public License
12 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 * Authors:
16 * Damon Chaplin <damon@gtk.org>
18 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
22 #ifndef E_MEETING_TIME_SELECTOR_H
23 #define E_MEETING_TIME_SELECTOR_H
25 #include <gtk/gtk.h>
26 #include <libgnomecanvas/libgnomecanvas.h>
28 #include <e-util/e-util.h>
30 #include "e-meeting-store.h"
31 #include "e-meeting-list-view.h"
34 * EMeetingTimeSelector displays a list of attendees for a meeting and a
35 * graphical summary of the times which they are free and busy, allowing the
36 * user to select an appropriate time for a meeting.
39 /* Standard GObject macros */
40 #define E_TYPE_MEETING_TIME_SELECTOR \
41 (e_meeting_time_selector_get_type ())
42 #define E_MEETING_TIME_SELECTOR(obj) \
43 (G_TYPE_CHECK_INSTANCE_CAST \
44 ((obj), E_TYPE_MEETING_TIME_SELECTOR, EMeetingTimeSelector))
45 #define E_MEETING_TIME_SELECTOR_CLASS(cls) \
46 (G_TYPE_CHECK_CLASS_CAST \
47 ((cls), E_TYPE_MEETING_TIME_SELECTOR, EMeetingTimeSelectorClass))
48 #define E_IS_MEETING_TIME_SELECTOR(obj) \
49 (G_TYPE_CHECK_INSTANCE_TYPE \
50 ((obj), E_TYPE_MEETING_TIME_SELECTOR))
51 #define E_IS_MEETING_TIME_SELECTOR_CLASS(cls) \
52 (G_TYPE_CHECK_CLASS_TYPE \
53 ((cls), E_TYPE_MEETING_TIME_SELECTOR))
54 #define E_MEETING_TIME_SELECTOR_GET_CLASS(obj) \
55 (G_TYPE_INSTANCE_GET_CLASS \
56 ((obj), E_TYPE_MEETING_TIME_SELECTOR))
58 /* Define this to include the debugging functions. */
59 #undef E_MEETING_TIME_SELECTOR_DEBUG
61 /* This is the width of the icon column in the attendees list. */
62 #define E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH 24
64 #define E_MEETING_TIME_SELECTOR_TEXT_Y_PAD 3
65 #define E_MEETING_TIME_SELECTOR_TEXT_X_PAD 2
67 G_BEGIN_DECLS
69 /* This is used to specify the format used when displaying the dates.
70 * The abbreviated format is like 'Sun 12/9/99'.
71 * The short format is like '12/9/99'.
72 * The actual format used is determined in e_meeting_time_selector_style_updated (),
73 * once we know the font being used.
75 typedef enum
77 E_MEETING_TIME_SELECTOR_DATE_ABBREVIATED_DAY,
78 E_MEETING_TIME_SELECTOR_DATE_SHORT
79 } EMeetingTimeSelectorDateFormat;
81 /* This is used to specify a position regarding the vertical bars around the
82 * current meeting time, so we know which one is being dragged. */
83 typedef enum
85 E_MEETING_TIME_SELECTOR_POS_NONE,
86 E_MEETING_TIME_SELECTOR_POS_START,
87 E_MEETING_TIME_SELECTOR_POS_END
88 } EMeetingTimeSelectorPosition;
90 /* This is used to specify the autopick option, which determines how we choose
91 * the previous/next appropriate meeting time. */
92 typedef enum
94 E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_RESOURCES,
95 E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_ONE_RESOURCE,
96 E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE,
97 E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE_AND_ONE_RESOURCE
98 } EMeetingTimeSelectorAutopickOption;
100 /* An array of hour strings for 24 hour time, "0:00" .. "23:00". */
101 extern const gchar *EMeetingTimeSelectorHours[24];
102 /* An array of hour strings for 12 hour time, "12:00am" .. "11:00pm". */
103 extern const gchar *EMeetingTimeSelectorHours12[24];
105 typedef struct _EMeetingTimeSelector EMeetingTimeSelector;
106 typedef struct _EMeetingTimeSelectorClass EMeetingTimeSelectorClass;
107 typedef struct _EMeetingTimeSelectorPrivate EMeetingTimeSelectorPrivate;
109 struct _EMeetingTimeSelector {
110 /* We subclass a GtkTable which makes it easy to add extra widgets
111 * if neccesary. */
112 GtkTable table;
114 EMeetingTimeSelectorPrivate *priv;
117 * User Interface stuff - widgets, colors etc.
120 /* This contains our keyboard accelerators, which need to be added to
121 * the toplevel window. */
122 GtkAccelGroup *accel_group;
124 /* The vbox in the top-left corner, containing the 'All Attendees'
125 * title bar packed at the end. Extra widgets can be added here
126 * with PACK_START if necessary. */
127 GtkWidget *attendees_vbox;
128 GtkWidget *attendees_vbox_spacer;
130 /* The etable and model */
131 EMeetingStore *model;
132 EMeetingListView *list_view;
134 /* The canvas displaying the dates, times, and the summary
135 * 'All Attendees' free/busy display. */
136 GtkWidget *display_top;
137 GnomeCanvasItem *item_top;
139 /* The canvas containing the free/busy displays of individual
140 * attendees. This is separate from display_top since it also scrolls
141 * vertically. */
142 GtkWidget *display_main;
143 GnomeCanvasItem *item_main;
145 /* The 'Add attendees from addressbook' button */
146 GtkWidget *add_attendees_button;
148 /* This is the 'Options' button & menu. */
149 GtkWidget *options_button;
150 GtkWidget *options_menu;
152 /* This is the 'Autopick' button, menu & radio menu items. */
153 GtkWidget *autopick_down_button;
154 GtkWidget *autopick_button;
155 GtkWidget *autopick_up_button;
156 GtkWidget *autopick_menu;
157 GtkWidget *autopick_all_item;
158 GtkWidget *autopick_all_people_one_resource_item;
159 GtkWidget *autopick_required_people_item;
160 GtkWidget *autopick_required_people_one_resource_item;
162 /* The horizontal scrollbar which scrolls display_top & display_main.*/
163 GtkWidget *hscrollbar;
165 /* The vertical scrollbar which scrolls attendees & display_main. */
166 GtkWidget *vscrollbar;
168 /* The 2 EDateEdit widgets for the meeting start & end times. */
169 GtkWidget *start_date_edit;
170 GtkWidget *end_date_edit;
172 /* Colors. */
173 GdkColor bg_color;
174 GdkColor all_attendees_bg_color;
175 GdkColor meeting_time_bg_color;
176 GdkColor attendee_list_bg_color;
177 GdkColor grid_color;
178 GdkColor grid_shadow_color;
179 GdkColor grid_unused_color;
180 GdkColor busy_colors[E_MEETING_FREE_BUSY_LAST];
182 /* The pattern used for attendees with no data. */
183 cairo_pattern_t *no_info_pattern;
185 /* Width of the hours strings (e.g. "1:00") in the current font. */
186 gint hour_widths[24];
188 /* Whether we are using the full, abbreviated or short date format. */
189 EMeetingTimeSelectorDateFormat date_format;
192 * Option Settings.
195 /* True if we are selecting all day events */
196 gboolean all_day;
198 /* If this is TRUE we only show hours between day_start_hour and
199 * day_end_hour, defaults to TRUE (9am-6pm). */
200 gboolean working_hours_only;
201 gint day_start_hour[G_DATE_SUNDAY + 1];
202 gint day_start_minute[G_DATE_SUNDAY + 1];
203 gint day_end_hour[G_DATE_SUNDAY + 1];
204 gint day_end_minute[G_DATE_SUNDAY + 1];
206 /* If TRUE, view is compressed, with one cell for every 3 hours rather
207 * than every hour. Defaults to FALSE. */
208 gboolean zoomed_out;
211 * Internal Data.
214 /* These are the first & last dates shown in the current scroll area.
215 * We show E_MEETING_TIME_SELECTOR_DAYS_SHOWN days at a time. */
216 GDate first_date_shown;
217 GDate last_date_shown;
219 /* This is the current selection of the meeting time. */
220 EMeetingTime meeting_start_time;
221 EMeetingTime meeting_end_time;
223 /* These are the x pixel coordinates in the entire scroll region of
224 * the start and end times. Set to meeting_positions_valid to FALSE to
225 * invalidate. They will then be recomputed when needed. Always access
226 * with e_meeting_time_selector_get_meeting_time_positions (). */
227 gint meeting_positions_valid;
228 gint meeting_positions_in_scroll_area;
229 gint meeting_start_x;
230 gint meeting_end_x;
232 /* These are the width and height of the cells, including the grid
233 * lines which are displayed on the right and top or bottom of cells.*/
234 gint row_height;
235 gint col_width;
237 /* This is the width of a day in the display, which depends on
238 * col_width, working_hours_only and zoomed_out. */
239 gint day_width;
241 /* These are the first and last hour of each day we display, depending
242 * on working_hours_only and zoomed_out. */
243 gint first_hour_shown;
244 gint last_hour_shown;
246 /* The id of the source function for auto-scroll timeouts. */
247 guint auto_scroll_timeout_id;
249 /* This specifies if we are dragging one of the vertical bars around
250 * the meeting time. */
251 EMeetingTimeSelectorPosition dragging_position;
253 /* The last x coordinate of the mouse, relative to either the left or
254 * right edge of the canvas. Used in the auto_scroll_timeout function
255 * to determine which way to scroll and how fast. */
256 gint last_drag_x;
258 /* This is used to determine the delay between scrolls. */
259 gint scroll_count;
261 /* The notification function id for Free/Busy refreshes */
262 gboolean fb_refresh_not;
264 GdkCursorType last_cursor_set;
266 guint style_change_idle_id;
269 struct _EMeetingTimeSelectorClass {
270 GtkTableClass parent_class;
272 void (* changed) (EMeetingTimeSelector *mts);
276 * PUBLIC INTERFACE - note that this interface will probably change, when I
277 * know where the data is coming from. This is mainly just for testing for now.
280 GType e_meeting_time_selector_get_type (void);
281 GtkWidget * e_meeting_time_selector_new (EMeetingStore *ems);
282 void e_meeting_time_selector_construct
283 (EMeetingTimeSelector *mts,
284 EMeetingStore *ems);
285 gboolean e_meeting_time_selector_get_use_24_hour_format
286 (EMeetingTimeSelector *mts);
287 void e_meeting_time_selector_set_use_24_hour_format
288 (EMeetingTimeSelector *mts,
289 gboolean use_24_hour_format);
291 /* This returns the currently selected meeting time.
292 * Note that months are 1-12 and days are 1-31. The start time is guaranteed to
293 * be before or equal to the end time. You may want to check if they are equal
294 * if that if it is a problem. */
295 void e_meeting_time_selector_get_meeting_time
296 (EMeetingTimeSelector *mts,
297 gint *start_year,
298 gint *start_month,
299 gint *start_day,
300 gint *start_hour,
301 gint *start_minute,
302 gint *end_year,
303 gint *end_month,
304 gint *end_day,
305 gint *end_hour,
306 gint *end_minute);
308 /* This sets the meeting time, returning TRUE if it is valid. */
309 gboolean e_meeting_time_selector_set_meeting_time
310 (EMeetingTimeSelector *mts,
311 gint start_year,
312 gint start_month,
313 gint start_day,
314 gint start_hour,
315 gint start_minute,
316 gint end_year,
317 gint end_month,
318 gint end_day,
319 gint end_hour,
320 gint end_minute);
322 void e_meeting_time_selector_set_all_day
323 (EMeetingTimeSelector *mts,
324 gboolean all_day);
325 void e_meeting_time_selector_set_working_hours_only
326 (EMeetingTimeSelector *mts,
327 gboolean working_hours_only);
328 void e_meeting_time_selector_set_working_hours
329 (EMeetingTimeSelector *mts,
330 GDateWeekday for_weekday,
331 gint day_start_hour,
332 gint day_start_minute,
333 gint day_end_hour,
334 gint day_end_minute);
336 void e_meeting_time_selector_set_zoomed_out
337 (EMeetingTimeSelector *mts,
338 gboolean zoomed_out);
340 EMeetingTimeSelectorAutopickOption
341 e_meeting_time_selector_get_autopick_option
342 (EMeetingTimeSelector *mts);
343 void e_meeting_time_selector_set_autopick_option
344 (EMeetingTimeSelector *mts,
345 EMeetingTimeSelectorAutopickOption autopick_option);
347 void e_meeting_time_selector_attendee_set_send_meeting_to
348 (EMeetingTimeSelector *mts,
349 gint row,
350 gboolean send_meeting_to);
352 void e_meeting_time_selector_set_read_only
353 (EMeetingTimeSelector *mts,
354 gboolean read_only);
356 /* Clears all busy times for the given attendee. */
357 void e_meeting_time_selector_attendee_clear_busy_periods
358 (EMeetingTimeSelector *mts,
359 gint row);
360 /* Adds one busy time for the given attendee. */
361 gboolean e_meeting_time_selector_attendee_add_busy_period
362 (EMeetingTimeSelector *mts,
363 gint row,
364 gint start_year,
365 gint start_month,
366 gint start_day,
367 gint start_hour,
368 gint start_minute,
369 gint end_year,
370 gint end_month,
371 gint end_day,
372 gint end_hour,
373 gint end_minute,
374 EMeetingFreeBusyType busy_type);
377 * INTERNAL ROUTINES - functions to communicate with the canvas items within
378 * the EMeetingTimeSelector.
381 /* This returns the x pixel coordinates of the meeting start and end times,
382 * in the entire canvas scroll area. If it returns FALSE, then the meeting
383 * time isn't in the current scroll area (which shouldn't really happen). */
384 gboolean e_meeting_time_selector_get_meeting_time_positions
385 (EMeetingTimeSelector *mts,
386 gint *start_x,
387 gint *end_x);
389 void e_meeting_time_selector_drag_meeting_time
390 (EMeetingTimeSelector *mts,
391 gint x);
393 void e_meeting_time_selector_remove_timeout
394 (EMeetingTimeSelector *mts);
396 void e_meeting_time_selector_fix_time_overflows
397 (EMeetingTime *mtstime);
399 void e_meeting_time_selector_calculate_day_and_position
400 (EMeetingTimeSelector *mts,
401 gint x,
402 GDate *date,
403 gint *day_position);
404 void e_meeting_time_selector_convert_day_position_to_hours_and_mins
405 (EMeetingTimeSelector *mts,
406 gint day_position,
407 guint8 *hours,
408 guint8 *minutes);
409 void e_meeting_time_selector_calculate_time
410 (EMeetingTimeSelector *mts,
411 gint x,
412 EMeetingTime *time);
413 gint e_meeting_time_selector_calculate_time_position
414 (EMeetingTimeSelector *mts,
415 EMeetingTime *mtstime);
416 void e_meeting_time_selector_refresh_free_busy
417 (EMeetingTimeSelector *mts,
418 gint row,
419 gboolean all);
421 /* Debugging function to dump information on all attendees. */
422 #ifdef E_MEETING_TIME_SELECTOR_DEBUG
423 void e_meeting_time_selector_dump (EMeetingTimeSelector *mts);
424 gchar * e_meeting_time_selector_dump_time
425 (EMeetingTime *mtstime);
426 gchar * e_meeting_time_selector_dump_date
427 (GDate *date);
428 #endif /* E_MEETING_TIME_SELECTOR_DEBUG */
430 G_END_DECLS
432 #endif /* E_MEETING_TIME_SELECTOR_H */