* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
-#include <config.h>
+#include "config.h"
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
-#include <glib/gprintf.h>
-#undef GTK_DISABLE_DEPRECATED
-#include "gtkcalendar.h"
-#define GTK_DISABLE_DEPRECATED
+#include <glib.h>
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#endif
+#include "gtkcalendar.h"
#include "gtkdnd.h"
#include "gtkintl.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
+#include "gtktooltip.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)])
#define SELECTED_BG_COLOR(widget) (& (widget)->style->base[GTK_WIDGET_HAS_FOCUS (widget) ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE])
#define SELECTED_FG_COLOR(widget) (& (widget)->style->text[GTK_WIDGET_HAS_FOCUS (widget) ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE])
-#define NORMAL_DAY_COLOR(widget) (& (widget)->style->fg[GTK_WIDGET_STATE (widget)])
+#define NORMAL_DAY_COLOR(widget) (& (widget)->style->text[GTK_WIDGET_STATE (widget)])
#define PREV_MONTH_COLOR(widget) (& (widget)->style->mid[GTK_WIDGET_STATE (widget)])
#define NEXT_MONTH_COLOR(widget) (& (widget)->style->mid[GTK_WIDGET_STATE (widget)])
-#define MARKED_COLOR(widget) (& (widget)->style->fg[GTK_WIDGET_STATE (widget)])
+#define MARKED_COLOR(widget) (& (widget)->style->text[GTK_WIDGET_STATE (widget)])
#define BACKGROUND_COLOR(widget) (& (widget)->style->base[GTK_WIDGET_STATE (widget)])
#define HIGHLIGHT_BACK_COLOR(widget) (& (widget)->style->mid[GTK_WIDGET_STATE (widget)])
PROP_SHOW_DAY_NAMES,
PROP_NO_MONTH_CHANGE,
PROP_SHOW_WEEK_NUMBERS,
- PROP_LAST
+ PROP_SHOW_DETAILS,
+ PROP_DETAIL_WIDTH_CHARS,
+ PROP_DETAIL_HEIGHT_ROWS
};
static guint gtk_calendar_signals[LAST_SIGNAL] = { 0 };
gint drag_start_x;
gint drag_start_y;
+
+ /* Optional callback, used to display extra information for each day. */
+ GtkCalendarDetailFunc detail_func;
+ gpointer detail_func_user_data;
+ GDestroyNotify detail_func_destroy;
+
+ /* Size requistion for details provided by the hook. */
+ gint detail_height_rows;
+ gint detail_width_chars;
+ gint detail_overflow[6];
};
#define GTK_CALENDAR_GET_PRIVATE(widget) (GTK_CALENDAR (widget)->priv)
GtkStateType previous_state);
static void gtk_calendar_style_set (GtkWidget *widget,
GtkStyle *previous_style);
+static gboolean gtk_calendar_query_tooltip (GtkWidget *widget,
+ gint x,
+ gint y,
+ gboolean keyboard_mode,
+ GtkTooltip *tooltip);
static void gtk_calendar_drag_data_get (GtkWidget *widget,
GdkDragContext *context,
widget_class->state_changed = gtk_calendar_state_changed;
widget_class->grab_notify = gtk_calendar_grab_notify;
widget_class->focus_out_event = gtk_calendar_focus_out;
+ widget_class->query_tooltip = gtk_calendar_query_tooltip;
widget_class->drag_data_get = gtk_calendar_drag_data_get;
widget_class->drag_motion = gtk_calendar_drag_motion;
widget_class->drag_drop = gtk_calendar_drag_drop;
widget_class->drag_data_received = gtk_calendar_drag_data_received;
+ /**
+ * GtkCalendar:year:
+ *
+ * The selected year.
+ * This property gets initially set to the current year.
+ */
g_object_class_install_property (gobject_class,
PROP_YEAR,
g_param_spec_int ("year",
P_("Year"),
P_("The selected year"),
- 0, G_MAXINT, 0,
+ 0, G_MAXINT >> 9, 0,
GTK_PARAM_READWRITE));
+
+ /**
+ * GtkCalendar:month:
+ *
+ * The selected month (as a number between 0 and 11).
+ * This property gets initially set to the current month.
+ */
g_object_class_install_property (gobject_class,
PROP_MONTH,
g_param_spec_int ("month",
P_("The selected month (as a number between 0 and 11)"),
0, 11, 0,
GTK_PARAM_READWRITE));
+
+ /**
+ * GtkCalendar:day:
+ *
+ * The selected day (as a number between 1 and 31, or 0
+ * to unselect the currently selected day).
+ * This property gets initially set to the current day.
+ */
g_object_class_install_property (gobject_class,
PROP_DAY,
g_param_spec_int ("day",
FALSE,
GTK_PARAM_READWRITE));
+/**
+ * GtkCalendar:detail-width-chars:
+ *
+ * Width of a detail cell, in characters.
+ * A value of 0 allows any width. See gtk_calendar_set_detail_func().
+ *
+ * Since: 2.14
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_DETAIL_WIDTH_CHARS,
+ g_param_spec_int ("detail-width-chars",
+ P_("Details Width"),
+ P_("Details width in characters"),
+ 0, 127, 0,
+ GTK_PARAM_READWRITE));
+
+/**
+ * GtkCalendar:detail-height-rows:
+ *
+ * Height of a detail cell, in rows.
+ * A value of 0 allows any width. See gtk_calendar_set_detail_func().
+ *
+ * Since: 2.14
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_DETAIL_HEIGHT_ROWS,
+ g_param_spec_int ("detail-height-rows",
+ P_("Details Height"),
+ P_("Details height in rows"),
+ 0, 127, 0,
+ GTK_PARAM_READWRITE));
+
+/**
+ * GtkCalendar:show-details:
+ *
+ * Determines whether details are shown directly in the widget, or if they are
+ * available only as tooltip. When this property is set days with details are
+ * marked.
+ *
+ * Since: 2.14
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_SHOW_DETAILS,
+ g_param_spec_boolean ("show-details",
+ P_("Show Details"),
+ P_("If TRUE, details are shown"),
+ TRUE,
+ GTK_PARAM_READWRITE));
+
gtk_calendar_signals[MONTH_CHANGED_SIGNAL] =
- g_signal_new (I_("month_changed"),
+ g_signal_new (I_("month-changed"),
G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkCalendarClass, month_changed),
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gtk_calendar_signals[DAY_SELECTED_SIGNAL] =
- g_signal_new (I_("day_selected"),
+ g_signal_new (I_("day-selected"),
G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkCalendarClass, day_selected),
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gtk_calendar_signals[DAY_SELECTED_DOUBLE_CLICK_SIGNAL] =
- g_signal_new (I_("day_selected_double_click"),
+ g_signal_new (I_("day-selected-double-click"),
G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkCalendarClass, day_selected_double_click),
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gtk_calendar_signals[PREV_MONTH_SIGNAL] =
- g_signal_new (I_("prev_month"),
+ g_signal_new (I_("prev-month"),
G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkCalendarClass, prev_month),
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gtk_calendar_signals[NEXT_MONTH_SIGNAL] =
- g_signal_new (I_("next_month"),
+ g_signal_new (I_("next-month"),
G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkCalendarClass, next_month),
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gtk_calendar_signals[PREV_YEAR_SIGNAL] =
- g_signal_new (I_("prev_year"),
+ g_signal_new (I_("prev-year"),
G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkCalendarClass, prev_year),
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gtk_calendar_signals[NEXT_YEAR_SIGNAL] =
- g_signal_new (I_("next_year"),
+ g_signal_new (I_("next-year"),
G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkCalendarClass, next_year),
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;
+ union { unsigned int word; char *string; } langinfo;
gint week_1stday = 0;
gint first_weekday = 1;
guint week_origin;
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->num_marked_dates = 0;
calendar->selected_day = tm->tm_mday;
- calendar->display_flags = ( GTK_CALENDAR_SHOW_HEADING |
- GTK_CALENDAR_SHOW_DAY_NAMES );
+ calendar->display_flags = (GTK_CALENDAR_SHOW_HEADING |
+ GTK_CALENDAR_SHOW_DAY_NAMES |
+ GTK_CALENDAR_SHOW_DETAILS);
calendar->highlight_row = -1;
calendar->highlight_col = -1;
* 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];
- langinfo = nl_langinfo (_NL_TIME_WEEK_1STDAY);
- week_origin = GPOINTER_TO_INT (langinfo);
+ langinfo.string = nl_langinfo (_NL_TIME_FIRST_WEEKDAY);
+ first_weekday = langinfo.string[0];
+ langinfo.string = nl_langinfo (_NL_TIME_WEEK_1STDAY);
+ week_origin = langinfo.word;
if (week_origin == 19971130) /* Sunday */
week_1stday = 0;
else if (week_origin == 19971201) /* Monday */
g_warning ("Whoever translated calendar:week_start:0 did so wrongly.\n");
priv->week_start = 0;
}
+#endif
#endif
calendar_compute_days (calendar);
* Utility Functions *
****************************************/
+static void
+calendar_queue_refresh (GtkCalendar *calendar)
+{
+ GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
+
+ if (!(priv->detail_func) ||
+ !(calendar->display_flags & GTK_CALENDAR_SHOW_DETAILS) ||
+ (priv->detail_width_chars && priv->detail_height_rows))
+ gtk_widget_queue_draw (GTK_WIDGET (calendar));
+ else
+ gtk_widget_queue_resize (GTK_WIDGET (calendar));
+}
+
static void
calendar_set_month_next (GtkCalendar *calendar)
{
gint month_len;
-
- g_return_if_fail (GTK_IS_WIDGET (calendar));
-
+
if (calendar->display_flags & GTK_CALENDAR_NO_MONTH_CHANGE)
return;
else
gtk_calendar_select_day (calendar, calendar->selected_day);
- gtk_widget_queue_draw (GTK_WIDGET (calendar));
+ calendar_queue_refresh (calendar);
}
static void
calendar_set_year_prev (GtkCalendar *calendar)
{
gint month_len;
-
- g_return_if_fail (GTK_IS_WIDGET (calendar));
-
+
calendar->year--;
calendar_compute_days (calendar);
g_signal_emit (calendar,
else
gtk_calendar_select_day (calendar, calendar->selected_day);
- gtk_widget_queue_draw (GTK_WIDGET (calendar));
+ calendar_queue_refresh (calendar);
}
static void
calendar_set_year_next (GtkCalendar *calendar)
{
gint month_len;
-
- g_return_if_fail (GTK_IS_WIDGET (calendar));
-
+
calendar->year++;
calendar_compute_days (calendar);
g_signal_emit (calendar,
else
gtk_calendar_select_day (calendar, calendar->selected_day);
- gtk_widget_queue_draw (GTK_WIDGET (calendar));
+ calendar_queue_refresh (calendar);
}
static void
gint col;
gint day;
- g_return_if_fail (GTK_IS_CALENDAR (calendar));
-
year = calendar->year;
month = calendar->month + 1;
gtk_calendar_select_day (calendar, calendar->selected_day);
}
- gtk_widget_queue_draw (GTK_WIDGET (calendar));
+ calendar_queue_refresh (calendar);
}
\f
static void
gtk_calendar_finalize (GObject *object)
{
- (* G_OBJECT_CLASS (gtk_calendar_parent_class)->finalize) (object);
+ G_OBJECT_CLASS (gtk_calendar_parent_class)->finalize (object);
}
static void
gtk_calendar_destroy (GtkObject *object)
{
+ GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (object);
+
calendar_stop_spinning (GTK_CALENDAR (object));
+ /* Call the destroy function for the extra display callback: */
+ if (priv->detail_func_destroy && priv->detail_func_user_data)
+ {
+ priv->detail_func_destroy (priv->detail_func_user_data);
+ priv->detail_func_user_data = NULL;
+ priv->detail_func_destroy = NULL;
+ }
+
GTK_OBJECT_CLASS (gtk_calendar_parent_class)->destroy (object);
}
flags = calendar->display_flags | flag;
else
flags = calendar->display_flags & ~flag;
- gtk_calendar_display_options (calendar, flags);
+ gtk_calendar_set_display_options (calendar, flags);
}
static gboolean
GTK_CALENDAR_SHOW_WEEK_NUMBERS,
g_value_get_boolean (value));
break;
+ case PROP_SHOW_DETAILS:
+ calendar_set_display_option (calendar,
+ GTK_CALENDAR_SHOW_DETAILS,
+ g_value_get_boolean (value));
+ break;
+ case PROP_DETAIL_WIDTH_CHARS:
+ gtk_calendar_set_detail_width_chars (calendar,
+ g_value_get_int (value));
+ break;
+ case PROP_DETAIL_HEIGHT_ROWS:
+ gtk_calendar_set_detail_height_rows (calendar,
+ g_value_get_int (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
GValue *value,
GParamSpec *pspec)
{
- GtkCalendar *calendar;
-
- calendar = GTK_CALENDAR (object);
+ GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (object);
+ GtkCalendar *calendar = GTK_CALENDAR (object);
switch (prop_id)
{
g_value_set_boolean (value, calendar_get_display_option (calendar,
GTK_CALENDAR_SHOW_WEEK_NUMBERS));
break;
+ case PROP_SHOW_DETAILS:
+ g_value_set_boolean (value, calendar_get_display_option (calendar,
+ GTK_CALENDAR_SHOW_DETAILS));
+ break;
+ case PROP_DETAIL_WIDTH_CHARS:
+ g_value_set_int (value, priv->detail_width_chars);
+ break;
+ case PROP_DETAIL_HEIGHT_ROWS:
+ g_value_set_int (value, priv->detail_height_rows);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
attributes.x = widget->style->xthickness;
attributes.y = widget->style->ythickness;
attributes.width = widget->allocation.width - 2 * attributes.x;
- attributes.height = priv->header_h - 2 * attributes.y;
+ attributes.height = priv->header_h;
priv->header_win = gdk_window_new (widget->window,
&attributes, attributes_mask);
attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
- attributes.x = widget->style->xthickness + INNER_BORDER;
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
+ attributes.x = widget->style->xthickness + INNER_BORDER;
+ else
+ attributes.x = widget->allocation.width - priv->week_width - (widget->style->xthickness + INNER_BORDER);
attributes.y = (priv->header_h + priv->day_name_h
+ (widget->style->ythickness + INNER_BORDER));
attributes.width = priv->week_width;
| GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
| GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK);
- attributes.x = priv->week_width + (widget->style->ythickness + INNER_BORDER);
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
+ attributes.x = priv->week_width + (widget->style->ythickness + INNER_BORDER);
+ else
+ attributes.x = widget->style->ythickness + INNER_BORDER;
+
attributes.y = (priv->header_h + priv->day_name_h
+ (widget->style->ythickness + INNER_BORDER));
attributes.width = (widget->allocation.width - attributes.x
- (widget->style->xthickness + INNER_BORDER));
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+ attributes.width -= priv->week_width;
+
attributes.height = priv->main_h;
priv->main_win = gdk_window_new (widget->window,
&attributes, attributes_mask);
gdk_window_destroy (priv->day_name_win);
priv->day_name_win = NULL;
}
-
- if (GTK_WIDGET_CLASS (gtk_calendar_parent_class)->unrealize)
- (* GTK_WIDGET_CLASS (gtk_calendar_parent_class)->unrealize) (widget);
+
+ GTK_WIDGET_CLASS (gtk_calendar_parent_class)->unrealize (widget);
+}
+
+static gchar*
+gtk_calendar_get_detail (GtkCalendar *calendar,
+ gint row,
+ gint column)
+{
+ GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
+ gint year, month;
+
+ year = calendar->year;
+ month = calendar->month + calendar->day_month[row][column] - MONTH_CURRENT;
+
+ if (month < 0)
+ {
+ month += 12;
+ year -= 1;
+ }
+ else if (month > 11)
+ {
+ month -= 12;
+ year += 1;
+ }
+
+ return priv->detail_func (calendar,
+ year, month,
+ calendar->day[row][column],
+ priv->detail_func_user_data);
+}
+
+static gboolean
+gtk_calendar_query_tooltip (GtkWidget *widget,
+ gint x,
+ gint y,
+ gboolean keyboard_mode,
+ GtkTooltip *tooltip)
+{
+ GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget);
+ GtkCalendar *calendar = GTK_CALENDAR (widget);
+ gchar *detail = NULL;
+ GdkRectangle day_rect;
+
+ if (priv->main_win)
+ {
+ gint x0, y0, row, col;
+
+ gdk_window_get_position (priv->main_win, &x0, &y0);
+ col = calendar_column_from_x (calendar, x - x0);
+ row = calendar_row_from_y (calendar, y - y0);
+
+ if (col != -1 && row != -1 &&
+ (0 != (priv->detail_overflow[row] & (1 << col)) ||
+ 0 == (calendar->display_flags & GTK_CALENDAR_SHOW_DETAILS)))
+ {
+ detail = gtk_calendar_get_detail (calendar, row, col);
+ calendar_day_rectangle (calendar, row, col, &day_rect);
+
+ day_rect.x += x0;
+ day_rect.y += y0;
+ }
+ }
+
+ if (detail)
+ {
+ gtk_tooltip_set_tip_area (tooltip, &day_rect);
+ gtk_tooltip_set_markup (tooltip, detail);
+
+ g_free (detail);
+
+ return TRUE;
+ }
+
+ if (GTK_WIDGET_CLASS (gtk_calendar_parent_class)->query_tooltip)
+ return GTK_WIDGET_CLASS (gtk_calendar_parent_class)->query_tooltip (widget, x, y, keyboard_mode, tooltip);
+
+ return FALSE;
}
\f
PangoRectangle logical_rect;
gint height;
- gint i;
- gchar buffer[255];
+ gint i, r, c;
gint calendar_margin = CALENDAR_MARGIN;
gint header_width, main_width;
gint max_header_height = 0;
gint focus_width;
gint focus_padding;
-
+ gint max_detail_height;
+
gtk_widget_style_get (GTK_WIDGET (widget),
"focus-line-width", &focus_width,
"focus-padding", &focus_padding,
priv->max_year_width = 0;
/* Translators: This is a text measurement template.
- * Translate it to the widest year text.
- *
- * Don't include the prefix "year measurement template|"
- * in the translation.
+ * Translate it to the widest year text
*
* If you don't understand this, leave it as "2000"
*/
- pango_layout_set_text (layout, Q_("year measurement template|2000"), -1);
+ pango_layout_set_text (layout, C_("year measurement template", "2000"), -1);
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
priv->max_year_width = MAX (priv->max_year_width,
logical_rect.width + 8);
/* 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), C_("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++)
{
pango_layout_set_text (layout, default_abbreviated_dayname[i], -1);
- pango_layout_line_get_pixel_extents (pango_layout_get_lines (layout)->data, NULL, &logical_rect);
+ pango_layout_line_get_pixel_extents (pango_layout_get_lines_readonly (layout)->data, NULL, &logical_rect);
priv->min_day_width = MAX (priv->min_day_width, logical_rect.width);
priv->max_label_char_ascent = MAX (priv->max_label_char_ascent,
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), C_("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);
}
+ /* Calculate detail extents. Do this as late as possible since
+ * pango_layout_set_markup is called which alters font settings. */
+ max_detail_height = 0;
+
+ if (priv->detail_func && (calendar->display_flags & GTK_CALENDAR_SHOW_DETAILS))
+ {
+ gchar *markup, *tail;
+
+ if (priv->detail_width_chars || priv->detail_height_rows)
+ {
+ gint rows = MAX (1, priv->detail_height_rows) - 1;
+ gsize len = priv->detail_width_chars + rows + 16;
+
+ markup = tail = g_alloca (len);
+
+ memcpy (tail, "<small>", 7);
+ tail += 7;
+
+ memset (tail, 'm', priv->detail_width_chars);
+ tail += priv->detail_width_chars;
+
+ memset (tail, '\n', rows);
+ tail += rows;
+
+ memcpy (tail, "</small>", 9);
+ tail += 9;
+
+ g_assert (len == (tail - markup));
+
+ pango_layout_set_markup (layout, markup, -1);
+ pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
+
+ if (priv->detail_width_chars)
+ priv->min_day_width = MAX (priv->min_day_width, logical_rect.width);
+ if (priv->detail_height_rows)
+ max_detail_height = MAX (max_detail_height, logical_rect.height);
+ }
+
+ if (!priv->detail_width_chars || !priv->detail_height_rows)
+ for (r = 0; r < 6; r++)
+ for (c = 0; c < 7; c++)
+ {
+ gchar *detail = gtk_calendar_get_detail (calendar, r, c);
+
+ if (detail)
+ {
+ markup = g_strconcat ("<small>", detail, "</small>", NULL);
+ pango_layout_set_markup (layout, markup, -1);
+
+ if (priv->detail_width_chars)
+ {
+ pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
+ pango_layout_set_width (layout, PANGO_SCALE * priv->min_day_width);
+ }
+
+ pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
+
+ if (!priv->detail_width_chars)
+ priv->min_day_width = MAX (priv->min_day_width, logical_rect.width);
+ if (!priv->detail_height_rows)
+ max_detail_height = MAX (max_detail_height, logical_rect.height);
+
+ g_free (markup);
+ g_free (detail);
+ }
+ }
+ }
+
+ /* 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;
+
main_width = (7 * (priv->min_day_width + (focus_padding + focus_width) * 2) + (DAY_XSEP * 6) + CALENDAR_MARGIN * 2
+ (priv->max_week_char_width
? priv->max_week_char_width * 2 + (focus_padding + focus_width) * 2 + CALENDAR_XSEP * 2
priv->main_h = (CALENDAR_MARGIN + calendar_margin
+ 6 * (priv->max_day_char_ascent
+ priv->max_day_char_descent
+ + max_detail_height
+ 2 * (focus_padding + focus_width))
+ DAY_YSEP * 5);
* gtkcalendar widget. See strftime() manual for the format.
* Use only ASCII in the translation.
*
- * Also look for the msgid "year measurement template|2000".
+ * Also look for the msgid "2000".
* Translate that entry to a year with the widest output of this
- * msgid.
- *
- * Don't include the prefix "calendar year format|" in the
- * translation. "%Y" is appropriate for most locales.
+ * msgid.
+ *
+ * "%Y" is appropriate for most locales.
*/
- strftime (buffer, sizeof (buffer), Q_("calendar year format|%Y"), tm);
+ strftime (buffer, sizeof (buffer), C_("calendar year format", "%Y"), tm);
str = g_locale_to_utf8 (buffer, -1, NULL, NULL, NULL);
layout = gtk_widget_create_pango_layout (widget, str);
g_free (str);
GtkWidget *widget = GTK_WIDGET (calendar);
GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
cairo_t *cr;
- gint row, week = 0, year;
- gint x_loc;
- char buffer[3];
- gint y_loc, day_height;
+
+ guint week = 0, year;
+ gint row, x_loc, y_loc;
+ gint day_height;
+ char buffer[32];
PangoLayout *layout;
PangoRectangle logical_rect;
gint focus_padding;
+ 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.
+ *
+ * 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), C_("calendar:week:digits", "%d"), week);
pango_layout_set_text (layout, buffer, -1);
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
}
}
+static gboolean
+is_color_attribute (PangoAttribute *attribute,
+ gpointer data)
+{
+ return (attribute->klass->type == PANGO_ATTR_FOREGROUND ||
+ attribute->klass->type == PANGO_ATTR_BACKGROUND);
+}
+
static void
calendar_paint_day (GtkCalendar *calendar,
gint row,
GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
cairo_t *cr;
GdkColor *text_color;
- gchar buffer[255];
+ gchar *detail;
+ gchar buffer[32];
gint day;
gint x_loc, y_loc;
GdkRectangle day_rect;
PangoLayout *layout;
PangoRectangle logical_rect;
-
+ gboolean overflow = FALSE;
+ gboolean show_details;
+
g_return_if_fail (row < 6);
g_return_if_fail (col < 7);
cr = gdk_cairo_create (priv->main_win);
day = calendar->day[row][col];
+ show_details = (calendar->display_flags & GTK_CALENDAR_SHOW_DETAILS);
calendar_day_rectangle (calendar, row, col, &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.
+ *
+ * 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), C_("calendar:day:digits", "%d"), day);
+
+ /* Get extra information to show, if any: */
+
+ if (priv->detail_func)
+ detail = gtk_calendar_get_detail (calendar, row, col);
+ else
+ detail = NULL;
+
layout = gtk_widget_create_pango_layout (widget, buffer);
+ pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
- x_loc = day_rect.x + day_rect.width / 2 + priv->max_day_char_width;
- x_loc -= logical_rect.width;
- y_loc = day_rect.y + (day_rect.height - logical_rect.height) / 2;
-
+ x_loc = day_rect.x + (day_rect.width - logical_rect.width) / 2;
+ y_loc = day_rect.y;
+
gdk_cairo_set_source_color (cr, text_color);
cairo_move_to (cr, x_loc, y_loc);
pango_cairo_show_layout (cr, layout);
-
- if (calendar->marked_date[day-1]
- && calendar->day_month[row][col] == MONTH_CURRENT)
+
+ if (calendar->day_month[row][col] == MONTH_CURRENT &&
+ (calendar->marked_date[day-1] || (detail && !show_details)))
{
cairo_move_to (cr, x_loc - 1, y_loc);
pango_cairo_show_layout (cr, layout);
}
+ y_loc += priv->max_day_char_descent;
+
+ if (priv->detail_func && show_details)
+ {
+ cairo_save (cr);
+
+ if (calendar->selected_day == day)
+ gdk_cairo_set_source_color (cr, &widget->style->text[GTK_STATE_ACTIVE]);
+ else if (calendar->day_month[row][col] == MONTH_CURRENT)
+ gdk_cairo_set_source_color (cr, &widget->style->base[GTK_STATE_ACTIVE]);
+ else
+ gdk_cairo_set_source_color (cr, &widget->style->base[GTK_STATE_INSENSITIVE]);
+
+ cairo_set_line_width (cr, 1);
+ cairo_move_to (cr, day_rect.x + 2, y_loc + 0.5);
+ cairo_line_to (cr, day_rect.x + day_rect.width - 2, y_loc + 0.5);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+
+ y_loc += 2;
+ }
+
+ if (detail && show_details)
+ {
+ gchar *markup = g_strconcat ("<small>", detail, "</small>", NULL);
+ pango_layout_set_markup (layout, markup, -1);
+ g_free (markup);
+
+ if (day == calendar->selected_day)
+ {
+ /* Stripping colors as they conflict with selection marking. */
+
+ PangoAttrList *attrs = pango_layout_get_attributes (layout);
+ PangoAttrList *colors = NULL;
+
+ if (attrs)
+ colors = pango_attr_list_filter (attrs, is_color_attribute, NULL);
+ if (colors)
+ pango_attr_list_unref (colors);
+ }
+
+ pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
+ pango_layout_set_width (layout, PANGO_SCALE * day_rect.width);
+
+ if (priv->detail_height_rows)
+ {
+ gint dy = day_rect.height - (y_loc - day_rect.y);
+ pango_layout_set_height (layout, PANGO_SCALE * dy);
+ pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
+ }
+
+ cairo_move_to (cr, day_rect.x, y_loc);
+ pango_cairo_show_layout (cr, layout);
+ }
+
if (GTK_WIDGET_HAS_FOCUS (calendar)
&& calendar->focus_row == row && calendar->focus_col == col)
{
gtk_paint_focus (widget->style,
priv->main_win,
state,
-#if 0
- (calendar->selected_day == day)
- ? GTK_STATE_SELECTED : GTK_STATE_NORMAL,
-#endif
NULL, widget, "calendar-day",
day_rect.x, day_rect.y,
day_rect.width, day_rect.height);
}
+ if (overflow)
+ priv->detail_overflow[row] |= (1 << col);
+ else
+ priv->detail_overflow[row] &= ~(1 << col);
+
g_object_unref (layout);
cairo_destroy (cr);
+ g_free (detail);
}
static void
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);
}
}
GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
gboolean retval = FALSE;
- GDK_THREADS_ENTER ();
-
if (priv->timer)
{
calendar_arrow_action (calendar, priv->click_child);
g_object_get (settings, "gtk-timeout-repeat", &timeout, NULL);
priv->need_timer = FALSE;
- priv->timer = g_timeout_add (timeout,
- (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;
}
g_object_get (settings, "gtk-timeout-initial", &timeout, NULL);
priv->need_timer = TRUE;
- priv->timer = g_timeout_add (timeout,
- calendar_timer,
- calendar);
+ priv->timer = gdk_threads_add_timeout_full (G_PRIORITY_DEFAULT_IDLE,
+ timeout,
+ (GSourceFunc) calendar_timer,
+ (gpointer) calendar, NULL);
}
}
gint direction)
{
GtkTextDirection text_dir = gtk_widget_get_direction (GTK_WIDGET (calendar));
-
+
if ((text_dir == GTK_TEXT_DIR_LTR && direction == -1) ||
(text_dir == GTK_TEXT_DIR_RTL && direction == 1))
{
calendar->focus_col = 6;
calendar->focus_row--;
}
+
+ if (calendar->focus_col < 0)
+ calendar->focus_col = 6;
+ if (calendar->focus_row < 0)
+ calendar->focus_row = 5;
}
else
{
calendar->focus_col = 0;
calendar->focus_row++;
}
+
+ if (calendar->focus_col < 0)
+ calendar->focus_col = 0;
+ if (calendar->focus_row < 0)
+ calendar->focus_row = 0;
}
}
{
if (calendar->focus_row > 0)
calendar->focus_row--;
+ if (calendar->focus_row < 0)
+ calendar->focus_row = 5;
+ if (calendar->focus_col < 0)
+ calendar->focus_col = 6;
calendar_invalidate_day (calendar, old_focus_row, old_focus_col);
calendar_invalidate_day (calendar, calendar->focus_row,
calendar->focus_col);
{
if (calendar->focus_row < 5)
calendar->focus_row++;
+ if (calendar->focus_col < 0)
+ calendar->focus_col = 0;
calendar_invalidate_day (calendar, old_focus_row, old_focus_col);
calendar_invalidate_day (calendar, calendar->focus_row,
calendar->focus_col);
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)
GdkEventFocus *event)
{
GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget);
+ GtkCalendar *calendar = GTK_CALENDAR (widget);
- calendar_stop_spinning (GTK_CALENDAR (widget));
+ calendar_queue_refresh (calendar);
+ calendar_stop_spinning (calendar);
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
{
* supposed to call drag_status, not actually paste in the
* data.
*/
- str = gtk_selection_data_get_text (selection_data);
+ str = (gchar*) gtk_selection_data_get_text (selection_data);
+
if (str)
{
date = g_date_new ();
}
date = g_date_new ();
- str = gtk_selection_data_get_text (selection_data);
+ str = (gchar*) gtk_selection_data_get_text (selection_data);
if (str)
{
g_date_set_parse (date, str);
*
* 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,
if ((flags ^ calendar->display_flags) & GTK_CALENDAR_WEEK_START_MONDAY)
g_warning ("GTK_CALENDAR_WEEK_START_MONDAY is ignored; the first day of the week is determined from the locale");
+ if ((flags ^ calendar->display_flags) & GTK_CALENDAR_SHOW_DETAILS)
+ resize++;
+
calendar->display_flags = flags;
if (resize)
gtk_widget_queue_resize (GTK_WIDGET (calendar));
calendar->year = year;
calendar_compute_days (calendar);
-
- gtk_widget_queue_draw (GTK_WIDGET (calendar));
+ calendar_queue_refresh (calendar);
g_object_freeze_notify (G_OBJECT (calendar));
g_object_notify (G_OBJECT (calendar), "month");
}
calendar->num_marked_dates = 0;
-
- gtk_widget_queue_draw (GTK_WIDGET (calendar));
+ calendar_queue_refresh (calendar);
}
/**
*day = calendar->selected_day;
}
+/**
+ * gtk_calendar_set_detail_func:
+ * @calendar: a #GtkCalendar.
+ * @func: a function providing details for each day.
+ * @data: data to pass to @func invokations.
+ * @destroy: a function for releasing @data.
+ *
+ * Installs a function which provides Pango markup with detail information
+ * for each day. Examples for such details are holidays or appointments. That
+ * information is shown below each day when #GtkCalendar:show-details is set.
+ * A tooltip containing with full detail information is provided, if the entire
+ * text should not fit into the details area, or if #GtkCalendar:show-details
+ * is not set.
+ *
+ * The size of the details area can be restricted by setting the
+ * #GtkCalendar:detail-width-chars and #GtkCalendar:detail-height-rows
+ * properties.
+ *
+ * Since: 2.14
+ */
+void
+gtk_calendar_set_detail_func (GtkCalendar *calendar,
+ GtkCalendarDetailFunc func,
+ gpointer data,
+ GDestroyNotify destroy)
+{
+ GtkCalendarPrivate *priv;
+
+ g_return_if_fail (GTK_IS_CALENDAR (calendar));
+
+ priv = GTK_CALENDAR_GET_PRIVATE (calendar);
+
+ if (priv->detail_func_destroy)
+ priv->detail_func_destroy (priv->detail_func_user_data);
+
+ priv->detail_func = func;
+ priv->detail_func_user_data = data;
+ priv->detail_func_destroy = destroy;
+
+ gtk_widget_set_has_tooltip (GTK_WIDGET (calendar),
+ NULL != priv->detail_func);
+ gtk_widget_queue_resize (GTK_WIDGET (calendar));
+}
+
+/**
+ * gtk_calendar_set_detail_width_chars:
+ * @calendar: a #GtkCalendar.
+ * @chars: detail width in characters.
+ *
+ * Updates the width of detail cells.
+ * See #GtkCalendar:detail-width-chars.
+ *
+ * Since: 2.14
+ */
+void
+gtk_calendar_set_detail_width_chars (GtkCalendar *calendar,
+ gint chars)
+{
+ GtkCalendarPrivate *priv;
+
+ g_return_if_fail (GTK_IS_CALENDAR (calendar));
+
+ priv = GTK_CALENDAR_GET_PRIVATE (calendar);
+
+ if (chars != priv->detail_width_chars)
+ {
+ priv->detail_width_chars = chars;
+ g_object_notify (G_OBJECT (calendar), "detail-width-chars");
+ gtk_widget_queue_resize_no_redraw (GTK_WIDGET (calendar));
+ }
+}
+
+/**
+ * gtk_calendar_set_detail_height_rows:
+ * @calendar: a #GtkCalendar.
+ * @rows: detail height in rows.
+ *
+ * Updates the height of detail cells.
+ * See #GtkCalendar:detail-height-rows.
+ *
+ * Since: 2.14
+ */
+void
+gtk_calendar_set_detail_height_rows (GtkCalendar *calendar,
+ gint rows)
+{
+ GtkCalendarPrivate *priv;
+
+ g_return_if_fail (GTK_IS_CALENDAR (calendar));
+
+ priv = GTK_CALENDAR_GET_PRIVATE (calendar);
+
+ if (rows != priv->detail_height_rows)
+ {
+ priv->detail_height_rows = rows;
+ g_object_notify (G_OBJECT (calendar), "detail-height-rows");
+ gtk_widget_queue_resize_no_redraw (GTK_WIDGET (calendar));
+ }
+}
+
+/**
+ * gtk_calendar_get_detail_width_chars:
+ * @calendar: a #GtkCalendar.
+ *
+ * Queries the width of detail cells, in characters.
+ * See #GtkCalendar:detail-width-chars.
+ *
+ * Since: 2.14
+ *
+ * Return value: The width of detail cells, in characters.
+ */
+gint
+gtk_calendar_get_detail_width_chars (GtkCalendar *calendar)
+{
+ g_return_val_if_fail (GTK_IS_CALENDAR (calendar), 0);
+ return GTK_CALENDAR_GET_PRIVATE (calendar)->detail_width_chars;
+}
+
+/**
+ * gtk_calendar_get_detail_height_rows:
+ * @calendar: a #GtkCalendar.
+ *
+ * Queries the height of detail cells, in rows.
+ * See #GtkCalendar:detail-width-chars.
+ *
+ * Since: 2.14
+ *
+ * Return value: The height of detail cells, in rows.
+ */
+gint
+gtk_calendar_get_detail_height_rows (GtkCalendar *calendar)
+{
+ g_return_val_if_fail (GTK_IS_CALENDAR (calendar), 0);
+ return GTK_CALENDAR_GET_PRIVATE (calendar)->detail_height_rows;
+}
+
/**
* gtk_calendar_freeze:
* @calendar: a #GtkCalendar
*
* 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)