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. 5 * 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. 10 * 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/>. 13 * 14 * 15 * Authors: 16 * Damon Chaplin <damon@ximian.com> 17 * 18 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) 19 * 20 */ 21 22 #ifndef E_WEEK_VIEW_H 23 #define E_WEEK_VIEW_H 24 25 #include <gtk/gtk.h> 26 #include <libgnomecanvas/libgnomecanvas.h> 27 28 #include "e-calendar-view.h" 29 30 /* 31 * EWeekView - displays the Week & Month views of the calendar. 32 */ 33 34 /* Standard GObject macros */ 35 #define E_TYPE_WEEK_VIEW \ 36 (e_week_view_get_type ()) 37 #define E_WEEK_VIEW(obj) \ 38 (G_TYPE_CHECK_INSTANCE_CAST \ 39 ((obj), E_TYPE_WEEK_VIEW, EWeekView)) 40 #define E_WEEK_VIEW_CLASS(cls) \ 41 (G_TYPE_CHECK_CLASS_CAST \ 42 ((cls), E_TYPE_WEEK_VIEW, EWeekViewClass)) 43 #define E_IS_WEEK_VIEW(obj) \ 44 (G_TYPE_CHECK_INSTANCE_TYPE \ 45 ((obj), E_TYPE_WEEK_VIEW)) 46 #define E_IS_WEEK_VIEW_CLASS(cls) \ 47 (G_TYPE_CHECK_CLASS_TYPE \ 48 ((cls), E_TYPE_WEEK_VIEW)) 49 #define E_WEEK_VIEW_GET_CLASS(obj) \ 50 (G_TYPE_INSTANCE_GET_CLASS \ 51 ((obj), E_TYPE_WEEK_VIEW, EWeekViewClass)) 52 53 /* The maximum number of weeks we show. 5 is usually enough for 1 month, 54 * but we allow 6 for longer selections. */ 55 #define E_WEEK_VIEW_MAX_WEEKS 6 56 57 /* The size of the reminder & recurrence icons, and padding around them. 58 * X_PAD is the padding between icons. R_PAD is the padding on the right of 59 * the last icon, before the event text. */ 60 #define E_WEEK_VIEW_ICON_WIDTH 16 61 #define E_WEEK_VIEW_ICON_HEIGHT 16 62 #define E_WEEK_VIEW_ICON_X_PAD 1 63 #define E_WEEK_VIEW_ICON_Y_PAD 1 64 #define E_WEEK_VIEW_ICON_R_PAD 4 65 66 /* The space on the left & right outside of the event. (The triangle to 67 * indicate the event continues is displayed in this space). */ 68 #define E_WEEK_VIEW_EVENT_L_PAD 2 69 #define E_WEEK_VIEW_EVENT_R_PAD 2 70 71 /* The vertical spacing between rows of events. */ 72 #define E_WEEK_VIEW_EVENT_Y_SPACING 1 73 74 /* The size of the border around long events. */ 75 #define E_WEEK_VIEW_EVENT_BORDER_WIDTH 1 76 #define E_WEEK_VIEW_EVENT_BORDER_HEIGHT 1 77 78 /* The padding on the top and bottom of the event text. */ 79 #define E_WEEK_VIEW_EVENT_TEXT_Y_PAD 1 80 81 /* The space between the start and end times. */ 82 #define E_WEEK_VIEW_EVENT_TIME_SPACING 2 83 84 /* The space between the time and the event text or icons. */ 85 #define E_WEEK_VIEW_EVENT_TIME_X_PAD 4 86 87 /* The space between the borders of long events and any text of icons. */ 88 #define E_WEEK_VIEW_EVENT_EDGE_X_PAD 2 89 90 /* The padding above and on the right of the date string at the top of each 91 * cell. */ 92 #define E_WEEK_VIEW_DATE_T_PAD 2 93 #define E_WEEK_VIEW_DATE_R_PAD 4 94 95 /* The padding above and below the line under the date string, in the Week 96 * view, and also the space on the left of it. */ 97 #define E_WEEK_VIEW_DATE_LINE_T_PAD 1 98 #define E_WEEK_VIEW_DATE_LINE_B_PAD 1 99 #define E_WEEK_VIEW_DATE_LINE_L_PAD 10 100 101 /* The padding below the date string in the Month view. */ 102 #define E_WEEK_VIEW_DATE_B_PAD 1 103 104 /* We use a 7-bit field to store row numbers in EWeekViewEventSpan, so the 105 * maximum number or rows we can allow is 127. It is very unlikely to be 106 * reached anyway. */ 107 #define E_WEEK_VIEW_MAX_ROWS_PER_CELL 127 108 109 G_BEGIN_DECLS 110 111 /* These index our colors array. */ 112 typedef enum { 113 E_WEEK_VIEW_COLOR_EVEN_MONTHS, 114 E_WEEK_VIEW_COLOR_ODD_MONTHS, 115 E_WEEK_VIEW_COLOR_EVENT_BACKGROUND, 116 E_WEEK_VIEW_COLOR_EVENT_BORDER, 117 E_WEEK_VIEW_COLOR_EVENT_TEXT, 118 E_WEEK_VIEW_COLOR_GRID, 119 E_WEEK_VIEW_COLOR_SELECTED, 120 E_WEEK_VIEW_COLOR_SELECTED_UNFOCUSSED, 121 E_WEEK_VIEW_COLOR_DATES, 122 E_WEEK_VIEW_COLOR_DATES_SELECTED, 123 E_WEEK_VIEW_COLOR_TODAY, 124 E_WEEK_VIEW_COLOR_TODAY_BACKGROUND, 125 E_WEEK_VIEW_COLOR_MONTH_NONWORKING_DAY, 126 127 E_WEEK_VIEW_COLOR_LAST 128 } EWeekViewColors; 129 130 /* These specify which part of the selection we are dragging, if any. */ 131 typedef enum { 132 E_WEEK_VIEW_DRAG_NONE, 133 E_WEEK_VIEW_DRAG_START, 134 E_WEEK_VIEW_DRAG_END 135 } EWeekViewDragPosition; 136 137 /* These specify which times are shown for the 1-day events. We use the small 138 * font for the minutes if it can be loaded and the option is on. */ 139 typedef enum { 140 E_WEEK_VIEW_TIME_NONE, 141 E_WEEK_VIEW_TIME_START, 142 E_WEEK_VIEW_TIME_BOTH, 143 E_WEEK_VIEW_TIME_START_SMALL_MIN, 144 E_WEEK_VIEW_TIME_BOTH_SMALL_MIN 145 } EWeekViewTimeFormat; 146 147 typedef struct _EWeekViewEventSpan EWeekViewEventSpan; 148 struct _EWeekViewEventSpan { 149 guint start_day : 6; 150 guint num_days : 3; 151 guint row : 7; 152 GnomeCanvasItem *background_item; 153 GnomeCanvasItem *text_item; 154 }; 155 156 typedef struct _EWeekViewEvent EWeekViewEvent; 157 struct _EWeekViewEvent { 158 E_CALENDAR_VIEW_EVENT_FIELDS 159 160 gint spans_index; 161 guint8 num_spans; 162 }; 163 164 typedef struct _EWeekView EWeekView; 165 typedef struct _EWeekViewClass EWeekViewClass; 166 typedef struct _EWeekViewPrivate EWeekViewPrivate; 167 168 struct _EWeekView { 169 ECalendarView parent; 170 EWeekViewPrivate *priv; 171 172 /* The top canvas where the dates are shown. */ 173 GtkWidget *titles_canvas; 174 GnomeCanvasItem *titles_canvas_item; 175 176 /* The main canvas where the appointments are shown. */ 177 GtkWidget *main_canvas; 178 GnomeCanvasItem *main_canvas_item; 179 180 GnomeCanvasItem *jump_buttons[E_WEEK_VIEW_MAX_WEEKS * 7]; 181 gint focused_jump_button; 182 183 GtkWidget *vscrollbar; 184 185 /* The array of EWeekViewEvent elements. */ 186 GArray *events; 187 gboolean events_sorted; 188 gboolean events_need_layout; 189 gboolean events_need_reshape; 190 191 /* The ID of the timeout function for doing a new layout. */ 192 gint layout_timeout_id; 193 194 /* An array of EWeekViewEventSpan elements. Each event has its own 195 * space within this array, and uses the spans_index and num_spans 196 * fields of the EWeekViewEvent struct to access it. */ 197 GArray *spans; 198 199 /* The start of each day displayed. */ 200 time_t day_starts[E_WEEK_VIEW_MAX_WEEKS * 7 + 1]; 201 202 /* The base date, where the adjustment value is 0. */ 203 GDate base_date; 204 205 /* TRUE when requires scrolling by a week in a multi_week_view */ 206 gboolean month_scroll_by_week; 207 guint scroll_by_week_notif_id; 208 209 /* The vertical offset of the events from the top of the cells. */ 210 gint events_y_offset; 211 212 /* The height of the events, not including spacing between them. */ 213 gint row_height; 214 215 /* The number of rows of events in each cell. */ 216 gint rows_per_cell; 217 gint rows_per_compressed_cell; 218 219 /* The number of rows we have used for each day (i.e. each cell) */ 220 gint rows_per_day[E_WEEK_VIEW_MAX_WEEKS * 7 + 1]; 221 222 /* If the small font is used for displaying the minutes. */ 223 gboolean use_small_font; 224 225 /* Small font to display the minutes. */ 226 PangoFontDescription *small_font_desc; 227 228 /* The widths of various pieces of text, used to determine which of 229 * several date formats to display, set in e_week_view_style_updated (). */ 230 gint space_width; /* One space character ' '. */ 231 gint colon_width; /* Size of ':' in the font. */ 232 gint slash_width; /* Size of '/' in the font. */ 233 gint digit_width; /* Size of a '0' digit. */ 234 gint small_digit_width; /* Size of a small_font '0' digit. */ 235 gint day_widths[7]; /* Monday first. */ 236 gint max_day_width; 237 gint abbr_day_widths[7]; 238 gint max_abbr_day_width; 239 gint month_widths[12]; 240 gint max_month_width; 241 gint abbr_month_widths[12]; 242 gint max_abbr_month_width; 243 244 /* The size of the main grid of days and of the cells. A row 245 * corresponds to a compressed day, so normal days usually take 246 * up 2 rows. Note that the offsets arrays have one more element 247 * than the widths/heights arrays since they also contain the 248 * right/bottom edge. */ 249 gint rows; 250 gint columns; 251 gint col_widths[7]; 252 gint col_offsets[8]; 253 gint row_heights[E_WEEK_VIEW_MAX_WEEKS * 2]; 254 gint row_offsets[E_WEEK_VIEW_MAX_WEEKS * 2 + 1]; 255 256 /* This specifies which times we are showing for the events, depending 257 * on how much room is available. */ 258 EWeekViewTimeFormat time_format; 259 260 /* The icons. */ 261 GdkPixbuf *reminder_icon; 262 GdkPixbuf *recurrence_icon; 263 GdkPixbuf *attach_icon; 264 GdkPixbuf *timezone_icon; 265 GdkPixbuf *meeting_icon; 266 267 /* Colors for drawing. */ 268 GdkColor colors[E_WEEK_VIEW_COLOR_LAST]; 269 270 /* The normal & resizing cursors. */ 271 GdkCursor *normal_cursor; 272 GdkCursor *move_cursor; 273 GdkCursor *resize_width_cursor; 274 275 /* This remembers the last cursor set on the window. */ 276 GdkCursor *last_cursor_set; 277 278 /* The currently selected region, in days from the first day shown. 279 * If selection_start_day is -1 there is no current selection. */ 280 gint selection_start_day; 281 gint selection_end_day; 282 283 /* This specifies which end of the selection is being dragged, or is 284 * E_WEEK_VIEW_DRAG_NONE if the selection isn't being dragged. */ 285 EWeekViewDragPosition selection_drag_pos; 286 287 /* This is the event the mouse button was pressed on. If the button 288 * is released we start editing it, but if the mouse is dragged we set 289 * this to -1. */ 290 gint pressed_event_num; 291 gint pressed_span_num; 292 293 /* The event span currently being edited. The num is -1 if no event is 294 * being edited. */ 295 gint editing_event_num; 296 gint editing_span_num; 297 298 /* This is used to remember the last edited event. */ 299 gchar *last_edited_comp_string; 300 301 /* The event that the context menu is for. */ 302 gint popup_event_num; 303 304 /* The last mouse position when dragging, in the entire canvas. */ 305 gint drag_event_x; 306 gint drag_event_y; 307 308 /* "am" and "pm" in the current locale, and their widths. */ 309 gchar *am_string; 310 gchar *pm_string; 311 gint am_string_width; 312 gint pm_string_width; 313 gboolean event_destroyed; 314 315 /* remember last selected interval when click and restore on double click, 316 * if we double clicked inside that interval. */ 317 guint32 bc_event_time; 318 time_t before_click_dtstart; 319 time_t before_click_dtend; 320 321 gboolean requires_update; 322 }; 323 324 struct _EWeekViewClass { 325 ECalendarViewClass parent_class; 326 327 void (*cursor_key_up) (EWeekView *week_view); 328 void (*cursor_key_down) (EWeekView *week_view); 329 void (*cursor_key_left) (EWeekView *week_view); 330 void (*cursor_key_right) (EWeekView *week_view); 331 }; 332 333 GType e_week_view_get_type (void); 334 ECalendarView * e_week_view_new (ECalModel *model); 335 336 gboolean e_week_view_get_draw_flat_events 337 (EWeekView *week_view); 338 void e_week_view_set_draw_flat_events 339 (EWeekView *week_view, 340 gboolean draw_flat_events); 341 gboolean e_week_view_get_days_left_to_right 342 (EWeekView *week_view); 343 void e_week_view_set_days_left_to_right 344 (EWeekView *week_view, 345 gboolean days_left_to_right); 346 347 /* The first day shown. Note that it will be rounded down to the start of a 348 * week when set. The returned value will be invalid if no date has been set 349 * yet. */ 350 void e_week_view_get_first_day_shown (EWeekView *week_view, 351 GDate *date); 352 void e_week_view_set_first_day_shown (EWeekView *week_view, 353 GDate *date); 354 355 /* The first day of the week we display. */ 356 GDateWeekday e_week_view_get_display_start_day 357 (EWeekView *week_view); 358 359 /* The selected time range. The EWeekView will show the corresponding 360 * month and the days between start_time and end_time will be selected. 361 * To select a single day, use the same value for start_time & end_time. */ 362 void e_week_view_set_selected_time_range_visible 363 (EWeekView *week_view, 364 time_t start_time, 365 time_t end_time); 366 367 /* Whether to display 1 week or 1 month (5 weeks). It defaults to 1 week. */ 368 gboolean e_week_view_get_multi_week_view (EWeekView *week_view); 369 void e_week_view_set_multi_week_view (EWeekView *week_view, 370 gboolean multi_week_view); 371 372 /* Whether to update the base date when the time range changes */ 373 gboolean e_week_view_get_update_base_date (EWeekView *week_view); 374 void e_week_view_set_update_base_date (EWeekView *week_view, 375 gboolean update_base_date); 376 377 /* The number of weeks shown in the multi-week view. */ 378 gint e_week_view_get_weeks_shown (EWeekView *week_view); 379 void e_week_view_set_weeks_shown (EWeekView *week_view, 380 gint weeks_shown); 381 382 /* Whether the weekend (Sat/Sun) should be compressed into 1 cell in the Month 383 * view. In the Week view they are always compressed. */ 384 gboolean e_week_view_get_compress_weekend (EWeekView *week_view); 385 void e_week_view_set_compress_weekend (EWeekView *week_view, 386 gboolean compress_weekend); 387 388 /* Whether we display event end times. */ 389 gboolean e_week_view_get_show_event_end_times 390 (EWeekView *week_view); 391 void e_week_view_set_show_event_end_times 392 (EWeekView *week_view, 393 gboolean show_event_end_times); 394 gboolean e_week_view_get_show_icons_month_view 395 (EWeekView *week_view); 396 void e_week_view_set_show_icons_month_view 397 (EWeekView *week_view, 398 gboolean show_icons_month_view); 399 400 void e_week_view_delete_occurrence (EWeekView *week_view); 401 402 /* Returns the number of selected events (0 or 1 at present). */ 403 gint e_week_view_get_num_events_selected 404 (EWeekView *week_view); 405 406 /* 407 * Internal functions called by the associated canvas items. 408 */ 409 void e_week_view_get_day_position (EWeekView *week_view, 410 gint day, 411 gint *day_x, 412 gint *day_y, 413 gint *day_w, 414 gint *day_h); 415 gboolean e_week_view_get_span_position (EWeekView *week_view, 416 gint event_num, 417 gint span_num, 418 gint *span_x, 419 gint *span_y, 420 gint *span_w); 421 gboolean e_week_view_is_one_day_event (EWeekView *week_view, 422 gint event_num); 423 gboolean e_week_view_start_editing_event (EWeekView *week_view, 424 gint event_num, 425 gint span_num, 426 gchar *initial_text); 427 void e_week_view_stop_editing_event (EWeekView *week_view); 428 429 void e_week_view_show_popup_menu (EWeekView *week_view, 430 GdkEvent *button_event, 431 gint event_num); 432 433 void e_week_view_convert_time_to_display 434 (EWeekView *week_view, 435 gint hour, 436 gint *display_hour, 437 const gchar **suffix, 438 gint *suffix_width); 439 gint e_week_view_get_time_string_width 440 (EWeekView *week_view); 441 442 gint e_week_view_event_sort_func (gconstpointer arg1, 443 gconstpointer arg2); 444 445 gboolean e_week_view_find_event_from_item (EWeekView *week_view, 446 GnomeCanvasItem *item, 447 gint *event_num_return, 448 gint *span_num_return); 449 450 gboolean e_week_view_is_jump_button_visible 451 (EWeekView *week_view, 452 gint day); 453 void e_week_view_jump_to_button_item (EWeekView *week_view, 454 GnomeCanvasItem *item); 455 void e_week_view_scroll_a_step (EWeekView *week_view, 456 ECalViewMoveDirection direction); 457 458 gboolean e_week_view_is_editing (EWeekView *week_view); 459 460 G_END_DECLS 461 462 #endif /* E_WEEK_VIEW_H */ 463