aboutsummaryrefslogtreecommitdiffstats
path: root/calendar
diff options
context:
space:
mode:
Diffstat (limited to 'calendar')
-rw-r--r--calendar/ChangeLog42
-rw-r--r--calendar/cal-util/calobj.c95
-rw-r--r--calendar/calobj.c95
-rw-r--r--calendar/eventedit.c4
-rw-r--r--calendar/gnome-cal.c3
-rw-r--r--calendar/gui/eventedit.c4
-rw-r--r--calendar/gui/gnome-cal.c3
-rw-r--r--calendar/pcs/calobj.c95
8 files changed, 308 insertions, 33 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index 6f338a09b2..121dd41dcd 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,3 +1,45 @@
+1999-04-01 Steve Murphy <murf@e-tools.com>
+
+ * calobj.c (weekdaynum): Added this routine so Monthly recurrences
+ use the weekday field as a simple integer for a single weekday.
+
+ * calobj.c (load_recur_monthly_pos): Call weekdaynum instead of
+ weekdaylist. The interface only lets the user input a single value
+ anyway.
+
+ * calobj.c (ical_object_to_vobject): instead of code to output day
+ names from a bit array, use instead the value as an int and output
+ a single dayname.
+
+ * calobj.c (ical_object_generate_events): first_week_day gets the
+ day int instead of the first entry in the bit field. I inserted a
+ fair chunk of code to avoid calling generate if the day is out of
+ range for a month. It may be unneccessary, because mktime will
+ turn the extra days into a valid date the next month. But not all
+ mktimes are equal, I fear.
+
+ * eventedit.c (ee_store_recur_rule_to_ical): For case 3,
+ (Monthly), I added code to set the interval slot of the recur
+ struct; without this value, selecting a monthly recursing, by
+ date, would lead to an infinite loop broken only by a failure to
+ alloc more memory. Also, in the "by position" case, both
+ u.month_pos and u.month_day were being assigned values. This is a
+ mistake, as they are both part of an union, and the same
+ thing. The weekday field should get the recur_rr_month_weekday
+ value.
+
+ * eventedit.c (ee_rp_init_rule): set default day from the weekday
+ field instead of the u.month_day field, which is really the
+ month_pos value.
+
+ * gnome-cal.c (gnome_calendar_tag_calendar): Month days start with
+ 1, not 0; thus, setting tm.tm_mday = 0, and then calling mktime
+ will generate a time corresponding to the end of the previous
+ month, which may have a mday anywhere from 28 to 31. The end time
+ just adds 1 to the month, so your end time may not cover the last
+ few days of this month, depending on what the biggest mday of last
+ month was. I changed it so tm_mday is set to 1 instead.
+
1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gncal-todo.c (convert_time_t_to_char): Made static. Make it use
diff --git a/calendar/cal-util/calobj.c b/calendar/cal-util/calobj.c
index 30d9b5f8ed..d4a17c8859 100644
--- a/calendar/cal-util/calobj.c
+++ b/calendar/cal-util/calobj.c
@@ -206,6 +206,36 @@ weekdaylist (iCalObject *o, char **str)
}
static void
+weekdaynum (iCalObject *o, char **str)
+{
+ int i;
+ struct {
+ char first_letter, second_letter;
+ int index;
+ } days [] = {
+ { 'S', 'U', 0 },
+ { 'M', 'O', 1 },
+ { 'T', 'U', 2 },
+ { 'W', 'E', 3 },
+ { 'T', 'H', 4 },
+ { 'F', 'R', 5 },
+ { 'S', 'A', 6 }
+ };
+
+ ignore_space (str);
+ do {
+ for (i = 0; i < 7; i++){
+ if (**str == days [i].first_letter && *(*str+1) == days [i].second_letter){
+ o->recur->weekday = i;
+ *str += 2;
+ if (**str == ' ')
+ (*str)++;
+ }
+ }
+ } while (isalpha (**str));
+}
+
+static void
ocurrencelist (iCalObject *o, char **str)
{
char *p;
@@ -287,7 +317,7 @@ static void
load_recur_monthly_pos (iCalObject *o, char **str)
{
ocurrencelist (o, str);
- weekdaylist (o, str);
+ weekdaynum (o, str);
}
static void
@@ -947,12 +977,9 @@ ical_object_to_vobject (iCalObject *ical)
sprintf (buffer, "%d%s ", nega ? -ical->recur->u.month_pos : ical->recur->u.month_pos,
nega ? "-" : "+");
strcat (result, buffer);
- for (i = 0; i < 7; i++){
- if (ical->recur->weekday & (1 << i)){
- sprintf (buffer, "%s ", recur_day_list [i]);
- strcat (result, buffer);
- }
- }
+ /* the gui is set up for a single day, not a set here in this case */
+ sprintf (buffer, "%s ", recur_day_list [ical->recur->weekday]);
+ strcat (result, buffer);
}
break;
@@ -1173,7 +1200,8 @@ ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendar
if (ico->recur->u.month_pos == 0)
return;
- first_week_day = ical_object_get_first_weekday (ico->recur->weekday);
+ first_week_day = /* ical_object_get_first_weekday (ico->recur->weekday); */
+ ico->recur->weekday; /* the i/f only lets you choose a single day of the week! */
/* This should not happen, but take it into account */
if (first_week_day == -1) {
@@ -1194,7 +1222,56 @@ ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendar
tm.tm_mday = (7 * (ico->recur->u.month_pos - ((week_day_start <= first_week_day ) ? 1 : 0))
- (week_day_start - first_week_day) + 1);
-
+ if( tm.tm_mday > 31 )
+ {
+ tm.tm_mday = 1;
+ tm.tm_mon += ico->recur->interval;
+ current = mktime (&tm);
+ continue;
+ }
+
+ switch( tm.tm_mon )
+ {
+ case 3:
+ case 5:
+ case 8:
+ case 10:
+ if( tm.tm_mday > 30 )
+ {
+ tm.tm_mday = 1;
+ tm.tm_mon += ico->recur->interval;
+ current = mktime (&tm);
+ continue;
+ }
+ break;
+ case 1:
+ if( ((tm.tm_year+1900)%4) == 0
+ && ((tm.tm_year+1900)%400) != 100
+ && ((tm.tm_year+1900)%400) != 200
+ && ((tm.tm_year+1900)%400) != 300 )
+ {
+
+ if( tm.tm_mday > 29 )
+ {
+ tm.tm_mday = 1;
+ tm.tm_mon += ico->recur->interval;
+ current = mktime (&tm);
+ continue;
+ }
+ }
+ else
+ {
+ if( tm.tm_mday > 28 )
+ {
+ tm.tm_mday = 1;
+ tm.tm_mon += ico->recur->interval;
+ current = mktime (&tm);
+ continue;
+ }
+ }
+ break;
+ }
+
t = mktime (&tm);
if (time_in_range (t, start, end) && recur_in_range (current, ico->recur))
diff --git a/calendar/calobj.c b/calendar/calobj.c
index 30d9b5f8ed..d4a17c8859 100644
--- a/calendar/calobj.c
+++ b/calendar/calobj.c
@@ -206,6 +206,36 @@ weekdaylist (iCalObject *o, char **str)
}
static void
+weekdaynum (iCalObject *o, char **str)
+{
+ int i;
+ struct {
+ char first_letter, second_letter;
+ int index;
+ } days [] = {
+ { 'S', 'U', 0 },
+ { 'M', 'O', 1 },
+ { 'T', 'U', 2 },
+ { 'W', 'E', 3 },
+ { 'T', 'H', 4 },
+ { 'F', 'R', 5 },
+ { 'S', 'A', 6 }
+ };
+
+ ignore_space (str);
+ do {
+ for (i = 0; i < 7; i++){
+ if (**str == days [i].first_letter && *(*str+1) == days [i].second_letter){
+ o->recur->weekday = i;
+ *str += 2;
+ if (**str == ' ')
+ (*str)++;
+ }
+ }
+ } while (isalpha (**str));
+}
+
+static void
ocurrencelist (iCalObject *o, char **str)
{
char *p;
@@ -287,7 +317,7 @@ static void
load_recur_monthly_pos (iCalObject *o, char **str)
{
ocurrencelist (o, str);
- weekdaylist (o, str);
+ weekdaynum (o, str);
}
static void
@@ -947,12 +977,9 @@ ical_object_to_vobject (iCalObject *ical)
sprintf (buffer, "%d%s ", nega ? -ical->recur->u.month_pos : ical->recur->u.month_pos,
nega ? "-" : "+");
strcat (result, buffer);
- for (i = 0; i < 7; i++){
- if (ical->recur->weekday & (1 << i)){
- sprintf (buffer, "%s ", recur_day_list [i]);
- strcat (result, buffer);
- }
- }
+ /* the gui is set up for a single day, not a set here in this case */
+ sprintf (buffer, "%s ", recur_day_list [ical->recur->weekday]);
+ strcat (result, buffer);
}
break;
@@ -1173,7 +1200,8 @@ ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendar
if (ico->recur->u.month_pos == 0)
return;
- first_week_day = ical_object_get_first_weekday (ico->recur->weekday);
+ first_week_day = /* ical_object_get_first_weekday (ico->recur->weekday); */
+ ico->recur->weekday; /* the i/f only lets you choose a single day of the week! */
/* This should not happen, but take it into account */
if (first_week_day == -1) {
@@ -1194,7 +1222,56 @@ ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendar
tm.tm_mday = (7 * (ico->recur->u.month_pos - ((week_day_start <= first_week_day ) ? 1 : 0))
- (week_day_start - first_week_day) + 1);
-
+ if( tm.tm_mday > 31 )
+ {
+ tm.tm_mday = 1;
+ tm.tm_mon += ico->recur->interval;
+ current = mktime (&tm);
+ continue;
+ }
+
+ switch( tm.tm_mon )
+ {
+ case 3:
+ case 5:
+ case 8:
+ case 10:
+ if( tm.tm_mday > 30 )
+ {
+ tm.tm_mday = 1;
+ tm.tm_mon += ico->recur->interval;
+ current = mktime (&tm);
+ continue;
+ }
+ break;
+ case 1:
+ if( ((tm.tm_year+1900)%4) == 0
+ && ((tm.tm_year+1900)%400) != 100
+ && ((tm.tm_year+1900)%400) != 200
+ && ((tm.tm_year+1900)%400) != 300 )
+ {
+
+ if( tm.tm_mday > 29 )
+ {
+ tm.tm_mday = 1;
+ tm.tm_mon += ico->recur->interval;
+ current = mktime (&tm);
+ continue;
+ }
+ }
+ else
+ {
+ if( tm.tm_mday > 28 )
+ {
+ tm.tm_mday = 1;
+ tm.tm_mon += ico->recur->interval;
+ current = mktime (&tm);
+ continue;
+ }
+ }
+ break;
+ }
+
t = mktime (&tm);
if (time_in_range (t, start, end) && recur_in_range (current, ico->recur))
diff --git a/calendar/eventedit.c b/calendar/eventedit.c
index abd7670e8a..e97e39e8a2 100644
--- a/calendar/eventedit.c
+++ b/calendar/eventedit.c
@@ -580,7 +580,7 @@ ee_store_recur_rule_to_ical (EventEditor *ee)
ical->recur->u.month_pos =
option_menu_active_number (ee->recur_rr_month_day);
- ical->recur->u.month_day =
+ ical->recur->weekday =
option_menu_active_number (ee->recur_rr_month_weekday);
ical->recur->interval =
gtk_spin_button_get_value_as_int (
@@ -1014,7 +1014,7 @@ ee_rp_init_rule (EventEditor *ee)
page = 3;
month_period = interval;
def_pos = ee->ical->recur->u.month_pos;
- default_day = ee->ical->recur->u.month_day;
+ default_day = ee->ical->recur->weekday; /* you can't use u.month_pos and u.month_day-- it's a union... */
break;
case RECUR_MONTHLY_BY_DAY:
diff --git a/calendar/gnome-cal.c b/calendar/gnome-cal.c
index f589d0fe28..89d6998e3e 100644
--- a/calendar/gnome-cal.c
+++ b/calendar/gnome-cal.c
@@ -442,7 +442,8 @@ gnome_calendar_tag_calendar (GnomeCalendar *cal, GtkCalendar *gtk_cal)
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
- tm.tm_mday = 0;
+ tm.tm_mday = 1; /* setting this to zero is a no-no; it will set mktime back to the end of the
+ previous month, which may be 28,29,30; this may chop some days from the calendar */
tm.tm_mon = gtk_cal->month;
tm.tm_year = gtk_cal->year - 1900;
tm.tm_isdst= -1;
diff --git a/calendar/gui/eventedit.c b/calendar/gui/eventedit.c
index abd7670e8a..e97e39e8a2 100644
--- a/calendar/gui/eventedit.c
+++ b/calendar/gui/eventedit.c
@@ -580,7 +580,7 @@ ee_store_recur_rule_to_ical (EventEditor *ee)
ical->recur->u.month_pos =
option_menu_active_number (ee->recur_rr_month_day);
- ical->recur->u.month_day =
+ ical->recur->weekday =
option_menu_active_number (ee->recur_rr_month_weekday);
ical->recur->interval =
gtk_spin_button_get_value_as_int (
@@ -1014,7 +1014,7 @@ ee_rp_init_rule (EventEditor *ee)
page = 3;
month_period = interval;
def_pos = ee->ical->recur->u.month_pos;
- default_day = ee->ical->recur->u.month_day;
+ default_day = ee->ical->recur->weekday; /* you can't use u.month_pos and u.month_day-- it's a union... */
break;
case RECUR_MONTHLY_BY_DAY:
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index f589d0fe28..89d6998e3e 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -442,7 +442,8 @@ gnome_calendar_tag_calendar (GnomeCalendar *cal, GtkCalendar *gtk_cal)
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
- tm.tm_mday = 0;
+ tm.tm_mday = 1; /* setting this to zero is a no-no; it will set mktime back to the end of the
+ previous month, which may be 28,29,30; this may chop some days from the calendar */
tm.tm_mon = gtk_cal->month;
tm.tm_year = gtk_cal->year - 1900;
tm.tm_isdst= -1;
diff --git a/calendar/pcs/calobj.c b/calendar/pcs/calobj.c
index 30d9b5f8ed..d4a17c8859 100644
--- a/calendar/pcs/calobj.c
+++ b/calendar/pcs/calobj.c
@@ -206,6 +206,36 @@ weekdaylist (iCalObject *o, char **str)
}
static void
+weekdaynum (iCalObject *o, char **str)
+{
+ int i;
+ struct {
+ char first_letter, second_letter;
+ int index;
+ } days [] = {
+ { 'S', 'U', 0 },
+ { 'M', 'O', 1 },
+ { 'T', 'U', 2 },
+ { 'W', 'E', 3 },
+ { 'T', 'H', 4 },
+ { 'F', 'R', 5 },
+ { 'S', 'A', 6 }
+ };
+
+ ignore_space (str);
+ do {
+ for (i = 0; i < 7; i++){
+ if (**str == days [i].first_letter && *(*str+1) == days [i].second_letter){
+ o->recur->weekday = i;
+ *str += 2;
+ if (**str == ' ')
+ (*str)++;
+ }
+ }
+ } while (isalpha (**str));
+}
+
+static void
ocurrencelist (iCalObject *o, char **str)
{
char *p;
@@ -287,7 +317,7 @@ static void
load_recur_monthly_pos (iCalObject *o, char **str)
{
ocurrencelist (o, str);
- weekdaylist (o, str);
+ weekdaynum (o, str);
}
static void
@@ -947,12 +977,9 @@ ical_object_to_vobject (iCalObject *ical)
sprintf (buffer, "%d%s ", nega ? -ical->recur->u.month_pos : ical->recur->u.month_pos,
nega ? "-" : "+");
strcat (result, buffer);
- for (i = 0; i < 7; i++){
- if (ical->recur->weekday & (1 << i)){
- sprintf (buffer, "%s ", recur_day_list [i]);
- strcat (result, buffer);
- }
- }
+ /* the gui is set up for a single day, not a set here in this case */
+ sprintf (buffer, "%s ", recur_day_list [ical->recur->weekday]);
+ strcat (result, buffer);
}
break;
@@ -1173,7 +1200,8 @@ ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendar
if (ico->recur->u.month_pos == 0)
return;
- first_week_day = ical_object_get_first_weekday (ico->recur->weekday);
+ first_week_day = /* ical_object_get_first_weekday (ico->recur->weekday); */
+ ico->recur->weekday; /* the i/f only lets you choose a single day of the week! */
/* This should not happen, but take it into account */
if (first_week_day == -1) {
@@ -1194,7 +1222,56 @@ ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendar
tm.tm_mday = (7 * (ico->recur->u.month_pos - ((week_day_start <= first_week_day ) ? 1 : 0))
- (week_day_start - first_week_day) + 1);
-
+ if( tm.tm_mday > 31 )
+ {
+ tm.tm_mday = 1;
+ tm.tm_mon += ico->recur->interval;
+ current = mktime (&tm);
+ continue;
+ }
+
+ switch( tm.tm_mon )
+ {
+ case 3:
+ case 5:
+ case 8:
+ case 10:
+ if( tm.tm_mday > 30 )
+ {
+ tm.tm_mday = 1;
+ tm.tm_mon += ico->recur->interval;
+ current = mktime (&tm);
+ continue;
+ }
+ break;
+ case 1:
+ if( ((tm.tm_year+1900)%4) == 0
+ && ((tm.tm_year+1900)%400) != 100
+ && ((tm.tm_year+1900)%400) != 200
+ && ((tm.tm_year+1900)%400) != 300 )
+ {
+
+ if( tm.tm_mday > 29 )
+ {
+ tm.tm_mday = 1;
+ tm.tm_mon += ico->recur->interval;
+ current = mktime (&tm);
+ continue;
+ }
+ }
+ else
+ {
+ if( tm.tm_mday > 28 )
+ {
+ tm.tm_mday = 1;
+ tm.tm_mon += ico->recur->interval;
+ current = mktime (&tm);
+ continue;
+ }
+ }
+ break;
+ }
+
t = mktime (&tm);
if (time_in_range (t, start, end) && recur_in_range (current, ico->recur))