From 806673dd9b256e879d1483255886a8881d1d8115 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Thu, 14 Feb 2013 10:52:44 +0100 Subject: calendar.c: Rename to "ui-calendar.c" This unit belongs to the presentation layer -- rename the file accordingly. Also, rename calendar_*() to ui_calendar_*(). Signed-off-by: Lukas Fleischer --- src/Makefile.am | 2 +- src/calcurse.c | 40 +-- src/calcurse.h | 44 +-- src/calendar.c | 915 ------------------------------------------------------ src/config.c | 12 +- src/custom.c | 4 +- src/day.c | 4 +- src/pcal.c | 10 +- src/ui-calendar.c | 915 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ui-day.c | 28 +- src/utils.c | 2 +- src/vars.c | 4 +- src/wins.c | 2 +- 13 files changed, 991 insertions(+), 991 deletions(-) delete mode 100644 src/calendar.c create mode 100644 src/ui-calendar.c diff --git a/src/Makefile.am b/src/Makefile.am index 438106d..44d1ae8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,7 +13,6 @@ calcurse_SOURCES = \ sha1.h \ apoint.c \ args.c \ - calendar.c \ config.c \ custom.c \ day.c \ @@ -31,6 +30,7 @@ calcurse_SOURCES = \ sha1.c \ sigs.c \ todo.c \ + ui-calendar.c \ ui-day.c \ ui-todo.c \ utf8.c \ diff --git a/src/calcurse.c b/src/calcurse.c index 227c83f..6fd2ecb 100644 --- a/src/calcurse.c +++ b/src/calcurse.c @@ -49,7 +49,7 @@ int count, reg; */ static struct day_items_nb do_storage(int day_changed) { - struct day_items_nb inday = day_process_storage(calendar_get_slctd_day(), + struct day_items_nb inday = day_process_storage(ui_calendar_get_slctd_day(), day_changed); if (day_changed) { @@ -92,8 +92,8 @@ static inline void key_generic_other_cmd(void) static inline void key_generic_goto(void) { wins_erase_status_bar(); - calendar_set_current_date(); - calendar_change_day(conf.input_datefmt); + ui_calendar_set_current_date(); + ui_calendar_change_day(conf.input_datefmt); inday = do_storage(1); wins_update(FLAG_CAL | FLAG_APP | FLAG_STA); } @@ -101,8 +101,8 @@ static inline void key_generic_goto(void) static inline void key_generic_goto_today(void) { wins_erase_status_bar(); - calendar_set_current_date(); - calendar_goto_today(); + ui_calendar_set_current_date(); + ui_calendar_goto_today(); inday = do_storage(1); wins_update(FLAG_CAL | FLAG_APP | FLAG_STA); } @@ -287,7 +287,7 @@ static inline void key_generic_import(void) { wins_erase_status_bar(); io_import_data(IO_IMPORT_ICAL, NULL); - calendar_monthly_view_cache_set_invalid(); + ui_calendar_monthly_view_cache_set_invalid(); inday = do_storage(0); wins_update(FLAG_ALL); } @@ -317,7 +317,7 @@ static inline void key_generic_export() static inline void key_generic_prev_day(void) { - calendar_move(DAY_PREV, count); + ui_calendar_move(DAY_PREV, count); inday = do_storage(1); wins_update(FLAG_CAL | FLAG_APP); } @@ -330,7 +330,7 @@ static inline void key_move_left(void) static inline void key_generic_next_day(void) { - calendar_move(DAY_NEXT, count); + ui_calendar_move(DAY_NEXT, count); inday = do_storage(1); wins_update(FLAG_CAL | FLAG_APP); } @@ -343,7 +343,7 @@ static inline void key_move_right(void) static inline void key_generic_prev_week(void) { - calendar_move(WEEK_PREV, count); + ui_calendar_move(WEEK_PREV, count); inday = do_storage(1); wins_update(FLAG_CAL | FLAG_APP); } @@ -370,7 +370,7 @@ static inline void key_move_up(void) static inline void key_generic_next_week(void) { - calendar_move(WEEK_NEXT, count); + ui_calendar_move(WEEK_NEXT, count); inday = do_storage(1); wins_update(FLAG_CAL | FLAG_APP); } @@ -397,28 +397,28 @@ static inline void key_move_down(void) static inline void key_generic_prev_month(void) { - calendar_move(MONTH_PREV, count); + ui_calendar_move(MONTH_PREV, count); inday = do_storage(1); wins_update(FLAG_CAL | FLAG_APP); } static inline void key_generic_next_month(void) { - calendar_move(MONTH_NEXT, count); + ui_calendar_move(MONTH_NEXT, count); inday = do_storage(1); wins_update(FLAG_CAL | FLAG_APP); } static inline void key_generic_prev_year(void) { - calendar_move(YEAR_PREV, count); + ui_calendar_move(YEAR_PREV, count); inday = do_storage(1); wins_update(FLAG_CAL | FLAG_APP); } static inline void key_generic_next_year(void) { - calendar_move(YEAR_NEXT, count); + ui_calendar_move(YEAR_NEXT, count); inday = do_storage(1); wins_update(FLAG_CAL | FLAG_APP); } @@ -426,7 +426,7 @@ static inline void key_generic_next_year(void) static inline void key_start_of_week(void) { if (wins_slctd() == CAL) { - calendar_move(WEEK_START, count); + ui_calendar_move(WEEK_START, count); inday = do_storage(1); wins_update(FLAG_CAL | FLAG_APP); } @@ -435,7 +435,7 @@ static inline void key_start_of_week(void) static inline void key_end_of_week(void) { if (wins_slctd() == CAL) { - calendar_move(WEEK_END, count); + ui_calendar_move(WEEK_END, count); inday = do_storage(1); wins_update(FLAG_CAL | FLAG_APP); } @@ -444,7 +444,7 @@ static inline void key_end_of_week(void) static inline void key_generic_scroll_up(void) { if (wins_slctd() == CAL) { - calendar_view_prev(); + ui_calendar_view_prev(); wins_update(FLAG_CAL | FLAG_APP); } } @@ -452,7 +452,7 @@ static inline void key_generic_scroll_up(void) static inline void key_generic_scroll_down(void) { if (wins_slctd() == CAL) { - calendar_view_next(); + ui_calendar_view_next(); wins_update(FLAG_CAL | FLAG_APP); } } @@ -519,7 +519,7 @@ int main(int argc, char **argv) cbreak(); /* control chars generate a signal */ noecho(); /* controls echoing of typed chars */ curs_set(0); /* make cursor invisible */ - calendar_set_current_date(); + ui_calendar_set_current_date(); notify_init_vars(); wins_get_config(); @@ -586,7 +586,7 @@ int main(int argc, char **argv) /* Start miscellaneous threads. */ if (notify_bar()) notify_start_main_thread(); - calendar_start_date_thread(); + ui_calendar_start_date_thread(); if (conf.periodic_save > 0) io_start_psave_thread(); diff --git a/src/calcurse.h b/src/calcurse.h index 22c4fe8..8d76bba 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -631,28 +631,28 @@ void apoint_paste_item(struct apoint *, long); int parse_args(int, char **); /* calendar.c */ -void calendar_view_next(void); -void calendar_view_prev(void); -void calendar_set_view(int); -int calendar_get_view(void); -void calendar_start_date_thread(void); -void calendar_stop_date_thread(void); -void calendar_set_current_date(void); -void calendar_set_first_day_of_week(enum wday); -void calendar_change_first_day_of_week(void); -unsigned calendar_week_begins_on_monday(void); -void calendar_store_current_date(struct date *); -void calendar_init_slctd_day(void); -struct date *calendar_get_slctd_day(void); -long calendar_get_slctd_day_sec(void); -void calendar_monthly_view_cache_set_invalid(void); -void calendar_update_panel(struct window *); -void calendar_goto_today(void); -void calendar_change_day(int); -void calendar_move(enum move, int); -long calendar_start_of_year(void); -long calendar_end_of_year(void); -const char *calendar_get_pom(time_t); +void ui_calendar_view_next(void); +void ui_calendar_view_prev(void); +void ui_calendar_set_view(int); +int ui_calendar_get_view(void); +void ui_calendar_start_date_thread(void); +void ui_calendar_stop_date_thread(void); +void ui_calendar_set_current_date(void); +void ui_calendar_set_first_day_of_week(enum wday); +void ui_calendar_change_first_day_of_week(void); +unsigned ui_calendar_week_begins_on_monday(void); +void ui_calendar_store_current_date(struct date *); +void ui_calendar_init_slctd_day(void); +struct date *ui_calendar_get_slctd_day(void); +long ui_calendar_get_slctd_day_sec(void); +void ui_calendar_monthly_view_cache_set_invalid(void); +void ui_calendar_update_panel(struct window *); +void ui_calendar_goto_today(void); +void ui_calendar_change_day(int); +void ui_calendar_move(enum move, int); +long ui_calendar_start_of_year(void); +long ui_calendar_end_of_year(void); +const char *ui_calendar_get_pom(time_t); /* config.c */ diff --git a/src/calendar.c b/src/calendar.c deleted file mode 100644 index cad9ad9..0000000 --- a/src/calendar.c +++ /dev/null @@ -1,915 +0,0 @@ -/* - * Calcurse - text-based organizer - * - * Copyright (c) 2004-2013 calcurse Development Team - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Send your feedback or comments to : misc@calcurse.org - * Calcurse home page : http://calcurse.org - * - */ - -#include -#include -#include -#include -#include -#include - -#include "calcurse.h" - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -#define EPOCH 90 -#define EPSILONg 279.403303 /* solar ecliptic long at EPOCH */ -#define RHOg 282.768422 /* solar ecliptic long of perigee at EPOCH */ -#define ECCEN 0.016713 /* solar orbit eccentricity */ -#define lzero 318.351648 /* lunar mean long at EPOCH */ -#define Pzero 36.340410 /* lunar mean long of perigee at EPOCH */ -#define Nzero 318.510107 /* lunar mean long of node at EPOCH */ - -#define ISLEAP(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) - -enum pom { - NO_POM, - FIRST_QUARTER, - FULL_MOON, - LAST_QUARTER, - NEW_MOON, - MOON_PHASES -}; - -static struct date today, slctd_day; -static unsigned calendar_view, week_begins_on_monday; -static pthread_mutex_t date_thread_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_t calendar_t_date; - -static void draw_monthly_view(struct window *, struct date *, unsigned); -static void draw_weekly_view(struct window *, struct date *, unsigned); -static void (*draw_calendar[CAL_VIEWS]) (struct window *, struct date *, - unsigned) = { -draw_monthly_view, draw_weekly_view}; - -static int monthly_view_cache[MAXDAYSPERMONTH]; -static int monthly_view_cache_valid = 0; -static int monthly_view_cache_month = 0; - -/* Switch between calendar views (monthly view is selected by default). */ -void calendar_view_next(void) -{ - calendar_view++; - if (calendar_view == CAL_VIEWS) - calendar_view = 0; -} - -void calendar_view_prev(void) -{ - if (calendar_view == 0) - calendar_view = CAL_VIEWS; - calendar_view--; -} - -void calendar_set_view(int view) -{ - calendar_view = (view < 0 || view >= CAL_VIEWS) ? CAL_MONTH_VIEW : view; -} - -int calendar_get_view(void) -{ - return (int)calendar_view; -} - -/* Thread needed to update current date in calendar. */ -/* ARGSUSED0 */ -static void *calendar_date_thread(void *arg) -{ - time_t actual, tomorrow; - - for (;;) { - tomorrow = (time_t) (get_today() + DAYINSEC); - - while ((actual = time(NULL)) < tomorrow) - sleep(tomorrow - actual); - - calendar_set_current_date(); - calendar_update_panel(&win[CAL]); - } - - return NULL; -} - -/* Launch the calendar date thread. */ -void calendar_start_date_thread(void) -{ - pthread_create(&calendar_t_date, NULL, calendar_date_thread, NULL); -} - -/* Stop the calendar date thread. */ -void calendar_stop_date_thread(void) -{ - if (calendar_t_date) { - pthread_cancel(calendar_t_date); - pthread_join(calendar_t_date, NULL); - } -} - -/* Set static variable today to current date */ -void calendar_set_current_date(void) -{ - time_t timer; - struct tm tm; - - timer = time(NULL); - localtime_r(&timer, &tm); - - pthread_mutex_lock(&date_thread_mutex); - today.dd = tm.tm_mday; - today.mm = tm.tm_mon + 1; - today.yyyy = tm.tm_year + 1900; - pthread_mutex_unlock(&date_thread_mutex); -} - -/* Needed to display sunday or monday as the first day of week in calendar. */ -void calendar_set_first_day_of_week(enum wday first_day) -{ - switch (first_day) { - case SUNDAY: - week_begins_on_monday = 0; - break; - case MONDAY: - week_begins_on_monday = 1; - break; - default: - ERROR_MSG(_("ERROR setting first day of week")); - week_begins_on_monday = 0; - /* NOTREACHED */ - } -} - -/* Swap first day of week in calendar. */ -void calendar_change_first_day_of_week(void) -{ - week_begins_on_monday = !week_begins_on_monday; -} - -/* Return 1 if week begins on monday, 0 otherwise. */ -unsigned calendar_week_begins_on_monday(void) -{ - return week_begins_on_monday; -} - -/* Fill in the given variable with the current date. */ -void calendar_store_current_date(struct date *date) -{ - pthread_mutex_lock(&date_thread_mutex); - *date = today; - pthread_mutex_unlock(&date_thread_mutex); -} - -/* This is to start at the current date in calendar. */ -void calendar_init_slctd_day(void) -{ - calendar_store_current_date(&slctd_day); -} - -/* Return the selected day in calendar */ -struct date *calendar_get_slctd_day(void) -{ - return &slctd_day; -} - -/* Returned value represents the selected day in calendar (in seconds) */ -long calendar_get_slctd_day_sec(void) -{ - return date2sec(slctd_day, 0, 0); -} - -static int calendar_get_wday(struct date *date) -{ - struct tm t; - - memset(&t, 0, sizeof(struct tm)); - t.tm_mday = date->dd; - t.tm_mon = date->mm - 1; - t.tm_year = date->yyyy - 1900; - - mktime(&t); - - return t.tm_wday; -} - -static unsigned months_to_days(unsigned month) -{ - return (month * 3057 - 3007) / 100; -} - -static long years_to_days(unsigned year) -{ - return year * 365L + year / 4 - year / 100 + year / 400; -} - -static long ymd_to_scalar(unsigned year, unsigned month, unsigned day) -{ - long scalar; - - scalar = day + months_to_days(month); - if (month > 2) - scalar -= ISLEAP(year) ? 1 : 2; - year--; - scalar += years_to_days(year); - - return scalar; -} - -/* - * Used to change date by adding a certain amount of days or weeks. - * Returns 0 on success, 1 otherwise. - */ -static int date_change(struct tm *date, int delta_month, int delta_day) -{ - struct tm t; - - t = *date; - t.tm_mon += delta_month; - t.tm_mday += delta_day; - - if (mktime(&t) == -1) - return 1; - else { - *date = t; - return 0; - } -} - -void calendar_monthly_view_cache_set_invalid(void) -{ - monthly_view_cache_valid = 0; -} - -/* Draw the monthly view inside calendar panel. */ -static void -draw_monthly_view(struct window *cwin, struct date *current_day, - unsigned sunday_first) -{ - const int OFFY = CALHEIGHT / 2 - (conf.compact_panels ? 3 : 1); - struct date check_day; - int c_day, c_day_1, day_1_sav, numdays, j; - unsigned yr, mo; - int OFFX, SBAR_WIDTH, ofs_x, ofs_y; - int item_this_day = 0; - - mo = slctd_day.mm; - yr = slctd_day.yyyy; - - /* offset for centering calendar in window */ - SBAR_WIDTH = wins_sbar_width(); - OFFX = (SBAR_WIDTH - 27) / 2; - ofs_y = OFFY; - ofs_x = OFFX; - - /* checking the number of days in february */ - numdays = days[mo - 1]; - if (2 == mo && ISLEAP(yr)) - ++numdays; - - /* - * the first calendar day will be monday or sunday, depending on - * 'week_begins_on_monday' value - */ - c_day_1 = (int)((ymd_to_scalar(yr, mo, 1 + sunday_first) - (long)1) % 7L); - - /* Write the current month and year on top of the calendar */ - WINS_CALENDAR_LOCK; - custom_apply_attr(cwin->p, ATTR_HIGHEST); - mvwprintw(cwin->p, ofs_y, - (SBAR_WIDTH - (strlen(_(monthnames[mo - 1])) + 5)) / 2, - "%s %d", _(monthnames[mo - 1]), slctd_day.yyyy); - custom_remove_attr(cwin->p, ATTR_HIGHEST); - ++ofs_y; - - /* print the days, with regards to the first day of the week */ - custom_apply_attr(cwin->p, ATTR_HIGHEST); - for (j = 0; j < WEEKINDAYS; j++) { - mvwaddstr(cwin->p, ofs_y, ofs_x + 4 * j, _(daynames[1 + j - sunday_first])); - } - custom_remove_attr(cwin->p, ATTR_HIGHEST); - WINS_CALENDAR_UNLOCK; - - day_1_sav = (c_day_1 + 1) * 3 + c_day_1 - 7; - - /* invalidate cache if a new month is selected */ - if (yr * YEARINMONTHS + mo != monthly_view_cache_month) { - monthly_view_cache_month = yr * YEARINMONTHS + mo; - monthly_view_cache_valid = 0; - } - - for (c_day = 1; c_day <= numdays; ++c_day, ++c_day_1, c_day_1 %= 7) { - check_day.dd = c_day; - check_day.mm = slctd_day.mm; - check_day.yyyy = slctd_day.yyyy; - - /* check if the day contains an event or an appointment */ - if (monthly_view_cache_valid) { - item_this_day = monthly_view_cache[c_day - 1]; - } - else { - item_this_day = monthly_view_cache[c_day - 1] = - day_check_if_item(check_day); - } - - /* Go to next line, the week is over. */ - if (!c_day_1 && 1 != c_day) { - ofs_y++; - ofs_x = OFFX - day_1_sav - 4 * c_day; - } - - WINS_CALENDAR_LOCK; - if (c_day == current_day->dd - && current_day->mm == slctd_day.mm - && current_day->yyyy == slctd_day.yyyy - && current_day->dd != slctd_day.dd) { - /* This is today, so print it in yellow. */ - custom_apply_attr(cwin->p, ATTR_LOWEST); - mvwprintw(cwin->p, ofs_y + 1, - ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); - custom_remove_attr(cwin->p, ATTR_LOWEST); - } else if (c_day == slctd_day.dd) { - /* This is the selected day, print it according to user's theme. */ - custom_apply_attr(cwin->p, ATTR_HIGHEST); - mvwprintw(cwin->p, ofs_y + 1, - ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); - custom_remove_attr(cwin->p, ATTR_HIGHEST); - } else if (item_this_day) { - custom_apply_attr(cwin->p, ATTR_LOW); - mvwprintw(cwin->p, ofs_y + 1, - ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); - custom_remove_attr(cwin->p, ATTR_LOW); - } else { - /* otherwise, print normal days in black */ - mvwprintw(cwin->p, ofs_y + 1, - ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); - } - WINS_CALENDAR_UNLOCK; - } - - monthly_view_cache_valid = 1; -} - -static int weeknum(const struct tm *t, int firstweekday) -{ - int wday, wnum; - - wday = t->tm_wday; - if (firstweekday == MONDAY) { - if (wday == SUNDAY) - wday = 6; - else - wday--; - } - wnum = ((t->tm_yday + WEEKINDAYS - wday) / WEEKINDAYS); - if (wnum < 0) - wnum = 0; - - return wnum; -} - -/* - * Compute the week number according to ISO 8601. - */ -static int ISO8601weeknum(const struct tm *t) -{ - int wnum, jan1day; - - wnum = weeknum(t, MONDAY); - - jan1day = t->tm_wday - (t->tm_yday % WEEKINDAYS); - if (jan1day < 0) - jan1day += WEEKINDAYS; - - switch (jan1day) { - case MONDAY: - break; - case TUESDAY: - case WEDNESDAY: - case THURSDAY: - wnum++; - break; - case FRIDAY: - case SATURDAY: - case SUNDAY: - if (wnum == 0) { - /* Get week number of last week of last year. */ - struct tm dec31ly; /* 12/31 last year */ - - dec31ly = *t; - dec31ly.tm_year--; - dec31ly.tm_mon = 11; - dec31ly.tm_mday = 31; - dec31ly.tm_wday = (jan1day == SUNDAY) ? 6 : jan1day - 1; - dec31ly.tm_yday = 364 + ISLEAP(dec31ly.tm_year + 1900); - wnum = ISO8601weeknum(&dec31ly); - } - break; - } - - if (t->tm_mon == 11) { - int wday, mday; - - wday = t->tm_wday; - mday = t->tm_mday; - if ((wday == MONDAY && (mday >= 29 && mday <= 31)) - || (wday == TUESDAY && (mday == 30 || mday == 31)) - || (wday == WEDNESDAY && mday == 31)) - wnum = 1; - } - - return wnum; -} - -/* Draw the weekly view inside calendar panel. */ -static void -draw_weekly_view(struct window *cwin, struct date *current_day, - unsigned sunday_first) -{ -#define DAYSLICESNO 6 - const int WCALWIDTH = 30; - const int OFFY = CALHEIGHT / 2 - (conf.compact_panels ? 3 : 1); - struct tm t; - int OFFX, j, c_wday, days_to_remove, weeknum; - - OFFX = (wins_sbar_width() - WCALWIDTH) / 2 + 1; - - /* Fill in a tm structure with the first day of the selected week. */ - c_wday = calendar_get_wday(&slctd_day); - if (sunday_first) - days_to_remove = c_wday; - else - days_to_remove = c_wday == 0 ? WEEKINDAYS - 1 : c_wday - 1; - - memset(&t, 0, sizeof(struct tm)); - t.tm_mday = slctd_day.dd; - t.tm_mon = slctd_day.mm - 1; - t.tm_year = slctd_day.yyyy - 1900; - mktime(&t); - date_change(&t, 0, -days_to_remove); - - /* Print the week number. */ - weeknum = ISO8601weeknum(&t); - WINS_CALENDAR_LOCK; - custom_apply_attr(cwin->p, ATTR_HIGHEST); - mvwprintw(cwin->p, conf.compact_panels ? 0 : 2, cwin->w - 9, "(# %02d)", - weeknum); - custom_remove_attr(cwin->p, ATTR_HIGHEST); - WINS_CALENDAR_UNLOCK; - - /* Now draw calendar view. */ - for (j = 0; j < WEEKINDAYS; j++) { - struct date date; - unsigned attr, item_this_day; - int i, slices[DAYSLICESNO]; - - /* print the day names, with regards to the first day of the week */ - custom_apply_attr(cwin->p, ATTR_HIGHEST); - mvwaddstr(cwin->p, OFFY, OFFX + 4 * j, _(daynames[1 + j - sunday_first])); - custom_remove_attr(cwin->p, ATTR_HIGHEST); - - /* Check if the day to be printed has an item or not. */ - date.dd = t.tm_mday; - date.mm = t.tm_mon + 1; - date.yyyy = t.tm_year + 1900; - item_this_day = day_check_if_item(date); - - /* Print the day numbers with appropriate decoration. */ - if (t.tm_mday == current_day->dd - && current_day->mm == slctd_day.mm - && current_day->yyyy == slctd_day.yyyy - && current_day->dd != slctd_day.dd) - attr = ATTR_LOWEST; /* today, but not selected */ - else if (t.tm_mday == slctd_day.dd) - attr = ATTR_HIGHEST; /* selected day */ - else if (item_this_day) - attr = ATTR_LOW; - else - attr = 0; - - WINS_CALENDAR_LOCK; - if (attr) - custom_apply_attr(cwin->p, attr); - mvwprintw(cwin->p, OFFY + 1, OFFX + 1 + 4 * j, "%02d", t.tm_mday); - if (attr) - custom_remove_attr(cwin->p, attr); - WINS_CALENDAR_UNLOCK; - - /* Draw slices indicating appointment times. */ - memset(slices, 0, DAYSLICESNO * sizeof *slices); - if (day_chk_busy_slices(date, DAYSLICESNO, slices)) { - for (i = 0; i < DAYSLICESNO; i++) { - if (j != WEEKINDAYS - 1 && i != DAYSLICESNO - 1) { - WINS_CALENDAR_LOCK; - mvwhline(cwin->p, OFFY + 2 + i, OFFX + 3 + 4 * j, ACS_S9, 2); - WINS_CALENDAR_UNLOCK; - } - if (slices[i]) { - int highlight; - - highlight = (t.tm_mday == slctd_day.dd) ? 1 : 0; - WINS_CALENDAR_LOCK; - if (highlight) - custom_apply_attr(cwin->p, attr); - wattron(cwin->p, A_REVERSE); - mvwaddstr(cwin->p, OFFY + 2 + i, OFFX + 1 + 4 * j, " "); - mvwaddstr(cwin->p, OFFY + 2 + i, OFFX + 2 + 4 * j, " "); - wattroff(cwin->p, A_REVERSE); - if (highlight) - custom_remove_attr(cwin->p, attr); - WINS_CALENDAR_UNLOCK; - } - } - } - - /* get next day */ - date_change(&t, 0, 1); - } - - /* Draw marks to indicate midday on the sides of the calendar. */ - WINS_CALENDAR_LOCK; - custom_apply_attr(cwin->p, ATTR_HIGHEST); - mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, OFFX, ACS_S9, 1); - mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, - OFFX + WCALWIDTH - 3, ACS_S9, 1); - custom_remove_attr(cwin->p, ATTR_HIGHEST); - WINS_CALENDAR_UNLOCK; - -#undef DAYSLICESNO -} - -/* Function used to display the calendar panel. */ -void calendar_update_panel(struct window *cwin) -{ - struct date current_day; - unsigned sunday_first; - - calendar_store_current_date(¤t_day); - - WINS_CALENDAR_LOCK; - erase_window_part(cwin->p, 1, conf.compact_panels ? 1 : 3, cwin->w - 2, - cwin->h - 2); - if (!conf.compact_panels) - mvwhline(cwin->p, 2, 1, ACS_HLINE, cwin->w - 2); - WINS_CALENDAR_UNLOCK; - - sunday_first = calendar_week_begins_on_monday()? 0 : 1; - - draw_calendar[calendar_view] (cwin, ¤t_day, sunday_first); - - wnoutrefresh(cwin->p); -} - -/* Set the selected day in calendar to current day. */ -void calendar_goto_today(void) -{ - struct date today; - - calendar_store_current_date(&today); - slctd_day.dd = today.dd; - slctd_day.mm = today.mm; - slctd_day.yyyy = today.yyyy; -} - -/* - * Ask for a date to jump to, then check the correctness of that date - * and jump to it. - * If the entered date is empty, automatically jump to the current date. - * slctd_day is updated with the newly selected date. - */ -void calendar_change_day(int datefmt) -{ -#define LDAY 11 - char selected_day[LDAY] = ""; - char outstr[BUFSIZ]; - int dday, dmonth, dyear; - int wrong_day = 1; - const char *mesg_line1 = - _("The day you entered is not valid " - "(should be between 01/01/1902 and 12/31/2037)"); - const char *mesg_line2 = _("Press [ENTER] to continue"); - const char *request_date = _("Enter the day to go to [ENTER for today] : %s"); - - while (wrong_day) { - snprintf(outstr, BUFSIZ, request_date, DATEFMT_DESC(datefmt)); - status_mesg(outstr, ""); - if (getstring(win[STA].p, selected_day, LDAY, 0, 1) == GETSTRING_ESC) - return; - else { - if (strlen(selected_day) == 0) { - wrong_day = 0; - calendar_goto_today(); - } else if (parse_date(selected_day, datefmt, &dyear, &dmonth, &dday, - calendar_get_slctd_day())) { - wrong_day = 0; - /* go to chosen day */ - slctd_day.dd = dday; - slctd_day.mm = dmonth; - slctd_day.yyyy = dyear; - } - if (wrong_day) { - status_mesg(mesg_line1, mesg_line2); - wgetch(win[KEY].p); - } - } - } - - return; -} - -void calendar_move(enum move move, int count) -{ - int ret, days_to_remove, days_to_add; - struct tm t; - - memset(&t, 0, sizeof(struct tm)); - t.tm_mday = slctd_day.dd; - t.tm_mon = slctd_day.mm - 1; - t.tm_year = slctd_day.yyyy - 1900; - - switch (move) { - case DAY_PREV: - ret = date_change(&t, 0, -count); - break; - case DAY_NEXT: - ret = date_change(&t, 0, count); - break; - case WEEK_PREV: - ret = date_change(&t, 0, -count * WEEKINDAYS); - break; - case WEEK_NEXT: - ret = date_change(&t, 0, count * WEEKINDAYS); - break; - case MONTH_PREV: - ret = date_change(&t, -count, 0); - break; - case MONTH_NEXT: - ret = date_change(&t, count, 0); - break; - case YEAR_PREV: - ret = date_change(&t, -count * YEARINMONTHS, 0); - break; - case YEAR_NEXT: - ret = date_change(&t, count * YEARINMONTHS, 0); - break; - case WEEK_START: - /* Normalize struct tm to get week day number. */ - mktime(&t); - if (calendar_week_begins_on_monday()) - days_to_remove = ((t.tm_wday == 0) ? WEEKINDAYS - 1 : t.tm_wday - 1); - else - days_to_remove = ((t.tm_wday == 0) ? 0 : t.tm_wday); - days_to_remove += (count - 1) * WEEKINDAYS; - ret = date_change(&t, 0, -days_to_remove); - break; - case WEEK_END: - mktime(&t); - if (calendar_week_begins_on_monday()) - days_to_add = ((t.tm_wday == 0) ? 0 : WEEKINDAYS - t.tm_wday); - else - days_to_add = ((t.tm_wday == 0) ? - WEEKINDAYS - 1 : WEEKINDAYS - 1 - t.tm_wday); - days_to_add += (count - 1) * WEEKINDAYS; - ret = date_change(&t, 0, days_to_add); - break; - default: - ret = 1; - /* NOTREACHED */ - } - - if (ret == 0) { - if (t.tm_year < 2) { - t.tm_mday = 1; - t.tm_mon = 0; - t.tm_year = 2; - } else if (t.tm_year > 137) { - t.tm_mday = 31; - t.tm_mon = 11; - t.tm_year = 137; - } - - slctd_day.dd = t.tm_mday; - slctd_day.mm = t.tm_mon + 1; - slctd_day.yyyy = t.tm_year + 1900; - } -} - -/* Returns the beginning of current year as a long. */ -long calendar_start_of_year(void) -{ - time_t timer; - struct tm tm; - - timer = time(NULL); - localtime_r(&timer, &tm); - tm.tm_mon = 0; - tm.tm_mday = 1; - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - timer = mktime(&tm); - - return (long)timer; -} - -long calendar_end_of_year(void) -{ - time_t timer; - struct tm tm; - - timer = time(NULL); - localtime_r(&timer, &tm); - tm.tm_mon = 0; - tm.tm_mday = 1; - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_year++; - timer = mktime(&tm); - - return (long)(timer - 1); -} - -/* - * The pom, potm, dotr, adj360 are used to compute the current - * phase of the moon. - * The code is based on the OpenBSD version of pom(6). - * Below is reported the copyright notice. - */ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software posted to USENET. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * dtor -- - * convert degrees to radians - */ -static double dtor(double deg) -{ - return deg * M_PI / 180; -} - -/* - * adj360 -- - * adjust value so 0 <= deg <= 360 - */ -static void adj360(double *deg) -{ - for (;;) - if (*deg < 0.0) - *deg += 360.0; - else if (*deg > 360.0) - *deg -= 360.0; - else - break; -} - -/* - * potm -- - * return phase of the moon - */ -static double potm(double days) -{ - double N, Msol, Ec, LambdaSol, l, Mm, Ev, Ac, A3, Mmprime; - double A4, lprime, V, ldprime, D, Nm; - - N = 360.0 * days / 365.242191; /* sec 46 #3 */ - adj360(&N); - Msol = N + EPSILONg - RHOg; /* sec 46 #4 */ - adj360(&Msol); - Ec = 360 / M_PI * ECCEN * sin(dtor(Msol)); /* sec 46 #5 */ - LambdaSol = N + Ec + EPSILONg; /* sec 46 #6 */ - adj360(&LambdaSol); - l = 13.1763966 * days + lzero; /* sec 65 #4 */ - adj360(&l); - Mm = l - (0.1114041 * days) - Pzero; /* sec 65 #5 */ - adj360(&Mm); - Nm = Nzero - (0.0529539 * days); /* sec 65 #6 */ - adj360(&Nm); - Ev = 1.2739 * sin(dtor(2 * (l - LambdaSol) - Mm)); /* sec 65 #7 */ - Ac = 0.1858 * sin(dtor(Msol)); /* sec 65 #8 */ - A3 = 0.37 * sin(dtor(Msol)); - Mmprime = Mm + Ev - Ac - A3; /* sec 65 #9 */ - Ec = 6.2886 * sin(dtor(Mmprime)); /* sec 65 #10 */ - A4 = 0.214 * sin(dtor(2 * Mmprime)); /* sec 65 #11 */ - lprime = l + Ev + Ec - Ac + A4; /* sec 65 #12 */ - V = 0.6583 * sin(dtor(2 * (lprime - LambdaSol))); /* sec 65 #13 */ - ldprime = lprime + V; /* sec 65 #14 */ - D = ldprime - LambdaSol; /* sec 67 #2 */ - return 50.0 * (1 - cos(dtor(D))); /* sec 67 #3 */ -} - -/* - * Phase of the Moon. Calculates the current phase of the moon. - * Based on routines from `Practical Astronomy with Your Calculator', - * by Duffett-Smith. Comments give the section from the book that - * particular piece of code was adapted from. - * - * -- Keith E. Brandt VIII 1984 - * - * Updated to the Third Edition of Duffett-Smith's book, IX 1998 - * - */ -static double pom(time_t tmpt) -{ - struct tm *GMT; - double days; - int cnt; - - GMT = gmtime(&tmpt); - days = (GMT->tm_yday + 1) + ((GMT->tm_hour + (GMT->tm_min / 60.0) + - (GMT->tm_sec / 3600.0)) / 24.0); - for (cnt = EPOCH; cnt < GMT->tm_year; ++cnt) - days += ISLEAP(cnt + TM_YEAR_BASE) ? 366 : 365; - /* Selected time could be before EPOCH */ - for (cnt = GMT->tm_year; cnt < EPOCH; ++cnt) - days -= ISLEAP(cnt + TM_YEAR_BASE) ? 366 : 365; - - return potm(days); -} - -/* - * Return a pictogram representing the current phase of the moon. - * Careful: date is the selected day in calendar at 00:00, so it represents - * the phase of the moon for previous day. - */ -const char *calendar_get_pom(time_t date) -{ - const char *pom_pict[MOON_PHASES] = { " ", "|) ", "(|)", "(| ", " | " }; - enum pom phase = NO_POM; - double pom_today, relative_pom, pom_yesterday, pom_tomorrow; - const double half = 50.0; - - pom_yesterday = pom(date); - pom_today = pom(date + DAYINSEC); - relative_pom = abs(pom_today - half); - pom_tomorrow = pom(date + 2 * DAYINSEC); - if (pom_today > pom_yesterday && pom_today > pom_tomorrow) - phase = FULL_MOON; - else if (pom_today < pom_yesterday && pom_today < pom_tomorrow) - phase = NEW_MOON; - else if (relative_pom < abs(pom_yesterday - half) - && relative_pom < abs(pom_tomorrow - half)) - phase = (pom_tomorrow > pom_today) ? FIRST_QUARTER : LAST_QUARTER; - - return pom_pict[phase]; -} diff --git a/src/config.c b/src/config.c index 83d1a93..72ce7fa 100644 --- a/src/config.c +++ b/src/config.c @@ -202,9 +202,9 @@ static int config_parse_color_pair(int *dest1, int *dest2, const char *val) static int config_parse_calendar_view(void *dummy, const char *val) { if (!strcmp(val, "monthly")) - calendar_set_view(CAL_MONTH_VIEW); + ui_calendar_set_view(CAL_MONTH_VIEW); else if (!strcmp(val, "weekly")) - calendar_set_view(CAL_WEEK_VIEW); + ui_calendar_set_view(CAL_WEEK_VIEW); else return 0; @@ -228,9 +228,9 @@ static int config_parse_default_panel(void *dummy, const char *val) static int config_parse_first_day_of_week(void *dummy, const char *val) { if (!strcmp(val, "monday")) - calendar_set_first_day_of_week(MONDAY); + ui_calendar_set_first_day_of_week(MONDAY); else if (!strcmp(val, "sunday")) - calendar_set_first_day_of_week(SUNDAY); + ui_calendar_set_first_day_of_week(SUNDAY); else return 0; @@ -379,7 +379,7 @@ static void config_color_theme_name(char *theme_name) static int config_serialize_calendar_view(char *buf, void *dummy) { - if (calendar_get_view() == CAL_WEEK_VIEW) + if (ui_calendar_get_view() == CAL_WEEK_VIEW) strcpy(buf, "weekly"); else strcpy(buf, "monthly"); @@ -401,7 +401,7 @@ static int config_serialize_default_panel(char *buf, void *dummy) static int config_serialize_first_day_of_week(char *buf, void *dummy) { - if (calendar_week_begins_on_monday()) + if (ui_calendar_week_begins_on_monday()) strcpy(buf, "monday"); else strcpy(buf, "sunday"); diff --git a/src/custom.c b/src/custom.c index df344c2..45cd07a 100644 --- a/src/custom.c +++ b/src/custom.c @@ -668,7 +668,7 @@ static int print_general_options(WINDOW * win) mvwprintw(win, y, XPOS, "[8] %s ", opt[FIRST_DAY_OF_WEEK]); custom_apply_attr(win, ATTR_HIGHEST); mvwaddstr(win, y, XPOS + 4 + strlen(opt[FIRST_DAY_OF_WEEK]), - calendar_week_begins_on_monday()? _("Monday") : _("Sunday")); + ui_calendar_week_begins_on_monday()? _("Monday") : _("Sunday")); custom_remove_attr(win, ATTR_HIGHEST); mvwaddstr(win, y + 1, XPOS, _("(specifies the first day of week in the calendar view)")); @@ -773,7 +773,7 @@ void custom_general_config(void) conf.progress_bar = !conf.progress_bar; break; case '8': - calendar_change_first_day_of_week(); + ui_calendar_change_first_day_of_week(); break; case '9': status_mesg(output_datefmt_str, ""); diff --git a/src/day.c b/src/day.c index 4c2f5bf..2e3b4bf 100644 --- a/src/day.c +++ b/src/day.c @@ -370,7 +370,7 @@ struct day_items_nb day_process_storage(struct date *slctd_date, if (slctd_date) day = *slctd_date; else - calendar_store_current_date(&day); + ui_calendar_store_current_date(&day); date = date2sec(day, 0, 0); @@ -545,7 +545,7 @@ void day_popup_item(struct day_item *day) struct apoint apt_tmp; apt_tmp.start = day->start; apt_tmp.dur = day_item_get_duration(day); - apoint_sec2str(&apt_tmp, calendar_get_slctd_day_sec(), a_st, a_end); + apoint_sec2str(&apt_tmp, ui_calendar_get_slctd_day_sec(), a_st, a_end); item_in_popup(a_st, a_end, day_item_get_mesg(day), _("Appointment :")); } else { diff --git a/src/pcal.c b/src/pcal.c index 8bcc0b5..e2721e6 100644 --- a/src/pcal.c +++ b/src/pcal.c @@ -101,7 +101,7 @@ static void pcal_export_header(FILE * stream) fputs("# calcurse pcal export\n", stream); fputs("\n# =======\n# options\n# =======\n", stream); fprintf(stream, "opt -A -K -l -m -F %s\n", - calendar_week_begins_on_monday()? "Monday" : "Sunday"); + ui_calendar_week_begins_on_monday()? "Monday" : "Sunday"); fputs("# Display week number (i.e. 1-52) on every Monday\n", stream); fprintf(stream, "all monday in all week %%w\n"); fputc('\n', stream); @@ -172,8 +172,8 @@ static void pcal_export_recur_events(FILE * stream) EXIT(_("incoherent repetition type")); } } else { - const long YEAR_START = calendar_start_of_year(); - const long YEAR_END = calendar_end_of_year(); + const long YEAR_START = ui_calendar_start_of_year(); + const long YEAR_END = ui_calendar_end_of_year(); if (rev->day < YEAR_END && rev->day > YEAR_START) foreach_date_dump(YEAR_END, rev->rpt, &rev->exc, rev->day, 0, @@ -237,8 +237,8 @@ static void pcal_export_recur_apoints(FILE * stream) EXIT(_("incoherent repetition type")); } } else { - const long YEAR_START = calendar_start_of_year(); - const long YEAR_END = calendar_end_of_year(); + const long YEAR_START = ui_calendar_start_of_year(); + const long YEAR_END = ui_calendar_end_of_year(); if (rapt->start < YEAR_END && rapt->start > YEAR_START) foreach_date_dump(YEAR_END, rapt->rpt, &rapt->exc, rapt->start, diff --git a/src/ui-calendar.c b/src/ui-calendar.c new file mode 100644 index 0000000..f9749c8 --- /dev/null +++ b/src/ui-calendar.c @@ -0,0 +1,915 @@ +/* + * Calcurse - text-based organizer + * + * Copyright (c) 2004-2013 calcurse Development Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Send your feedback or comments to : misc@calcurse.org + * Calcurse home page : http://calcurse.org + * + */ + +#include +#include +#include +#include +#include +#include + +#include "calcurse.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define EPOCH 90 +#define EPSILONg 279.403303 /* solar ecliptic long at EPOCH */ +#define RHOg 282.768422 /* solar ecliptic long of perigee at EPOCH */ +#define ECCEN 0.016713 /* solar orbit eccentricity */ +#define lzero 318.351648 /* lunar mean long at EPOCH */ +#define Pzero 36.340410 /* lunar mean long of perigee at EPOCH */ +#define Nzero 318.510107 /* lunar mean long of node at EPOCH */ + +#define ISLEAP(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) + +enum pom { + NO_POM, + FIRST_QUARTER, + FULL_MOON, + LAST_QUARTER, + NEW_MOON, + MOON_PHASES +}; + +static struct date today, slctd_day; +static unsigned ui_calendar_view, week_begins_on_monday; +static pthread_mutex_t date_thread_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_t ui_calendar_t_date; + +static void draw_monthly_view(struct window *, struct date *, unsigned); +static void draw_weekly_view(struct window *, struct date *, unsigned); +static void (*draw_calendar[CAL_VIEWS]) (struct window *, struct date *, + unsigned) = { +draw_monthly_view, draw_weekly_view}; + +static int monthly_view_cache[MAXDAYSPERMONTH]; +static int monthly_view_cache_valid = 0; +static int monthly_view_cache_month = 0; + +/* Switch between calendar views (monthly view is selected by default). */ +void ui_calendar_view_next(void) +{ + ui_calendar_view++; + if (ui_calendar_view == CAL_VIEWS) + ui_calendar_view = 0; +} + +void ui_calendar_view_prev(void) +{ + if (ui_calendar_view == 0) + ui_calendar_view = CAL_VIEWS; + ui_calendar_view--; +} + +void ui_calendar_set_view(int view) +{ + ui_calendar_view = (view < 0 || view >= CAL_VIEWS) ? CAL_MONTH_VIEW : view; +} + +int ui_calendar_get_view(void) +{ + return (int)ui_calendar_view; +} + +/* Thread needed to update current date in calendar. */ +/* ARGSUSED0 */ +static void *ui_calendar_date_thread(void *arg) +{ + time_t actual, tomorrow; + + for (;;) { + tomorrow = (time_t) (get_today() + DAYINSEC); + + while ((actual = time(NULL)) < tomorrow) + sleep(tomorrow - actual); + + ui_calendar_set_current_date(); + ui_calendar_update_panel(&win[CAL]); + } + + return NULL; +} + +/* Launch the calendar date thread. */ +void ui_calendar_start_date_thread(void) +{ + pthread_create(&ui_calendar_t_date, NULL, ui_calendar_date_thread, NULL); +} + +/* Stop the calendar date thread. */ +void ui_calendar_stop_date_thread(void) +{ + if (ui_calendar_t_date) { + pthread_cancel(ui_calendar_t_date); + pthread_join(ui_calendar_t_date, NULL); + } +} + +/* Set static variable today to current date */ +void ui_calendar_set_current_date(void) +{ + time_t timer; + struct tm tm; + + timer = time(NULL); + localtime_r(&timer, &tm); + + pthread_mutex_lock(&date_thread_mutex); + today.dd = tm.tm_mday; + today.mm = tm.tm_mon + 1; + today.yyyy = tm.tm_year + 1900; + pthread_mutex_unlock(&date_thread_mutex); +} + +/* Needed to display sunday or monday as the first day of week in calendar. */ +void ui_calendar_set_first_day_of_week(enum wday first_day) +{ + switch (first_day) { + case SUNDAY: + week_begins_on_monday = 0; + break; + case MONDAY: + week_begins_on_monday = 1; + break; + default: + ERROR_MSG(_("ERROR setting first day of week")); + week_begins_on_monday = 0; + /* NOTREACHED */ + } +} + +/* Swap first day of week in calendar. */ +void ui_calendar_change_first_day_of_week(void) +{ + week_begins_on_monday = !week_begins_on_monday; +} + +/* Return 1 if week begins on monday, 0 otherwise. */ +unsigned ui_calendar_week_begins_on_monday(void) +{ + return week_begins_on_monday; +} + +/* Fill in the given variable with the current date. */ +void ui_calendar_store_current_date(struct date *date) +{ + pthread_mutex_lock(&date_thread_mutex); + *date = today; + pthread_mutex_unlock(&date_thread_mutex); +} + +/* This is to start at the current date in calendar. */ +void ui_calendar_init_slctd_day(void) +{ + ui_calendar_store_current_date(&slctd_day); +} + +/* Return the selected day in calendar */ +struct date *ui_calendar_get_slctd_day(void) +{ + return &slctd_day; +} + +/* Returned value represents the selected day in calendar (in seconds) */ +long ui_calendar_get_slctd_day_sec(void) +{ + return date2sec(slctd_day, 0, 0); +} + +static int ui_calendar_get_wday(struct date *date) +{ + struct tm t; + + memset(&t, 0, sizeof(struct tm)); + t.tm_mday = date->dd; + t.tm_mon = date->mm - 1; + t.tm_year = date->yyyy - 1900; + + mktime(&t); + + return t.tm_wday; +} + +static unsigned months_to_days(unsigned month) +{ + return (month * 3057 - 3007) / 100; +} + +static long years_to_days(unsigned year) +{ + return year * 365L + year / 4 - year / 100 + year / 400; +} + +static long ymd_to_scalar(unsigned year, unsigned month, unsigned day) +{ + long scalar; + + scalar = day + months_to_days(month); + if (month > 2) + scalar -= ISLEAP(year) ? 1 : 2; + year--; + scalar += years_to_days(year); + + return scalar; +} + +/* + * Used to change date by adding a certain amount of days or weeks. + * Returns 0 on success, 1 otherwise. + */ +static int date_change(struct tm *date, int delta_month, int delta_day) +{ + struct tm t; + + t = *date; + t.tm_mon += delta_month; + t.tm_mday += delta_day; + + if (mktime(&t) == -1) + return 1; + else { + *date = t; + return 0; + } +} + +void ui_calendar_monthly_view_cache_set_invalid(void) +{ + monthly_view_cache_valid = 0; +} + +/* Draw the monthly view inside calendar panel. */ +static void +draw_monthly_view(struct window *cwin, struct date *current_day, + unsigned sunday_first) +{ + const int OFFY = CALHEIGHT / 2 - (conf.compact_panels ? 3 : 1); + struct date check_day; + int c_day, c_day_1, day_1_sav, numdays, j; + unsigned yr, mo; + int OFFX, SBAR_WIDTH, ofs_x, ofs_y; + int item_this_day = 0; + + mo = slctd_day.mm; + yr = slctd_day.yyyy; + + /* offset for centering calendar in window */ + SBAR_WIDTH = wins_sbar_width(); + OFFX = (SBAR_WIDTH - 27) / 2; + ofs_y = OFFY; + ofs_x = OFFX; + + /* checking the number of days in february */ + numdays = days[mo - 1]; + if (2 == mo && ISLEAP(yr)) + ++numdays; + + /* + * the first calendar day will be monday or sunday, depending on + * 'week_begins_on_monday' value + */ + c_day_1 = (int)((ymd_to_scalar(yr, mo, 1 + sunday_first) - (long)1) % 7L); + + /* Write the current month and year on top of the calendar */ + WINS_CALENDAR_LOCK; + custom_apply_attr(cwin->p, ATTR_HIGHEST); + mvwprintw(cwin->p, ofs_y, + (SBAR_WIDTH - (strlen(_(monthnames[mo - 1])) + 5)) / 2, + "%s %d", _(monthnames[mo - 1]), slctd_day.yyyy); + custom_remove_attr(cwin->p, ATTR_HIGHEST); + ++ofs_y; + + /* print the days, with regards to the first day of the week */ + custom_apply_attr(cwin->p, ATTR_HIGHEST); + for (j = 0; j < WEEKINDAYS; j++) { + mvwaddstr(cwin->p, ofs_y, ofs_x + 4 * j, _(daynames[1 + j - sunday_first])); + } + custom_remove_attr(cwin->p, ATTR_HIGHEST); + WINS_CALENDAR_UNLOCK; + + day_1_sav = (c_day_1 + 1) * 3 + c_day_1 - 7; + + /* invalidate cache if a new month is selected */ + if (yr * YEARINMONTHS + mo != monthly_view_cache_month) { + monthly_view_cache_month = yr * YEARINMONTHS + mo; + monthly_view_cache_valid = 0; + } + + for (c_day = 1; c_day <= numdays; ++c_day, ++c_day_1, c_day_1 %= 7) { + check_day.dd = c_day; + check_day.mm = slctd_day.mm; + check_day.yyyy = slctd_day.yyyy; + + /* check if the day contains an event or an appointment */ + if (monthly_view_cache_valid) { + item_this_day = monthly_view_cache[c_day - 1]; + } + else { + item_this_day = monthly_view_cache[c_day - 1] = + day_check_if_item(check_day); + } + + /* Go to next line, the week is over. */ + if (!c_day_1 && 1 != c_day) { + ofs_y++; + ofs_x = OFFX - day_1_sav - 4 * c_day; + } + + WINS_CALENDAR_LOCK; + if (c_day == current_day->dd + && current_day->mm == slctd_day.mm + && current_day->yyyy == slctd_day.yyyy + && current_day->dd != slctd_day.dd) { + /* This is today, so print it in yellow. */ + custom_apply_attr(cwin->p, ATTR_LOWEST); + mvwprintw(cwin->p, ofs_y + 1, + ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); + custom_remove_attr(cwin->p, ATTR_LOWEST); + } else if (c_day == slctd_day.dd) { + /* This is the selected day, print it according to user's theme. */ + custom_apply_attr(cwin->p, ATTR_HIGHEST); + mvwprintw(cwin->p, ofs_y + 1, + ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); + custom_remove_attr(cwin->p, ATTR_HIGHEST); + } else if (item_this_day) { + custom_apply_attr(cwin->p, ATTR_LOW); + mvwprintw(cwin->p, ofs_y + 1, + ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); + custom_remove_attr(cwin->p, ATTR_LOW); + } else { + /* otherwise, print normal days in black */ + mvwprintw(cwin->p, ofs_y + 1, + ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); + } + WINS_CALENDAR_UNLOCK; + } + + monthly_view_cache_valid = 1; +} + +static int weeknum(const struct tm *t, int firstweekday) +{ + int wday, wnum; + + wday = t->tm_wday; + if (firstweekday == MONDAY) { + if (wday == SUNDAY) + wday = 6; + else + wday--; + } + wnum = ((t->tm_yday + WEEKINDAYS - wday) / WEEKINDAYS); + if (wnum < 0) + wnum = 0; + + return wnum; +} + +/* + * Compute the week number according to ISO 8601. + */ +static int ISO8601weeknum(const struct tm *t) +{ + int wnum, jan1day; + + wnum = weeknum(t, MONDAY); + + jan1day = t->tm_wday - (t->tm_yday % WEEKINDAYS); + if (jan1day < 0) + jan1day += WEEKINDAYS; + + switch (jan1day) { + case MONDAY: + break; + case TUESDAY: + case WEDNESDAY: + case THURSDAY: + wnum++; + break; + case FRIDAY: + case SATURDAY: + case SUNDAY: + if (wnum == 0) { + /* Get week number of last week of last year. */ + struct tm dec31ly; /* 12/31 last year */ + + dec31ly = *t; + dec31ly.tm_year--; + dec31ly.tm_mon = 11; + dec31ly.tm_mday = 31; + dec31ly.tm_wday = (jan1day == SUNDAY) ? 6 : jan1day - 1; + dec31ly.tm_yday = 364 + ISLEAP(dec31ly.tm_year + 1900); + wnum = ISO8601weeknum(&dec31ly); + } + break; + } + + if (t->tm_mon == 11) { + int wday, mday; + + wday = t->tm_wday; + mday = t->tm_mday; + if ((wday == MONDAY && (mday >= 29 && mday <= 31)) + || (wday == TUESDAY && (mday == 30 || mday == 31)) + || (wday == WEDNESDAY && mday == 31)) + wnum = 1; + } + + return wnum; +} + +/* Draw the weekly view inside calendar panel. */ +static void +draw_weekly_view(struct window *cwin, struct date *current_day, + unsigned sunday_first) +{ +#define DAYSLICESNO 6 + const int WCALWIDTH = 30; + const int OFFY = CALHEIGHT / 2 - (conf.compact_panels ? 3 : 1); + struct tm t; + int OFFX, j, c_wday, days_to_remove, weeknum; + + OFFX = (wins_sbar_width() - WCALWIDTH) / 2 + 1; + + /* Fill in a tm structure with the first day of the selected week. */ + c_wday = ui_calendar_get_wday(&slctd_day); + if (sunday_first) + days_to_remove = c_wday; + else + days_to_remove = c_wday == 0 ? WEEKINDAYS - 1 : c_wday - 1; + + memset(&t, 0, sizeof(struct tm)); + t.tm_mday = slctd_day.dd; + t.tm_mon = slctd_day.mm - 1; + t.tm_year = slctd_day.yyyy - 1900; + mktime(&t); + date_change(&t, 0, -days_to_remove); + + /* Print the week number. */ + weeknum = ISO8601weeknum(&t); + WINS_CALENDAR_LOCK; + custom_apply_attr(cwin->p, ATTR_HIGHEST); + mvwprintw(cwin->p, conf.compact_panels ? 0 : 2, cwin->w - 9, "(# %02d)", + weeknum); + custom_remove_attr(cwin->p, ATTR_HIGHEST); + WINS_CALENDAR_UNLOCK; + + /* Now draw calendar view. */ + for (j = 0; j < WEEKINDAYS; j++) { + struct date date; + unsigned attr, item_this_day; + int i, slices[DAYSLICESNO]; + + /* print the day names, with regards to the first day of the week */ + custom_apply_attr(cwin->p, ATTR_HIGHEST); + mvwaddstr(cwin->p, OFFY, OFFX + 4 * j, _(daynames[1 + j - sunday_first])); + custom_remove_attr(cwin->p, ATTR_HIGHEST); + + /* Check if the day to be printed has an item or not. */ + date.dd = t.tm_mday; + date.mm = t.tm_mon + 1; + date.yyyy = t.tm_year + 1900; + item_this_day = day_check_if_item(date); + + /* Print the day numbers with appropriate decoration. */ + if (t.tm_mday == current_day->dd + && current_day->mm == slctd_day.mm + && current_day->yyyy == slctd_day.yyyy + && current_day->dd != slctd_day.dd) + attr = ATTR_LOWEST; /* today, but not selected */ + else if (t.tm_mday == slctd_day.dd) + attr = ATTR_HIGHEST; /* selected day */ + else if (item_this_day) + attr = ATTR_LOW; + else + attr = 0; + + WINS_CALENDAR_LOCK; + if (attr) + custom_apply_attr(cwin->p, attr); + mvwprintw(cwin->p, OFFY + 1, OFFX + 1 + 4 * j, "%02d", t.tm_mday); + if (attr) + custom_remove_attr(cwin->p, attr); + WINS_CALENDAR_UNLOCK; + + /* Draw slices indicating appointment times. */ + memset(slices, 0, DAYSLICESNO * sizeof *slices); + if (day_chk_busy_slices(date, DAYSLICESNO, slices)) { + for (i = 0; i < DAYSLICESNO; i++) { + if (j != WEEKINDAYS - 1 && i != DAYSLICESNO - 1) { + WINS_CALENDAR_LOCK; + mvwhline(cwin->p, OFFY + 2 + i, OFFX + 3 + 4 * j, ACS_S9, 2); + WINS_CALENDAR_UNLOCK; + } + if (slices[i]) { + int highlight; + + highlight = (t.tm_mday == slctd_day.dd) ? 1 : 0; + WINS_CALENDAR_LOCK; + if (highlight) + custom_apply_attr(cwin->p, attr); + wattron(cwin->p, A_REVERSE); + mvwaddstr(cwin->p, OFFY + 2 + i, OFFX + 1 + 4 * j, " "); + mvwaddstr(cwin->p, OFFY + 2 + i, OFFX + 2 + 4 * j, " "); + wattroff(cwin->p, A_REVERSE); + if (highlight) + custom_remove_attr(cwin->p, attr); + WINS_CALENDAR_UNLOCK; + } + } + } + + /* get next day */ + date_change(&t, 0, 1); + } + + /* Draw marks to indicate midday on the sides of the calendar. */ + WINS_CALENDAR_LOCK; + custom_apply_attr(cwin->p, ATTR_HIGHEST); + mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, OFFX, ACS_S9, 1); + mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, + OFFX + WCALWIDTH - 3, ACS_S9, 1); + custom_remove_attr(cwin->p, ATTR_HIGHEST); + WINS_CALENDAR_UNLOCK; + +#undef DAYSLICESNO +} + +/* Function used to display the calendar panel. */ +void ui_calendar_update_panel(struct window *cwin) +{ + struct date current_day; + unsigned sunday_first; + + ui_calendar_store_current_date(¤t_day); + + WINS_CALENDAR_LOCK; + erase_window_part(cwin->p, 1, conf.compact_panels ? 1 : 3, cwin->w - 2, + cwin->h - 2); + if (!conf.compact_panels) + mvwhline(cwin->p, 2, 1, ACS_HLINE, cwin->w - 2); + WINS_CALENDAR_UNLOCK; + + sunday_first = ui_calendar_week_begins_on_monday()? 0 : 1; + + draw_calendar[ui_calendar_view] (cwin, ¤t_day, sunday_first); + + wnoutrefresh(cwin->p); +} + +/* Set the selected day in calendar to current day. */ +void ui_calendar_goto_today(void) +{ + struct date today; + + ui_calendar_store_current_date(&today); + slctd_day.dd = today.dd; + slctd_day.mm = today.mm; + slctd_day.yyyy = today.yyyy; +} + +/* + * Ask for a date to jump to, then check the correctness of that date + * and jump to it. + * If the entered date is empty, automatically jump to the current date. + * slctd_day is updated with the newly selected date. + */ +void ui_calendar_change_day(int datefmt) +{ +#define LDAY 11 + char selected_day[LDAY] = ""; + char outstr[BUFSIZ]; + int dday, dmonth, dyear; + int wrong_day = 1; + const char *mesg_line1 = + _("The day you entered is not valid " + "(should be between 01/01/1902 and 12/31/2037)"); + const char *mesg_line2 = _("Press [ENTER] to continue"); + const char *request_date = _("Enter the day to go to [ENTER for today] : %s"); + + while (wrong_day) { + snprintf(outstr, BUFSIZ, request_date, DATEFMT_DESC(datefmt)); + status_mesg(outstr, ""); + if (getstring(win[STA].p, selected_day, LDAY, 0, 1) == GETSTRING_ESC) + return; + else { + if (strlen(selected_day) == 0) { + wrong_day = 0; + ui_calendar_goto_today(); + } else if (parse_date(selected_day, datefmt, &dyear, &dmonth, &dday, + ui_calendar_get_slctd_day())) { + wrong_day = 0; + /* go to chosen day */ + slctd_day.dd = dday; + slctd_day.mm = dmonth; + slctd_day.yyyy = dyear; + } + if (wrong_day) { + status_mesg(mesg_line1, mesg_line2); + wgetch(win[KEY].p); + } + } + } + + return; +} + +void ui_calendar_move(enum move move, int count) +{ + int ret, days_to_remove, days_to_add; + struct tm t; + + memset(&t, 0, sizeof(struct tm)); + t.tm_mday = slctd_day.dd; + t.tm_mon = slctd_day.mm - 1; + t.tm_year = slctd_day.yyyy - 1900; + + switch (move) { + case DAY_PREV: + ret = date_change(&t, 0, -count); + break; + case DAY_NEXT: + ret = date_change(&t, 0, count); + break; + case WEEK_PREV: + ret = date_change(&t, 0, -count * WEEKINDAYS); + break; + case WEEK_NEXT: + ret = date_change(&t, 0, count * WEEKINDAYS); + break; + case MONTH_PREV: + ret = date_change(&t, -count, 0); + break; + case MONTH_NEXT: + ret = date_change(&t, count, 0); + break; + case YEAR_PREV: + ret = date_change(&t, -count * YEARINMONTHS, 0); + break; + case YEAR_NEXT: + ret = date_change(&t, count * YEARINMONTHS, 0); + break; + case WEEK_START: + /* Normalize struct tm to get week day number. */ + mktime(&t); + if (ui_calendar_week_begins_on_monday()) + days_to_remove = ((t.tm_wday == 0) ? WEEKINDAYS - 1 : t.tm_wday - 1); + else + days_to_remove = ((t.tm_wday == 0) ? 0 : t.tm_wday); + days_to_remove += (count - 1) * WEEKINDAYS; + ret = date_change(&t, 0, -days_to_remove); + break; + case WEEK_END: + mktime(&t); + if (ui_calendar_week_begins_on_monday()) + days_to_add = ((t.tm_wday == 0) ? 0 : WEEKINDAYS - t.tm_wday); + else + days_to_add = ((t.tm_wday == 0) ? + WEEKINDAYS - 1 : WEEKINDAYS - 1 - t.tm_wday); + days_to_add += (count - 1) * WEEKINDAYS; + ret = date_change(&t, 0, days_to_add); + break; + default: + ret = 1; + /* NOTREACHED */ + } + + if (ret == 0) { + if (t.tm_year < 2) { + t.tm_mday = 1; + t.tm_mon = 0; + t.tm_year = 2; + } else if (t.tm_year > 137) { + t.tm_mday = 31; + t.tm_mon = 11; + t.tm_year = 137; + } + + slctd_day.dd = t.tm_mday; + slctd_day.mm = t.tm_mon + 1; + slctd_day.yyyy = t.tm_year + 1900; + } +} + +/* Returns the beginning of current year as a long. */ +long ui_calendar_start_of_year(void) +{ + time_t timer; + struct tm tm; + + timer = time(NULL); + localtime_r(&timer, &tm); + tm.tm_mon = 0; + tm.tm_mday = 1; + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + timer = mktime(&tm); + + return (long)timer; +} + +long ui_calendar_end_of_year(void) +{ + time_t timer; + struct tm tm; + + timer = time(NULL); + localtime_r(&timer, &tm); + tm.tm_mon = 0; + tm.tm_mday = 1; + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + tm.tm_year++; + timer = mktime(&tm); + + return (long)(timer - 1); +} + +/* + * The pom, potm, dotr, adj360 are used to compute the current + * phase of the moon. + * The code is based on the OpenBSD version of pom(6). + * Below is reported the copyright notice. + */ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software posted to USENET. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * dtor -- + * convert degrees to radians + */ +static double dtor(double deg) +{ + return deg * M_PI / 180; +} + +/* + * adj360 -- + * adjust value so 0 <= deg <= 360 + */ +static void adj360(double *deg) +{ + for (;;) + if (*deg < 0.0) + *deg += 360.0; + else if (*deg > 360.0) + *deg -= 360.0; + else + break; +} + +/* + * potm -- + * return phase of the moon + */ +static double potm(double days) +{ + double N, Msol, Ec, LambdaSol, l, Mm, Ev, Ac, A3, Mmprime; + double A4, lprime, V, ldprime, D, Nm; + + N = 360.0 * days / 365.242191; /* sec 46 #3 */ + adj360(&N); + Msol = N + EPSILONg - RHOg; /* sec 46 #4 */ + adj360(&Msol); + Ec = 360 / M_PI * ECCEN * sin(dtor(Msol)); /* sec 46 #5 */ + LambdaSol = N + Ec + EPSILONg; /* sec 46 #6 */ + adj360(&LambdaSol); + l = 13.1763966 * days + lzero; /* sec 65 #4 */ + adj360(&l); + Mm = l - (0.1114041 * days) - Pzero; /* sec 65 #5 */ + adj360(&Mm); + Nm = Nzero - (0.0529539 * days); /* sec 65 #6 */ + adj360(&Nm); + Ev = 1.2739 * sin(dtor(2 * (l - LambdaSol) - Mm)); /* sec 65 #7 */ + Ac = 0.1858 * sin(dtor(Msol)); /* sec 65 #8 */ + A3 = 0.37 * sin(dtor(Msol)); + Mmprime = Mm + Ev - Ac - A3; /* sec 65 #9 */ + Ec = 6.2886 * sin(dtor(Mmprime)); /* sec 65 #10 */ + A4 = 0.214 * sin(dtor(2 * Mmprime)); /* sec 65 #11 */ + lprime = l + Ev + Ec - Ac + A4; /* sec 65 #12 */ + V = 0.6583 * sin(dtor(2 * (lprime - LambdaSol))); /* sec 65 #13 */ + ldprime = lprime + V; /* sec 65 #14 */ + D = ldprime - LambdaSol; /* sec 67 #2 */ + return 50.0 * (1 - cos(dtor(D))); /* sec 67 #3 */ +} + +/* + * Phase of the Moon. Calculates the current phase of the moon. + * Based on routines from `Practical Astronomy with Your Calculator', + * by Duffett-Smith. Comments give the section from the book that + * particular piece of code was adapted from. + * + * -- Keith E. Brandt VIII 1984 + * + * Updated to the Third Edition of Duffett-Smith's book, IX 1998 + * + */ +static double pom(time_t tmpt) +{ + struct tm *GMT; + double days; + int cnt; + + GMT = gmtime(&tmpt); + days = (GMT->tm_yday + 1) + ((GMT->tm_hour + (GMT->tm_min / 60.0) + + (GMT->tm_sec / 3600.0)) / 24.0); + for (cnt = EPOCH; cnt < GMT->tm_year; ++cnt) + days += ISLEAP(cnt + TM_YEAR_BASE) ? 366 : 365; + /* Selected time could be before EPOCH */ + for (cnt = GMT->tm_year; cnt < EPOCH; ++cnt) + days -= ISLEAP(cnt + TM_YEAR_BASE) ? 366 : 365; + + return potm(days); +} + +/* + * Return a pictogram representing the current phase of the moon. + * Careful: date is the selected day in calendar at 00:00, so it represents + * the phase of the moon for previous day. + */ +const char *ui_calendar_get_pom(time_t date) +{ + const char *pom_pict[MOON_PHASES] = { " ", "|) ", "(|)", "(| ", " | " }; + enum pom phase = NO_POM; + double pom_today, relative_pom, pom_yesterday, pom_tomorrow; + const double half = 50.0; + + pom_yesterday = pom(date); + pom_today = pom(date + DAYINSEC); + relative_pom = abs(pom_today - half); + pom_tomorrow = pom(date + 2 * DAYINSEC); + if (pom_today > pom_yesterday && pom_today > pom_tomorrow) + phase = FULL_MOON; + else if (pom_today < pom_yesterday && pom_today < pom_tomorrow) + phase = NEW_MOON; + else if (relative_pom < abs(pom_yesterday - half) + && relative_pom < abs(pom_tomorrow - half)) + phase = (pom_tomorrow > pom_today) ? FIRST_QUARTER : LAST_QUARTER; + + return pom_pict[phase]; +} diff --git a/src/ui-day.c b/src/ui-day.c index c300699..75adb3b 100644 --- a/src/ui-day.c +++ b/src/ui-day.c @@ -242,7 +242,7 @@ static void update_rept(struct rpt **rpt, const long start) int newmonth, newday, newyear; if (parse_date(timstr, conf.input_datefmt, &newyear, &newmonth, - &newday, calendar_get_slctd_day())) { + &newday, ui_calendar_get_slctd_day())) { t = start; localtime_r(&t, <); new_date.dd = newday; @@ -360,7 +360,7 @@ void ui_day_item_edit(void) break; } - calendar_monthly_view_cache_set_invalid(); + ui_calendar_monthly_view_cache_set_invalid(); if (need_check_notify) notify_check_next_app(1); @@ -490,18 +490,18 @@ void ui_day_item_add(void) status_mesg(mesg_3, ""); if (getstring(win[STA].p, item_mesg, BUFSIZ, 0, 1) == GETSTRING_VALID) { if (is_appointment) { - apoint_start = date2sec(*calendar_get_slctd_day(), heures, minutes); + apoint_start = date2sec(*ui_calendar_get_slctd_day(), heures, minutes); apoint_new(item_mesg, 0L, apoint_start, min2sec(apoint_duration), 0L); if (notify_bar()) notify_check_added(item_mesg, apoint_start, 0L); } else - event_new(item_mesg, 0L, date2sec(*calendar_get_slctd_day(), 0, 0), Id); + event_new(item_mesg, 0L, date2sec(*ui_calendar_get_slctd_day(), 0, 0), Id); if (ui_day_hilt() == 0) ui_day_hilt_increase(1); } - calendar_monthly_view_cache_set_invalid(); + ui_calendar_monthly_view_cache_set_invalid(); wins_erase_status_bar(); } @@ -524,7 +524,7 @@ void ui_day_item_delete(unsigned *nb_events, unsigned *nb_apoints, const char *note_choices = _("[in]"); const int nb_note_choices = 2; - long date = calendar_get_slctd_day_sec(); + long date = ui_calendar_get_slctd_day_sec(); int nb_items = *nb_apoints + *nb_events; int to_be_removed = 0; @@ -585,7 +585,7 @@ void ui_day_item_delete(unsigned *nb_events, unsigned *nb_apoints, /* NOTREACHED */ } - calendar_monthly_view_cache_set_invalid(); + ui_calendar_monthly_view_cache_set_invalid(); if (ui_day_hilt() > 1) ui_day_hilt_decrease(1); @@ -687,7 +687,7 @@ void ui_day_item_repeat(void) date_entered = 1; } else { if (parse_date(user_input, conf.input_datefmt, - &year, &month, &day, calendar_get_slctd_day())) { + &year, &month, &day, ui_calendar_get_slctd_day())) { t = p->start; localtime_r(&t, <); until_date.dd = day; @@ -713,7 +713,7 @@ void ui_day_item_repeat(void) return; } - date = calendar_get_slctd_day_sec(); + date = ui_calendar_get_slctd_day_sec(); if (p->type == EVNT) { struct event *ev = p->item.ev; recur_event_new(ev->mesg, ev->note, ev->day, ev->id, type, freq, until, @@ -734,7 +734,7 @@ void ui_day_item_repeat(void) day_cut[REG_BLACK_HOLE].type = p->type; day_cut[REG_BLACK_HOLE].item = p->item; - calendar_monthly_view_cache_set_invalid(); + ui_calendar_monthly_view_cache_set_invalid(); } /* Free the current cut item, if any. */ @@ -783,9 +783,9 @@ void ui_day_item_paste(unsigned *nb_events, unsigned *nb_apoints, return; day_item_fork(&day_cut[reg], &day); - item_type = day_paste_item(&day, calendar_get_slctd_day_sec()); + item_type = day_paste_item(&day, ui_calendar_get_slctd_day_sec()); - calendar_monthly_view_cache_set_invalid(); + ui_calendar_monthly_view_cache_set_invalid(); if (item_type == EVNT || item_type == RECUR_EVNT) (*nb_events)++; @@ -884,7 +884,7 @@ void ui_day_update_panel(int which_pan) struct date slctd_date; /* variable inits */ - slctd_date = *calendar_get_slctd_day(); + slctd_date = *ui_calendar_get_slctd_day(); title_xpos = win[APP].w - (strlen(_(monthnames[slctd_date.mm - 1])) + 16); if (slctd_date.dd < 10) title_xpos++; @@ -895,7 +895,7 @@ void ui_day_update_panel(int which_pan) erase_window_part(win[APP].p, 1, title_lines, win[APP].w - 2, win[APP].h - 2); custom_apply_attr(win[APP].p, ATTR_HIGHEST); mvwprintw(win[APP].p, title_lines, title_xpos, "%s %s %d, %d", - calendar_get_pom(date), _(monthnames[slctd_date.mm - 1]), + ui_calendar_get_pom(date), _(monthnames[slctd_date.mm - 1]), slctd_date.dd, slctd_date.yyyy); custom_remove_attr(win[APP].p, ATTR_HIGHEST); diff --git a/src/utils.c b/src/utils.c index 1192ed8..7baa961 100644 --- a/src/utils.c +++ b/src/utils.c @@ -80,7 +80,7 @@ void exit_calcurse(int status) } else was_interactive = 0; - calendar_stop_date_thread(); + ui_calendar_stop_date_thread(); io_stop_psave_thread(); free_user_data(); keys_free(); diff --git a/src/vars.c b/src/vars.c index a54b702..0235089 100644 --- a/src/vars.c +++ b/src/vars.c @@ -161,7 +161,7 @@ void vars_init(void) wins_set_layout(1); - calendar_set_first_day_of_week(MONDAY); + ui_calendar_set_first_day_of_week(MONDAY); /* Pad structure to scroll text inside the appointment panel */ apad.length = 1; @@ -171,5 +171,5 @@ void vars_init(void) custom_init_attr(); /* Start at the current date */ - calendar_init_slctd_day(); + ui_calendar_init_slctd_day(); } diff --git a/src/wins.c b/src/wins.c index 6274a19..d8f1f45 100644 --- a/src/wins.c +++ b/src/wins.c @@ -499,7 +499,7 @@ void wins_update_panels(int flags) if (flags & FLAG_TOD) ui_todo_update_panel(slctd_win); if (flags & FLAG_CAL) - calendar_update_panel(&win[CAL]); + ui_calendar_update_panel(&win[CAL]); } /* -- cgit v1.2.3-70-g09d2