static void dates_date_change (DatesData *data, int direction) { icaltimetype *time, *oldtime; oldtime = (icaltimetype *)dates_view_get_date (data->view); time = g_new (icaltimetype, 1); g_memmove (time, oldtime, sizeof (icaltimetype)); if (data->zoom == 16) time->year += direction; else if (data->zoom >= 11) { int days; time->month += direction; if (time->month > 12) { time->month = 1; time->year++; } else if (time->month < 1) { time->month = 12; time->year--; } days = icaltime_days_in_month (time->month, time->year); if (time->day > days) time->day = days; } else if (data->zoom >= 8) icaltime_adjust (time, direction * 7, 0, 0, 0); else icaltime_adjust (time, direction, 0, 0, 0); if (time->year < 1900) goto out; dates_view_set_date (data->view, time); out: g_free (time); }
/** * gcal_month_view_get_final_date: * * Since: 0.1 * Return value: the last day of the month * Returns: (transfer full): Release with g_free **/ icaltimetype* gcal_month_view_get_final_date (GcalMonthView *view) { GcalMonthViewPrivate *priv; icaltimetype *new_date; priv = view->priv; new_date = gcal_dup_icaltime (priv->date); new_date->day = icaltime_days_in_month (priv->date->month, priv->date->year); return new_date; }
/* Calculate the relative position of the week in a month from a date */ static int calculate_pos (icaltimetype icaltime) { int pos; pos = (icaltime.day -1) / 7; /* Check if pos 3 is the last occurence of the week day in the month */ if (pos == 3 && ((icaltime.day + 7) > icaltime_days_in_month (icaltime.month, icaltime.year))) pos = 4; return r_pos [pos]; }
NS_IMETHODIMP calDateTime::GetEndOfMonth(calIDateTime ** aResult) { NS_ENSURE_ARG_POINTER(aResult); icaltimetype icalt; ToIcalTime(&icalt); icalt.day = icaltime_days_in_month(icalt.month, icalt.year); icalt.is_date = 1; calDateTime * const cdt = new calDateTime(&icalt, mTimezone); CAL_ENSURE_MEMORY(cdt); NS_ADDREF(*aResult = cdt); return NS_OK; }
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); }
/** @brief Internal, shouldn't be part of the public API * * Adds (or subtracts) a time from a icaltimetype. * NOTE: This function is exactly the same as icaltimezone_adjust_change() * except for the type of the first parameter. */ void icaltime_adjust(struct icaltimetype *tt, const int days, const int hours, const int minutes, const int seconds) { int second, minute, hour, day; int minutes_overflow, hours_overflow, days_overflow = 0, years_overflow; int days_in_month; /* If we are passed a date make sure to ignore hour minute and second */ if (tt->is_date) goto IS_DATE; /* Add on the seconds. */ second = tt->second + seconds; tt->second = second % 60; minutes_overflow = second / 60; if (tt->second < 0) { tt->second += 60; minutes_overflow--; } /* Add on the minutes. */ minute = tt->minute + minutes + minutes_overflow; tt->minute = minute % 60; hours_overflow = minute / 60; if (tt->minute < 0) { tt->minute += 60; hours_overflow--; } /* Add on the hours. */ hour = tt->hour + hours + hours_overflow; tt->hour = hour % 24; days_overflow = hour / 24; if (tt->hour < 0) { tt->hour += 24; days_overflow--; } IS_DATE: /* Normalize the month. We do this before handling the day since we may need to know what month it is to get the number of days in it. Note that months are 1 to 12, so we have to be a bit careful. */ if (tt->month >= 13) { years_overflow = (tt->month - 1) / 12; tt->year += years_overflow; tt->month -= years_overflow * 12; } else if (tt->month <= 0) { /* 0 to -11 is -1 year out, -12 to -23 is -2 years. */ years_overflow = (tt->month / 12) - 1; tt->year += years_overflow; tt->month -= years_overflow * 12; } /* Add on the days. */ day = tt->day + days + days_overflow; if (day > 0) { for (;;) { days_in_month = icaltime_days_in_month(tt->month, tt->year); if (day <= days_in_month) break; tt->month++; if (tt->month >= 13) { tt->year++; tt->month = 1; } day -= days_in_month; } } else { while (day <= 0) { if (tt->month == 1) { tt->year--; tt->month = 12; } else { tt->month--; } day += icaltime_days_in_month(tt->month, tt->year); } } tt->day = day; }
static void gcal_month_view_draw_month_grid (GcalMonthView *month_view, cairo_t *cr, gint x, gint y) { GcalMonthViewPrivate *priv; GtkWidget *widget; GtkStyleContext *context; GtkStateFlags state; GdkRGBA color; gint i, j; gint font_width; gint font_height; guint8 n_days_in_month; PangoLayout *layout; gchar *day; priv = month_view->priv; widget = GTK_WIDGET (month_view); context = gtk_widget_get_style_context (widget); state = gtk_widget_get_state_flags (widget); state |= GTK_STATE_FLAG_SELECTED; gtk_style_context_get_background_color (context, state, &color); cairo_set_source_rgba (cr, color.red, color.green, color.blue, 0.8); cairo_rectangle (cr, x + priv->horizontal_step * ( priv->selected_cell % 7), y + priv->vertical_step * ( priv->selected_cell / 7), priv->horizontal_step, priv->vertical_step); cairo_fill (cr); state = gtk_widget_get_state_flags (widget); gtk_style_context_get_color (context, state, &color); cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha); layout = pango_cairo_create_layout (cr); pango_layout_set_font_description (layout, gtk_style_context_get_font (context, state)); n_days_in_month = icaltime_days_in_month (priv->date->month, priv->date->year); for (i = 0; i < 7; i++) { pango_layout_set_text (layout, weekdays[i], -1); pango_cairo_update_layout (cr, layout); pango_layout_get_pixel_size (layout, &font_width, &font_height); cairo_move_to (cr, x + priv->horizontal_step * i + 1, y - font_height - 1); pango_cairo_show_layout (cr, layout); for (j = 0; j < 5; j++) { gint n_day = j * 7 + i + priv->days_delay; if (n_day <= 0 || n_day > n_days_in_month) continue; day = g_strdup_printf ("%d", n_day); pango_layout_set_text (layout, day, -1); pango_cairo_update_layout (cr, layout); pango_layout_get_pixel_size (layout, &font_width, &font_height); cairo_move_to (cr, x + priv->horizontal_step * i + 2, y + priv->vertical_step * j + 1); pango_cairo_show_layout (cr, layout); g_free (day); } } /* free the layout object */ g_object_unref (layout); for (i = 0; i < 6; i++) { cairo_move_to (cr, x, y + priv->vertical_step * i); cairo_line_to (cr, x + priv->horizontal_step * 7, y + priv->vertical_step * i); } for (i = 0; i < 8; i++) { cairo_move_to (cr, x + priv->horizontal_step * i, y); cairo_line_to (cr, x + priv->horizontal_step * i, y + priv->vertical_step * 5); } cairo_stroke (cr); }
/** Adds (or subtracts) a time from a icaltimezonechange. NOTE: This function is exactly the same as icaltime_adjust() except for the type of the first parameter. */ static void icaltimezone_adjust_change (icaltimezonechange *tt, int days, int hours, int minutes, int seconds) { int second, minute, hour, day; int minutes_overflow, hours_overflow, days_overflow; int days_in_month; /* Add on the seconds. */ second = tt->second + seconds; tt->second = second % 60; minutes_overflow = second / 60; if (tt->second < 0) { tt->second += 60; minutes_overflow--; } /* Add on the minutes. */ minute = tt->minute + minutes + minutes_overflow; tt->minute = minute % 60; hours_overflow = minute / 60; if (tt->minute < 0) { tt->minute += 60; hours_overflow--; } /* Add on the hours. */ hour = tt->hour + hours + hours_overflow; tt->hour = hour % 24; days_overflow = hour / 24; if (tt->hour < 0) { tt->hour += 24; days_overflow--; } /* Add on the days. */ day = tt->day + days + days_overflow; if (day > 0) { for (;;) { days_in_month = icaltime_days_in_month (tt->month, tt->year); if (day <= days_in_month) break; tt->month++; if (tt->month >= 13) { tt->year++; tt->month = 1; } day -= days_in_month; } } else { while (day <= 0) { if (tt->month == 1) { tt->year--; tt->month = 12; } else { tt->month--; } day += icaltime_days_in_month (tt->month, tt->year); } } tt->day = day; }