/** * time_week_begin_with_zone: * @time: A time_t value. * @week_start_day: Day to use as the starting of the week. * @zone: Timezone to use. * * Returns the start of the week containing the given time_t, using the given * timezone. week_start_day should use the same values as mktime(), * i.e. 0 (Sun) to 6 (Sat). * NOTE: this function is only here to make the transition to the timezone * functions easier. New code should use icaltimetype values and * icaltime_adjust() to add or subtract days, hours, minutes & seconds. * * Return value: the beginning of the week. */ time_t time_week_begin_with_zone (time_t time, int week_start_day, icaltimezone *zone) { struct icaltimetype tt; int weekday, offset; /* Convert to an icaltimetype. */ tt = icaltime_from_timet_with_zone (time, FALSE, zone); /* Get the weekday. */ weekday = time_day_of_week (tt.day, tt.month - 1, tt.year); /* Calculate the current offset from the week start day. */ offset = (weekday + 7 - week_start_day) % 7; /* Set it to the start of the month. */ tt.day -= offset; tt.hour = 0; tt.minute = 0; tt.second = 0; /* Normalize it, to fix any overflow. */ tt = icaltime_normalize (tt); /* Convert back to a time_t. */ return icaltime_as_timet_with_zone (tt, zone); }
static gboolean calculate_day_month_for_coord (GcalYearView *year_view, gdouble x, gdouble y, gint *out_day, gint *out_month) { GcalYearViewPrivate *priv = year_view->priv; gint row, column, i, sw, box_side, clicked_cell, day, month; row = -1; column = -1; box_side = priv->navigator_grid->box_side; sw = 1 - 2 * priv->k; /* y selection */ for (i = 0; i < 4 && ((row == -1) || (column == -1)); i++) { if (row == -1 && y > priv->navigator_grid->coordinates[i * 4].y + box_side && y < priv->navigator_grid->coordinates[i * 4].y + box_side * 7) { row = i; } if (column == -1 && x > priv->navigator_grid->coordinates[i].x + box_side * 0.5 && x < priv->navigator_grid->coordinates[i].x + box_side * 7.5) { column = i; } } if (row == -1 || column == -1) return FALSE; month = row * 4 + column; row = (y - (priv->navigator_grid->coordinates[month].y + box_side)) / box_side; column = (x - (priv->navigator_grid->coordinates[month].x + box_side * 0.5)) / box_side; clicked_cell = row * 7 + column; day = 7 * ((clicked_cell + 7 * priv->k) / 7) + sw * (clicked_cell % 7) + (1 - priv->k); day -= ((time_day_of_week (1, month, priv->date->year) - priv->first_weekday + 7) % 7); if (day < 1 || day > time_days_in_month (priv->date->year, month)) return FALSE; *out_day = day; *out_month = month; return TRUE; }
/** * icaltimetype_to_tm: * @itt: An icaltimetype structure. * * Convers an icaltimetype structure into a GLibc's struct tm. * * Return value: The converted time as a struct tm. All fields will be * set properly except for tm.tm_yday. */ struct tm icaltimetype_to_tm (struct icaltimetype *itt) { struct tm tm; memset (&tm, 0, sizeof (struct tm)); if (!itt->is_date) { tm.tm_sec = itt->second; tm.tm_min = itt->minute; tm.tm_hour = itt->hour; } tm.tm_mday = itt->day; tm.tm_mon = itt->month - 1; tm.tm_year = itt->year - 1900; tm.tm_wday = time_day_of_week (itt->day, itt->month - 1, itt->year); tm.tm_isdst = -1; return tm; }
/* Builds a static string out of an exception date */ static gchar * get_exception_string (EDateTimeList *date_time_list, struct icaltimetype *itt) { static gchar buf[256]; struct icaltimetype tt; struct tm tmp_tm; icaltimezone *zone; gboolean use_24_hour_format; use_24_hour_format = e_date_time_list_get_use_24_hour_format (date_time_list); zone = e_date_time_list_get_timezone (date_time_list); tt = *itt; if (zone) tt = icaltime_convert_to_zone (tt, zone); tmp_tm.tm_year = tt.year - 1900; tmp_tm.tm_mon = tt.month - 1; tmp_tm.tm_mday = tt.day; tmp_tm.tm_hour = tt.hour; tmp_tm.tm_min = tt.minute; tmp_tm.tm_sec = tt.second; tmp_tm.tm_isdst = -1; tmp_tm.tm_wday = time_day_of_week ( tt.day, tt.month - 1, tt.year); e_time_format_date_and_time ( &tmp_tm, use_24_hour_format, FALSE, FALSE, buf, sizeof (buf)); return buf; }
static void draw_month_grid (GcalYearView *year_view, GtkWidget *widget, cairo_t *cr, gint month_nr, gint *weeks_counter) { GcalYearViewPrivate *priv = year_view->priv; GtkStyleContext *context; GtkStateFlags state_flags; PangoLayout *layout, *slayout; PangoFontDescription *font_desc, *sfont_desc; GdkRGBA color; gint layout_width, layout_height, i, j, sw; gint x, y, column, row, box_side, box_padding_top, box_padding_start; gint days_delay, days, shown_rows, sunday_idx; gchar *str, *nr_day, *nr_week; gboolean selected_day; cairo_save (cr); context = gtk_widget_get_style_context (widget); state_flags = gtk_widget_get_state_flags (widget); sw = 1 - 2 * priv->k; box_side = priv->navigator_grid->box_side; x = priv->navigator_grid->coordinates[month_nr].x; y = priv->navigator_grid->coordinates[month_nr].y; gtk_style_context_get (context, state_flags | GTK_STATE_FLAG_SELECTED, "font", &sfont_desc, NULL); slayout = gtk_widget_create_pango_layout (widget, NULL); pango_layout_set_font_description (slayout, sfont_desc); /* header */ gtk_style_context_save (context); gtk_style_context_add_class (context, "header"); str = g_strdup (gcal_get_month_name (month_nr)); gtk_style_context_get (context, state_flags, "font", &font_desc, NULL); layout = gtk_widget_create_pango_layout (widget, str); pango_layout_set_font_description (layout, font_desc); pango_layout_get_pixel_size (layout, &layout_width, &layout_height); gtk_render_layout (context, cr, x + (box_side * 8 - layout_width) / 2, y + (box_side - layout_height) / 2, layout); gtk_render_background (context, cr, x + (box_side * 8 - layout_width) / 2, y + (box_side - layout_height) / 2, layout_width, layout_width); pango_font_description_free (font_desc); g_free (str); gtk_style_context_restore (context); /* separator line */ gtk_style_context_save (context); gtk_style_context_add_class (context, "lines"); gtk_style_context_get_color (context, state_flags, &color); cairo_set_line_width (cr, 0.2); gdk_cairo_set_source_rgba (cr, &color); cairo_move_to (cr, x + box_side / 2, y + box_side + 0.4); cairo_rel_line_to (cr, 7 * box_side, 0); cairo_stroke (cr); gtk_style_context_restore (context); /* days */ gtk_style_context_save (context); gtk_style_context_add_class (context, "days"); gtk_style_context_get (context, state_flags, "font", &font_desc, NULL); pango_layout_set_font_description (layout, font_desc); days_delay = (time_day_of_week (1, month_nr, priv->date->year) - priv->first_weekday + 7) % 7; days = days_delay + icaltime_days_in_month (month_nr + 1, priv->date->year); shown_rows = ceil (days / 7.0); sunday_idx = priv->k * 6 + sw * ((7 - priv->first_weekday) % 7); for (i = 0; i < 7 * shown_rows; i++) { column = i % 7; row = i / 7; j = 7 * ((i + 7 * priv->k) / 7) + sw * (i % 7) + (1 - priv->k); if (j <= days_delay) continue; else if (j > days) continue; j -= days_delay; nr_day = g_strdup_printf ("%d", j); pango_layout_set_text (layout, nr_day, -1); pango_layout_get_pixel_size (layout, &layout_width, &layout_height); box_padding_top = (box_side - layout_height) / 2 > 0 ? (box_side - layout_height) / 2 : 0; box_padding_start = (box_side - layout_width) / 2 > 0 ? (box_side - layout_width) / 2 : 0; selected_day = FALSE; if (priv->selected_data->start_day != 0) { ButtonData selected_data = *(priv->selected_data); order_selected_data (&selected_data); if (month_nr > selected_data.start_month && month_nr < selected_data.end_month) { selected_day = TRUE; } else if (month_nr == selected_data.start_month && month_nr == selected_data.end_month) { selected_day = j >= selected_data.start_day && j <= selected_data.end_day; } else if (month_nr == selected_data.start_month && j >= selected_data.start_day) { selected_day = TRUE; } else if (month_nr == selected_data.end_month && j <= selected_data.end_day) { selected_day = TRUE; } } if (priv->date->year == priv->current_date->year && month_nr + 1 == priv->current_date->month && j == priv->current_date->day) { PangoLayout *clayout; PangoFontDescription *cfont_desc; gtk_style_context_save (context); gtk_style_context_add_class (context, "current"); clayout = gtk_widget_create_pango_layout (widget, nr_day); gtk_style_context_get (context, state_flags, "font", &cfont_desc, NULL); pango_layout_set_font_description (clayout, cfont_desc); pango_layout_get_pixel_size (clayout, &layout_width, &layout_height); box_padding_top = (box_side - layout_height) / 2 > 0 ? (box_side - layout_height) / 2 : 0; box_padding_start = (box_side - layout_width) / 2 > 0 ? (box_side - layout_width) / 2 : 0; /* FIXME: hardcoded padding of the number background */ gtk_render_background (context, cr, box_side * (column + 0.5 + priv->k) + x + sw * box_padding_start - priv->k * layout_width - 2.0, box_side * (row + 1) + y + box_padding_top - 1.0, layout_width + 4.0, layout_height + 2.0); gtk_render_layout (context, cr, box_side * (column + 0.5 + priv->k) + x + sw * box_padding_start - priv->k * layout_width, box_side * (row + 1) + y + box_padding_top, clayout); gtk_style_context_restore (context); pango_font_description_free (cfont_desc); g_object_unref (clayout); } else if (selected_day) { gtk_style_context_set_state (context, state_flags | GTK_STATE_FLAG_SELECTED); pango_layout_set_text (slayout, nr_day, -1); pango_layout_get_pixel_size (slayout, &layout_width, &layout_height); box_padding_top = (box_side - layout_height) / 2 > 0 ? (box_side - layout_height) / 2 : 0; box_padding_start = (box_side - layout_width) / 2 > 0 ? (box_side - layout_width) / 2 : 0; gtk_render_layout (context, cr, box_side * (column + 0.5 + priv->k) + x + sw * box_padding_start - priv->k * layout_width, box_side * (row + 1) + y + box_padding_top, slayout); gtk_style_context_set_state (context, state_flags); } else if (column == sunday_idx) { gtk_style_context_save (context); gtk_style_context_add_class (context, "sunday"); gtk_render_layout (context, cr, box_side * (column + 0.5 + priv->k) + x + sw * box_padding_start - priv->k * layout_width, box_side * (row + 1) + y + box_padding_top, layout); gtk_style_context_restore (context); } else { gtk_render_layout (context, cr, box_side * (column + 0.5 + priv->k) + x + sw * box_padding_start - priv->k * layout_width, box_side * (row + 1) + y + box_padding_top, layout); } g_free (nr_day); } pango_font_description_free (font_desc); gtk_style_context_restore (context); /* week numbers */ gtk_style_context_save (context); gtk_style_context_add_class (context, "week-numbers"); gtk_style_context_get (context, state_flags, "font", &font_desc, NULL); pango_layout_set_font_description (layout, font_desc); for (i = 0; i < shown_rows; i++) { if (i == 0) { if (days_delay == 0) *weeks_counter = *weeks_counter + 1; } else *weeks_counter = *weeks_counter + 1; nr_week = g_strdup_printf ("%d", *weeks_counter); pango_layout_set_text (layout, nr_week, -1); pango_layout_get_pixel_size (layout, &layout_width, &layout_height); box_padding_top = (box_side - layout_height) / 2 > 0 ? (box_side - layout_height) / 2 : 0; box_padding_start = ((box_side / 2) - layout_width) / 2 > 0 ? ((box_side / 2) - layout_width) / 2 : 0; gtk_render_layout (context, cr, x + sw * box_padding_start + priv->k * (8 * box_side - layout_width), box_side * (i + 1) + y + box_padding_top, layout); g_free (nr_week); } gtk_style_context_restore (context); pango_font_description_free (sfont_desc); g_object_unref (slayout); pango_font_description_free (font_desc); g_object_unref (layout); cairo_restore (cr); }