#include <string.h>
#include <stdlib.h>
#include <time.h>
-#include <glib/gprintf.h>
+
+#include <glib.h>
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#endif
#undef GTK_DISABLE_DEPRECATED
#include "gtkcalendar.h"
-#define GTK_DISABLE_DEPRECATED
#include "gtkdnd.h"
#include "gtkintl.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
#include "gtkprivate.h"
-#include "gtkintl.h"
#include "gdk/gdkkeysyms.h"
#include "gtkalias.h"
/***************************************************************************/
-/* The following date routines are taken from the lib_date package. Keep
- * them separate in case we want to update them if a newer lib_date comes
- * out with fixes. */
-
-typedef unsigned int N_int;
-typedef unsigned long N_long;
-typedef signed long Z_long;
-typedef enum { false = FALSE , true = TRUE } boolean;
-
-#define and && /* logical (boolean) operators: lower case */
-#define or ||
+/* The following date routines are taken from the lib_date package.
+ * They have been minimally edited to avoid conflict with types defined
+ * in win32 headers.
+ */
-static const N_int month_length[2][13] =
+static const guint month_length[2][13] =
{
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
-static const N_int days_in_months[2][14] =
+static const guint days_in_months[2][14] =
{
{ 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
{ 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};
-static Z_long calc_days(N_int year, N_int mm, N_int dd);
-static N_int day_of_week(N_int year, N_int mm, N_int dd);
-static Z_long dates_difference(N_int year1, N_int mm1, N_int dd1,
- N_int year2, N_int mm2, N_int dd2);
-static N_int weeks_in_year(N_int year);
+static glong calc_days(guint year, guint mm, guint dd);
+static guint day_of_week(guint year, guint mm, guint dd);
+static glong dates_difference(guint year1, guint mm1, guint dd1,
+ guint year2, guint mm2, guint dd2);
+static guint weeks_in_year(guint year);
-static boolean
-leap(N_int year)
+static gboolean
+leap (guint year)
{
- return((((year % 4) == 0) and ((year % 100) != 0)) or ((year % 400) == 0));
+ return((((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0));
}
-static N_int
-day_of_week(N_int year, N_int mm, N_int dd)
+static guint
+day_of_week (guint year, guint mm, guint dd)
{
- Z_long days;
+ glong days;
days = calc_days(year, mm, dd);
if (days > 0L)
days %= 7L;
days++;
}
- return( (N_int) days );
+ return( (guint) days );
}
-static N_int weeks_in_year(N_int year)
+static guint weeks_in_year(guint year)
{
- return(52 + ((day_of_week(year,1,1)==4) or (day_of_week(year,12,31)==4)));
+ return(52 + ((day_of_week(year,1,1)==4) || (day_of_week(year,12,31)==4)));
}
-static boolean
-check_date(N_int year, N_int mm, N_int dd)
+static gboolean
+check_date(guint year, guint mm, guint dd)
{
- if (year < 1) return(false);
- if ((mm < 1) or (mm > 12)) return(false);
- if ((dd < 1) or (dd > month_length[leap(year)][mm])) return(false);
- return(true);
+ if (year < 1) return FALSE;
+ if ((mm < 1) || (mm > 12)) return FALSE;
+ if ((dd < 1) || (dd > month_length[leap(year)][mm])) return FALSE;
+ return TRUE;
}
-static N_int
-week_number(N_int year, N_int mm, N_int dd)
+static guint
+week_number(guint year, guint mm, guint dd)
{
- N_int first;
+ guint first;
first = day_of_week(year,1,1) - 1;
- return( (N_int) ( (dates_difference(year,1,1, year,mm,dd) + first) / 7L ) +
+ return( (guint) ( (dates_difference(year,1,1, year,mm,dd) + first) / 7L ) +
(first < 4) );
}
-static Z_long
-year_to_days(N_int year)
+static glong
+year_to_days(guint year)
{
return( year * 365L + (year / 4) - (year / 100) + (year / 400) );
}
-static Z_long
-calc_days(N_int year, N_int mm, N_int dd)
+static glong
+calc_days(guint year, guint mm, guint dd)
{
- boolean lp;
+ gboolean lp;
if (year < 1) return(0L);
- if ((mm < 1) or (mm > 12)) return(0L);
- if ((dd < 1) or (dd > month_length[(lp = leap(year))][mm])) return(0L);
+ if ((mm < 1) || (mm > 12)) return(0L);
+ if ((dd < 1) || (dd > month_length[(lp = leap(year))][mm])) return(0L);
return( year_to_days(--year) + days_in_months[lp][mm] + dd );
}
-static boolean
-week_of_year(N_int *week, N_int *year, N_int mm, N_int dd)
+static gboolean
+week_of_year(guint *week, guint *year, guint mm, guint dd)
{
if (check_date(*year,mm,dd))
{
*week = 1;
(*year)++;
}
- return(true);
+ return TRUE;
}
- return(false);
+ return FALSE;
}
-static Z_long
-dates_difference(N_int year1, N_int mm1, N_int dd1,
- N_int year2, N_int mm2, N_int dd2)
+static glong
+dates_difference(guint year1, guint mm1, guint dd1,
+ guint year2, guint mm2, guint dd2)
{
return( calc_days(year2, mm2, dd2) - calc_days(year1, mm1, dd1) );
}
#define DAY_XSEP 0 /* not really good for small calendar */
#define DAY_YSEP 0 /* not really good for small calendar */
+#define SCROLL_DELAY_FACTOR 5
+
/* Color usage */
#define HEADER_FG_COLOR(widget) (& (widget)->style->fg[GTK_WIDGET_STATE (widget)])
#define HEADER_BG_COLOR(widget) (& (widget)->style->bg[GTK_WIDGET_STATE (widget)])
time_t secs;
struct tm *tm;
gint i;
+#ifdef G_OS_WIN32
+ wchar_t wbuffer[100];
+#else
char buffer[255];
time_t tmp_time;
+#endif
GtkCalendarPrivate *priv;
gchar *year_before;
+#ifdef HAVE__NL_TIME_FIRST_WEEKDAY
gchar *langinfo;
gint week_1stday = 0;
gint first_weekday = 1;
guint week_origin;
+#else
+ gchar *week_start;
+#endif
priv = calendar->priv = G_TYPE_INSTANCE_GET_PRIVATE (calendar,
GTK_TYPE_CALENDAR,
if (!default_abbreviated_dayname[0])
for (i=0; i<7; i++)
{
+#ifndef G_OS_WIN32
tmp_time= (i+3)*86400;
strftime ( buffer, sizeof (buffer), "%a", gmtime (&tmp_time));
default_abbreviated_dayname[i] = g_locale_to_utf8 (buffer, -1, NULL, NULL, NULL);
+#else
+ if (!GetLocaleInfoW (GetThreadLocale (), LOCALE_SABBREVDAYNAME1 + (i+6)%7,
+ wbuffer, G_N_ELEMENTS (wbuffer)))
+ default_abbreviated_dayname[i] = g_strdup_printf ("(%d)", i);
+ else
+ default_abbreviated_dayname[i] = g_utf16_to_utf8 (wbuffer, -1, NULL, NULL, NULL);
+#endif
}
if (!default_monthname[0])
for (i=0; i<12; i++)
{
+#ifndef G_OS_WIN32
tmp_time=i*2764800;
strftime ( buffer, sizeof (buffer), "%B", gmtime (&tmp_time));
default_monthname[i] = g_locale_to_utf8 (buffer, -1, NULL, NULL, NULL);
+#else
+ if (!GetLocaleInfoW (GetThreadLocale (), LOCALE_SMONTHNAME1 + i,
+ wbuffer, G_N_ELEMENTS (wbuffer)))
+ default_monthname[i] = g_strdup_printf ("(%d)", i);
+ else
+ default_monthname[i] = g_utf16_to_utf8 (wbuffer, -1, NULL, NULL, NULL);
+#endif
}
/* Set defaults */
calendar->month = tm->tm_mon;
calendar->year = 1900 + tm->tm_year;
- calendar_compute_days (calendar);
-
for (i=0;i<31;i++)
calendar->marked_date[i] = FALSE;
calendar->num_marked_dates = 0;
* Do *not* translate it to anything else, if it
* it isn't calendar:YM or calendar:MY it will not work.
*
- * Note that this flipping is in top the text direction flipping,
+ * Note that this flipping is in top of the text direction flipping,
* so if you have a default text direction of RTL and YM, then
* the year will appear on the right.
*/
else if (strcmp (year_before, "calendar:MY") != 0)
g_warning ("Whoever translated calendar:MY did so wrongly.\n");
+#ifdef G_OS_WIN32
+ priv->week_start = 0;
+ week_start = NULL;
+
+ if (GetLocaleInfoW (GetThreadLocale (), LOCALE_IFIRSTDAYOFWEEK,
+ wbuffer, G_N_ELEMENTS (wbuffer)))
+ week_start = g_utf16_to_utf8 (wbuffer, -1, NULL, NULL, NULL);
+
+ if (week_start != NULL)
+ {
+ priv->week_start = (week_start[0] - '0' + 1) % 7;
+ g_free(week_start);
+ }
+#else
#ifdef HAVE__NL_TIME_FIRST_WEEKDAY
langinfo = nl_langinfo (_NL_TIME_FIRST_WEEKDAY);
first_weekday = langinfo[0];
priv->week_start = 0;
}
#endif
+#endif
+
+ calendar_compute_days (calendar);
}
\f
gint height;
gint i;
- gchar buffer[255];
gint calendar_margin = CALENDAR_MARGIN;
gint header_width, main_width;
gint max_header_height = 0;
/* Mainwindow labels width */
priv->max_day_char_width = 0;
+ priv->max_day_char_ascent = 0;
+ priv->max_day_char_descent = 0;
priv->min_day_width = 0;
- priv->max_label_char_ascent = 0;
- priv->max_label_char_descent = 0;
for (i = 0; i < 9; i++)
{
- g_snprintf (buffer, sizeof (buffer), "%d%d", i, i);
+ gchar buffer[32];
+ g_snprintf (buffer, sizeof (buffer), Q_("calendar:day:digits|%d"), i * 11);
pango_layout_set_text (layout, buffer, -1);
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
priv->min_day_width = MAX (priv->min_day_width,
logical_rect.width);
- priv->max_day_char_ascent = MAX (priv->max_label_char_ascent,
+ priv->max_day_char_ascent = MAX (priv->max_day_char_ascent,
PANGO_ASCENT (logical_rect));
- priv->max_day_char_descent = MAX (priv->max_label_char_descent,
+ priv->max_day_char_descent = MAX (priv->max_day_char_descent,
PANGO_DESCENT (logical_rect));
}
/* We add one to max_day_char_width to be able to make the marked day "bold" */
priv->max_day_char_width = priv->min_day_width / 2 + 1;
+ priv->max_label_char_ascent = 0;
+ priv->max_label_char_descent = 0;
if (calendar->display_flags & GTK_CALENDAR_SHOW_DAY_NAMES)
for (i = 0; i < 7; i++)
{
if (calendar->display_flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS)
for (i = 0; i < 9; i++)
{
- g_snprintf (buffer, sizeof (buffer), "%d%d", i, i);
+ gchar buffer[32];
+ g_snprintf (buffer, sizeof (buffer), Q_("calendar:week:digits|%d"), i * 11);
pango_layout_set_text (layout, buffer, -1);
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
priv->max_week_char_width = MAX (priv->max_week_char_width,
- logical_rect.width / 2);
+ logical_rect.width / 2);
}
main_width = (7 * (priv->min_day_width + (focus_padding + focus_width) * 2) + (DAY_XSEP * 6) + CALENDAR_MARGIN * 2
cairo_t *cr;
gint row, week = 0, year;
gint x_loc;
- char buffer[3];
+ char buffer[32];
gint y_loc, day_height;
PangoLayout *layout;
PangoRectangle logical_rect;
+ calendar->month) % 12 + 1, calendar->day[row][6]);
g_return_if_fail (result);
- g_snprintf (buffer, sizeof (buffer), "%d", week);
+ /* Translators: this defines whether the week numbers should use
+ * localized digits or the ones used in English (0123...).
+ *
+ * Translate to "%Id" if you want to use localized digits, or
+ * translate to "%d" otherwise. Don't include the
+ * "calendar:week:digits|" part in the translation.
+ *
+ * Note that translating this doesn't guarantee that you get localized
+ * digits. That needs support from your system and locale definition
+ * too.
+ */
+ g_snprintf (buffer, sizeof (buffer), Q_("calendar:week:digits|%d"), week);
pango_layout_set_text (layout, buffer, -1);
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
cairo_t *cr;
GdkColor *text_color;
- gchar buffer[255];
+ gchar buffer[32];
gint day;
gint x_loc, y_loc;
GdkRectangle day_rect;
text_color = NORMAL_DAY_COLOR (widget);
}
- g_snprintf (buffer, sizeof (buffer), "%d", day);
+ /* Translators: this defines whether the day numbers should use
+ * localized digits or the ones used in English (0123...).
+ *
+ * Translate to "%Id" if you want to use localized digits, or
+ * translate to "%d" otherwise. Don't include the "calendar:day:digits|"
+ * part in the translation.
+ *
+ * Note that translating this doesn't guarantee that you get localized
+ * digits. That needs support from your system and locale definition
+ * too.
+ */
+ g_snprintf (buffer, sizeof (buffer), Q_("calendar:day:digits|%d"), day);
layout = gtk_widget_create_pango_layout (widget, buffer);
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
gtk_paint_arrow (widget->style, window, state,
GTK_SHADOW_OUT, NULL, widget, "calendar",
GTK_ARROW_RIGHT, TRUE,
- width/2 - 2, height/2 - 4, 8, 8);
+ width/2 - 4, height/2 - 4, 8, 8);
}
}
* Mouse handling *
****************************************/
-#define CALENDAR_INITIAL_TIMER_DELAY 200
-#define CALENDAR_TIMER_DELAY 20
-
static void
calendar_arrow_action (GtkCalendar *calendar,
guint arrow)
GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
gboolean retval = FALSE;
- GDK_THREADS_ENTER ();
-
if (priv->timer)
{
calendar_arrow_action (calendar, priv->click_child);
if (priv->need_timer)
{
+ GtkSettings *settings;
+ guint timeout;
+
+ settings = gtk_widget_get_settings (GTK_WIDGET (calendar));
+ g_object_get (settings, "gtk-timeout-repeat", &timeout, NULL);
+
priv->need_timer = FALSE;
- priv->timer = g_timeout_add (CALENDAR_TIMER_DELAY,
- (GSourceFunc) calendar_timer,
- (gpointer) calendar);
+ priv->timer = gdk_threads_add_timeout_full (G_PRIORITY_DEFAULT_IDLE,
+ timeout * SCROLL_DELAY_FACTOR,
+ (GSourceFunc) calendar_timer,
+ (gpointer) calendar, NULL);
}
else
retval = TRUE;
}
- GDK_THREADS_LEAVE ();
-
return retval;
}
if (!priv->timer)
{
+ GtkSettings *settings;
+ guint timeout;
+
+ settings = gtk_widget_get_settings (GTK_WIDGET (calendar));
+ g_object_get (settings, "gtk-timeout-initial", &timeout, NULL);
+
priv->need_timer = TRUE;
- priv->timer = g_timeout_add (CALENDAR_INITIAL_TIMER_DELAY,
- calendar_timer,
- calendar);
+ priv->timer = gdk_threads_add_timeout_full (G_PRIORITY_DEFAULT_IDLE,
+ timeout,
+ (GSourceFunc) calendar_timer,
+ (gpointer) calendar, NULL);
}
}
case GDK_space:
row = calendar->focus_row;
col = calendar->focus_col;
- day = calendar->day[row][col];
if (row > -1 && col > -1)
{
return_val = TRUE;
+ day = calendar->day[row][col];
if (calendar->day_month[row][col] == MONTH_PREV)
calendar_set_month_prev (calendar);
else if (calendar->day_month[row][col] == MONTH_NEXT)
{
GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget);
+ gtk_widget_queue_draw (widget);
+
calendar_stop_spinning (GTK_CALENDAR (widget));
priv->in_drag = 0;
}
target = gtk_drag_dest_find_target (widget, context, NULL);
- if (target == GDK_NONE)
+ if (target == GDK_NONE || context->suggested_action == 0)
gdk_drag_status (context, 0, time);
else
{
*
* Sets display options (whether to display the heading and the month headings).
*
- * Deprecated: Use gtk_calendar_set_display_options() instead
+ * Deprecated: 2.4: Use gtk_calendar_set_display_options() instead
**/
void
gtk_calendar_display_options (GtkCalendar *calendar,
*
* Does nothing. Previously locked the display of the calendar until
* it was thawed with gtk_calendar_thaw().
+ *
+ * Deprecated: 2.8:
**/
void
gtk_calendar_freeze (GtkCalendar *calendar)
*
* Does nothing. Previously defrosted a calendar; all the changes made
* since the last gtk_calendar_freeze() were displayed.
+ *
+ * Deprecated: 2.8:
**/
void
gtk_calendar_thaw (GtkCalendar *calendar)