1998-09-30 Federico Mena Quintero <federico@nuclecu.unam.mx> * year-view.c (mark_current_day): New function to mark the current day in the year view. * mark.c: Removed mark_current_day from here. svn path=/trunk/; revision=418
270 lines
6.8 KiB
C
270 lines
6.8 KiB
C
/* Functions to mark calendars
|
|
*
|
|
* Copyright (C) 1998 Red Hat Software, Inc.
|
|
*
|
|
* Author: Federico Mena <federico@nuclecu.unam.mx>
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include "gnome-cal.h"
|
|
#include "main.h"
|
|
#include "mark.h"
|
|
#include "timeutil.h"
|
|
|
|
|
|
/* Frees the specified data when an object is destroyed */
|
|
static void
|
|
free_data (GtkObject *object, gpointer data)
|
|
{
|
|
g_free (data);
|
|
}
|
|
|
|
/* If the array of "marked" attributes for the days in a a month item has not been created yet, this
|
|
* function creates the array and clears it. Otherwise, it just returns the existing array.
|
|
*/
|
|
static char *
|
|
get_attributes (GnomeMonthItem *mitem)
|
|
{
|
|
char *attrs;
|
|
|
|
attrs = gtk_object_get_data (GTK_OBJECT (mitem), "day_mark_attributes");
|
|
|
|
if (!attrs) {
|
|
attrs = g_new0 (char, 42);
|
|
gtk_object_set_data (GTK_OBJECT (mitem), "day_mark_attributes", attrs);
|
|
gtk_signal_connect (GTK_OBJECT (mitem), "destroy",
|
|
(GtkSignalFunc) free_data,
|
|
attrs);
|
|
}
|
|
|
|
return attrs;
|
|
}
|
|
|
|
void
|
|
colorify_month_item (GnomeMonthItem *mitem, GetColorFunc func, gpointer func_data)
|
|
{
|
|
g_return_if_fail (mitem != NULL);
|
|
g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
|
|
g_return_if_fail (func != NULL);
|
|
|
|
unmark_month_item (mitem);
|
|
|
|
/* We have to do this in several calls to gnome_canvas_item_set(), as color_spec_from_prop()
|
|
* returns a pointer to a static string -- and we need several values.
|
|
*/
|
|
|
|
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
|
|
"heading_color", (* func) (COLOR_PROP_HEADING_COLOR, func_data),
|
|
NULL);
|
|
|
|
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
|
|
"outline_color", (* func) (COLOR_PROP_OUTLINE_COLOR, func_data),
|
|
NULL);
|
|
|
|
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
|
|
"day_box_color", (* func) (COLOR_PROP_EMPTY_DAY_BG, func_data),
|
|
NULL);
|
|
|
|
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
|
|
"day_color", (* func) (COLOR_PROP_DAY_FG, func_data),
|
|
NULL);
|
|
}
|
|
|
|
/* In the month item, marks all the days that are touched by the specified time span. Assumes that
|
|
* the time span is completely contained within the month. The array of day attributes is modified
|
|
* accordingly.
|
|
*/
|
|
static void
|
|
mark_event_in_month (GnomeMonthItem *mitem, time_t start, time_t end)
|
|
{
|
|
struct tm tm;
|
|
int day_index;
|
|
|
|
tm = *localtime (&start);
|
|
|
|
for (; start <= end; start += 60 * 60 * 24) {
|
|
mktime (&tm); /* normalize the time */
|
|
|
|
/* Figure out the day index that corresponds to this time */
|
|
|
|
day_index = gnome_month_item_day2index (mitem, tm.tm_mday);
|
|
g_assert (day_index >= 0);
|
|
|
|
/* Mark the day box */
|
|
|
|
mark_month_item_index (mitem, day_index, default_color_func, NULL);
|
|
|
|
/* Next day */
|
|
|
|
tm.tm_mday++;
|
|
}
|
|
}
|
|
|
|
void
|
|
mark_month_item (GnomeMonthItem *mitem, Calendar *cal)
|
|
{
|
|
time_t month_begin, month_end;
|
|
GList *list, *l;
|
|
CalendarObject *co;
|
|
|
|
g_return_if_fail (mitem != NULL);
|
|
g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
|
|
g_return_if_fail (cal != NULL);
|
|
|
|
month_begin = time_month_begin (time_from_day (mitem->year, mitem->month, 1));
|
|
month_end = time_month_end (month_begin);
|
|
|
|
list = calendar_get_events_in_range (cal, month_begin, month_end);
|
|
|
|
for (l = list; l; l = l->next) {
|
|
co = l->data;
|
|
|
|
/* We clip the event's start and end times to the month's limits */
|
|
|
|
mark_event_in_month (mitem, MAX (co->ev_start, month_begin), MIN (co->ev_end, month_end));
|
|
}
|
|
|
|
calendar_destroy_event_list (list);
|
|
}
|
|
|
|
void
|
|
mark_month_item_index (GnomeMonthItem *mitem, int index, GetColorFunc func, gpointer func_data)
|
|
{
|
|
char *attrs;
|
|
GnomeCanvasItem *item;
|
|
|
|
g_return_if_fail (mitem != NULL);
|
|
g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
|
|
g_return_if_fail ((index >= 0) && (index < 42));
|
|
g_return_if_fail (func != NULL);
|
|
|
|
attrs = get_attributes (mitem);
|
|
|
|
attrs[index] = TRUE;
|
|
|
|
item = gnome_month_item_num2child (mitem, GNOME_MONTH_ITEM_DAY_BOX + index);
|
|
gnome_canvas_item_set (item,
|
|
"fill_color", (* func) (COLOR_PROP_MARK_DAY_BG, func_data),
|
|
NULL);
|
|
}
|
|
|
|
void
|
|
unmark_month_item (GnomeMonthItem *mitem)
|
|
{
|
|
int i;
|
|
char *attrs;
|
|
GnomeCanvasItem *item;
|
|
|
|
g_return_if_fail (mitem != NULL);
|
|
g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
|
|
|
|
attrs = get_attributes (mitem);
|
|
|
|
/* Find marked days and unmark them by turning off their marked attribute flag and changing
|
|
* the color.
|
|
*/
|
|
|
|
for (i = 0; i < 42; i++)
|
|
if (attrs[i]) {
|
|
attrs[i] = FALSE;
|
|
|
|
item = gnome_month_item_num2child (mitem, GNOME_MONTH_ITEM_DAY_BOX + i);
|
|
gnome_canvas_item_set (item,
|
|
"fill_color", color_spec_from_prop (COLOR_PROP_EMPTY_DAY_BG),
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
/* Handles EnterNotify and LeaveNotify events from the month item's day groups, and performs
|
|
* appropriate prelighting.
|
|
*/
|
|
static gint
|
|
day_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data)
|
|
{
|
|
GnomeMonthItem *mitem;
|
|
GnomeCanvasItem *box;
|
|
int child_num, day;
|
|
GetColorFunc func;
|
|
gpointer func_data;
|
|
char *color;
|
|
char *attrs;
|
|
|
|
/* We only accept enters and leaves */
|
|
|
|
if (!((event->type == GDK_ENTER_NOTIFY) || (event->type == GDK_LEAVE_NOTIFY)))
|
|
return FALSE;
|
|
|
|
/* Get index information */
|
|
|
|
mitem = GNOME_MONTH_ITEM (data);
|
|
child_num = gnome_month_item_child2num (mitem, item);
|
|
day = gnome_month_item_num2day (mitem, child_num);
|
|
|
|
if (day == 0)
|
|
return FALSE; /* it was a day outside the month's range */
|
|
|
|
child_num -= GNOME_MONTH_ITEM_DAY_GROUP;
|
|
box = gnome_month_item_num2child (mitem, GNOME_MONTH_ITEM_DAY_BOX + child_num);
|
|
|
|
/* Get colors */
|
|
|
|
func = gtk_object_get_data (GTK_OBJECT (mitem), "prelight_color_func");
|
|
func_data = gtk_object_get_data (GTK_OBJECT (mitem), "prelight_color_data");
|
|
|
|
/* Now actually set the proper color in the item */
|
|
|
|
switch (event->type) {
|
|
case GDK_ENTER_NOTIFY:
|
|
color = (* func) (COLOR_PROP_PRELIGHT_DAY_BG, func_data);
|
|
gnome_canvas_item_set (box,
|
|
"fill_color", color,
|
|
NULL);
|
|
break;
|
|
|
|
case GDK_LEAVE_NOTIFY:
|
|
attrs = get_attributes (mitem);
|
|
color = (* func) (attrs[child_num] ? COLOR_PROP_MARK_DAY_BG : COLOR_PROP_EMPTY_DAY_BG,
|
|
func_data);
|
|
gnome_canvas_item_set (box,
|
|
"fill_color", color,
|
|
NULL);
|
|
break;
|
|
|
|
default:
|
|
g_assert_not_reached ();
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
month_item_prepare_prelight (GnomeMonthItem *mitem, GetColorFunc func, gpointer func_data)
|
|
{
|
|
GnomeCanvasItem *day_group;
|
|
int i;
|
|
|
|
g_return_if_fail (mitem != NULL);
|
|
g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
|
|
g_return_if_fail (func != NULL);
|
|
|
|
/* Store the function in the object data */
|
|
|
|
gtk_object_set_data (GTK_OBJECT (mitem), "prelight_color_func", func);
|
|
gtk_object_set_data (GTK_OBJECT (mitem), "prelight_color_data", func_data);
|
|
|
|
/* Connect the appropriate signals to perform prelighting */
|
|
|
|
for (i = 0; i < 42; i++) {
|
|
day_group = gnome_month_item_num2child (GNOME_MONTH_ITEM (mitem), GNOME_MONTH_ITEM_DAY_GROUP + i);
|
|
gtk_signal_connect (GTK_OBJECT (day_group), "event",
|
|
(GtkSignalFunc) day_event,
|
|
mitem);
|
|
}
|
|
}
|
|
|
|
char *
|
|
default_color_func (ColorProp propnum, gpointer data)
|
|
{
|
|
return color_spec_from_prop (propnum);
|
|
}
|