summaryrefslogtreecommitdiffstats
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* Make the text for empty days configurableLars Henriksen2019-11-035-1/+27
| | | | | | | The default is "--"; a single space makes the text invisible. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Allow discarding a todo item from the priority promptLukas Fleischer2019-11-031-2/+4
| | | | Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Support RET to set the todo item priority to 0Issam Maghni2019-11-031-4/+7
| | | | Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Fix save of interactively imported dataLars Henriksen2019-11-031-0/+4
| | | | | | Adresses Github issue #249. Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* DST and recurrent itemsLars Henriksen2019-10-181-35/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The patch adresses two issues with the function recur_item_find ocurrence(), one major: mktime(), and one minor: item duration. In addition, some refactoring is done. The following recurrent appointments demonstrate the problems (as described in the message) and are used as test cases in the associated test commit. 03/29/2019 @ 12:00 -> 03/30/2019 @ 11:00 {2D -> 04/03/2019} |two-day - every other day - not on 1/4 03/31/2019 @ 12:00 -> 03/31/2019 @ 13:00 {1D -> 04/01/2019} |daily - not on 31/3, twice on 1/4 03/31/2019 @ 04:00 -> 03/31/2019 @ 05:00 {1W} |weekly - appears after one week 03/31/2019 @ 12:00 -> 03/31/2019 @ 12:00 {1M} |monthly - never appears 03/31/2019 @ 12:00 -> 03/31/2019 @ 12:00 {1Y} |yearly - never appears 10/20/2019 @ 00:00 -> 10/21/2019 @ 01:00 {1W -> 11/03/2019} |25 hours - ends on 27th, but continues on 28th 03/24/2019 @ 00:00 -> 03/25/2019 @ 00:00 {1W -> 04/07/2019} |24 hours - does not continue on April 1 The root cause is two mktime() calls in recur_item_find_occurrence(), both of which use an inherited tm_isdst value in the tm structure. In such cases mktime() will "normalize" the tm stucture if tm_isdst is 0 or 1 and in disagreement with the rest of the tm contents (just like 32 May will be normalized to 1 June). Example. In 2019 DST started on 31/3 at 02:00:00 (in the European Union). If the (local) time "31/3/2018 00:00:00" is passed to mktime() with tm_isdst = 0, the return value is (say) T sec and the tm structure is unchanged, because DST is not in effect at midnight. If the same call is performed with tm_isdst = 1, the return value becomes (T - 3600) sec and the tm structure is normalized to "30/3/2018 23:00:00", tm_isdst = 0. In recur_item_find_occurrence(), the normalized tm structure with wrong day and time is used in ensuing calculations, leading to wrong dates and the errors observed. The first mktime() call is used to calculate the "day span" of the occurrence before the occurrence itself has been determined. But once the occurence is known, the "day span" is easily determined, and there is no need for the first mktime() call. Events have no explicit duration. However, recur_event_find_occurrence() and recur_event_inday() set the duration of an event to DAYINSEC before passing it on to recur_item_find_occurrence(). The value is not correct on the day when DST begins or ends. The interpretation of the daylength should be left to the called function. Hence, duration is set to -1 to signal no (explicit) duration. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Set time-of-day consistently to midnight for until dayLars Henriksen2019-09-062-8/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A day begins on midnight (inclusive) and ends on midnight (exclusive). A day as a whole is represented by the initial midnight, i.e. time-of-day is 00:00. On load of recurrent appointments (but not events) time-of-day for the until day is set to 23:59. For a newly created recurrent appointment the setting depends on the input method: time-of-day is set to 00:00 if until day is given as a date (day, month and year), but to time-of-day for the start day if given as an offset (+dd). The resulting behaviour is only visible in interactive use of calcurse as proved by the following scenario. 1) Create an appointment with start time 12:00, end time 11:59 (multi day). 2) Turn it into a recurrent appointment of type daily, frequency 3, until day +3. The appointment is correctly displayed with two 2-day occurrences three days apart. 3) Edit the appointment and select Repetition. Accept existing type, frequency and end day (now as a date). The second day of the second occurrence disappears. 4) Repeat 3), but set the end day as an offset (+3). The second day of the second occurrence reappears. The inconsistencies have been eliminated, and time-of-day for the until day is now always 00:00. Also, until day may equal start day, so midnights should be compared. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* DST: fix date_change() thoroughlyLars Henriksen2019-09-061-1/+2
| | | | | | | | Explicit setting of Daylight Saving Time should be avoided before as well as after the mktime() call. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Fix monthly and yearly recurrence algorithmsLars Henriksen2019-09-061-5/+6
| | | | | | | | | | | | | | | | | | | | | | | The calculation of the year of the most recent occurrence for year dates before the start date (disregarding the year) is incorrect for frequencies greater than one. The most recent occurrence (for a date as mentioned) is either too far or too close in the past. In most cases it does no harm because the most recent ocurrence is in the past and does not span the date (i.e. there is no occurrence on the day). But the following appointment shows the presence of the bug: 12/31/2019 @ 12:00 -> 01/01/2020 @ 12:00 {2Y} |new year The occurence on 1 Jan 2020 is missing, because the most recent occurrence is too far in the past (31 Dec 2018 instead of 31 Dec 2019). An occurrence appears on 1 Jan 2021, because the most recent occurence is too close in the past (31 Dec 2020 instead of 31 Dec 2019). A similar miscalculation affects the monthly rule as proved by 3/31/2019 @ 12:00 -> 4/1/2019 @ 11:00 {2M} |change of month Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Fix edit of empty exception day listLars Henriksen2019-07-101-1/+1
| | | | | Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Treat recurrence item parameters as a unitLars Henriksen2019-06-163-23/+43
| | | | | | | | An edit session, and in particular, a cancelled edit session should encompass all parameters. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Use current value as default for periodic saveLukas Fleischer2019-06-071-0/+1
| | | | Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Disable view item/note bindings for dummy itemsLukas Fleischer2019-06-061-2/+2
| | | | Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Use empty end date instead of 0 when editing repetitionsLukas Fleischer2019-06-062-17/+12
| | | | | | | | | Since commit 987fa9d (Allow to omit end date in repetitions, 2019-06-03), one can provide an empty date instead of using the value 0 to omit the end date of a repetition. Use this as default value when editing repetitions without an end date. Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Allow to omit end date in repetitionsLukas Fleischer2019-06-031-12/+9
| | | | | | Addresses GitHub issue #213. Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Fix recurrent appointment end time when duration is zeroLars Henriksen2019-06-031-9/+4
| | | | | | | | | Fixes a regression introduced in 223810c (Major overhaul of appointment/event input routines., 2017-11-06) and 16d3032 (Refactoring update_duration/day_edit_duration., 2017-10-18). Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Return at least two days in multiple days modeLars Henriksen2019-05-301-1/+4
| | | | | Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Mark selected day in the appointments panel in multiple days modeLars Henriksen2019-05-282-4/+5
| | | | | Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Remove appointments panel scrollbar in multiple days modeLars Henriksen2019-05-281-0/+4
| | | | | | | | | | A scrollbar gives the impression of a fixed list. But the list on display is automatically and silently changed as needed for movements in the panel or the calendar, thus creating the illusion of an endless list. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Fix sidebar width to accommodate calendar week columnLars Henriksen2019-05-282-5/+3
| | | | | Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Fix missing calculation of number of days on resizeLars Henriksen2019-05-281-0/+4
| | | | | Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Automate the calculation of number of days to loadLars Henriksen2019-05-264-13/+20
| | | | | | | | | | | | Instead of having the user tell how many days to load, calcurse can calculate an overestimation from the running configuration (panel size, appearance of headers and separators etc.) The configuration variable conf.multiple_days is turned into a Boolean that switches the feature on and off. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Make separation of days conspicuousLars Henriksen2019-05-266-34/+60
| | | | | | | | | | | | | | | ... by adding a horizontal line from border to border above the day heading and turning the event separator into an empty line. The horizontal line is left out for the first day loaded. Also reduce the number of empty lines at the end of a day to at most one. A new configuration variable, header_line, turns the horizontal line on and off. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Derive selected day from selected itemLars Henriksen2019-05-226-13/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously, with only one day visible at a time, the appointments panel displayed the details of the day selected in the calendar (slctd_day); information required for operations on items (day_items) can often be derived from the selected day. The items available are derived from the selected day. In particular, the selected item is derived from the selected day. With multiple days in the APP panel, the relation between selected day (in the calendar) and the selected item (in the APP panel) has, in a way, been turned around. The selected item may now be moved between days without explicitly changing the selected day. Implicitly it is changed when the target day of a move is unavailable. This commit draws the full consequence: the selected day in the calendar is always (set to) the day of the selected item in the APP panel. The static variable 'struct date slctd_day' lives in ui_calendar.c and is accessible through various public functions. To these are added ui_calendar_set_slctd_day() which sets slctd_day directly. The selected day retains its significance for load of the day vector (in day_store_items()): the range of loaded days begins with the selected day. Movements (up/down) in the APP panel will change the selected day as the selected item moves among the already loaded days. Only when the target of a movement is unreachable, will further days be loaded. On the other hand, if the same range of days must be reloaded because of a changed item, the selected item - and with it the selected day - must be reset to the first day item (see do_storage()). Movements in the calendar (generic-next-day, etc.) are not affected and behave as previously, i.e. they will cause a range of days to be loaded with the selected day as the first and the selected item as the first of the selected day. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Add configuration variables for multiple daysLars Henriksen2019-05-226-8/+64
| | | | | | | | | | | | | | | The number of days displayed in the APP panel has been made configurable, maximum 21 days, default seven days. With several days in the APP panel, it may be desirable to "squeeze" the entries by leaving out the final empty line of each appointment and lower the number of lines between consecutive days (0, 1, or 2). Both are made general configuration options. To make a uniform display, an empty line is added to a day without appointments, if appointments have an empty line. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Add week numbers in the calendar and full first and last weekLars Henriksen2019-05-225-96/+165
| | | | | | | | | | | | | | | | | | | | | | | | | Much in the calendar is based on the selected day, struct date slctd_day, in ui-calendar.c. On the screen it is highlighted with a deviating colour. The highlight effect has been changed to a pair of red square brackets that do not obscure the day colour. The week number (in the frame) used to be that of the selected day, but has no obvious relation to the days in the APP panel. It has been replaced by the year day number of the selected day. The week numbers of all visible weeks are displayed to the left of the calendar. Dates are displayed also for the overlapping parts of the first and last week of the month (which do not belong to the month). Days are accessible in the appointments panel as well as in the calendar. Hence, validation of days (= inside UNIX time limits) must be extended from the calendar (in ui_calendar_move()) to include loaded days (in day_store_items()). Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Implement scrolling in the appointments panelLars Henriksen2019-05-224-21/+121
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | With multiple days in the APP panel, up/down movements should change behaviour at the top and bottom of the list displayed, and load the previous/next lot of days. This requires that the move function returns the result of the operation. Furthermore, the ability to move the selection to the beginning of a day is needed when moving down (in order to move from the first day to the last day). For this reason a DAY_SEPARATOR has been inserted also after the last day of a lot. Appointments have a listbox height of three to separate them clearly when there is more than one in a day. This leaves a spurious empty line at the end of a day with appointments. The DAY_SEPARATOR height is reduced from two to one, and a new EMPTY_SEPARATOR of height one is inserted in any day with only events. When scrolling up the DAY_HEADING becomes visible when the selection reaches the first item of the day. The length of the separator (between events and appointments) is adjusted to leave a space to the window border at both ends, thereby making it a part of the day, not a separation between days. The dummy event must also be recognisable when not the selected item and is only inserted in interactive mode. The test for a saved selection must also recognise caption items which have item pointer NULL. The function day_get_nb() has been renamed day_get_days(). Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Redesign selected-item implementation for the APP panelLars Henriksen2019-05-224-85/+144
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The day vector, day_items, is displayed in the appointments panel; the selected day_item object is highlighted (when the panel has the focus). When items are inserted, edited, moved etc., and when the day is changed, the day vector is rebuilt and displayed anew. Problem: How shall the selection be set automatically in the context of the new day vector? In previous versions all of the above is mostly handled by the function do_storage() in calcurse.c The function saves data about the selection as needed, rebuilds the day vector, loads the listbox and sets the selection from the saved selection data. This works well in "single day" calcurse in cases where the selected item is present in the day vector both before and after the rebuild, or when the item ordering in the listbox is unaffected by the changes. But when a new item is added the selection cannot be set to the new object by do_storage(). Instead the necessary operations are performed by ui_day_item_add(), and do_storage() is bypassed. In general, when an item cannot be found in the new vector, the item which occupies the old place in the list gets selected, e.g. when an item is deleted. When an item is turned into a repeating one, the old item is deleted and a new is created. Here the new selection is not always the affected item, but in any case not far away. Generally, with only one day in the panel an erronous selection might not be noticed or be accurate by chance. In "multiple day" calcurse the existing scheme works less well; in addition the day vector may now contain more than one object that refer to the same event or appointment (recurrent items or multi-day appointments). The scheme has therefore been modified. The do_storage() function is no longer bypassed, but handles day vector rebuild, load of listbox and item selection exclusively. To make that possible, data about the selected item is no longer saved in a local automatic variable, private to do_storage(), but in an external static variable in day.c, which may be set not only by do_storage(). The variable is declared as static struct day_item sel_data; and used as follows: 1. On startup sel_data is initialized to empty (i.e. no selection). 2. In any operation involving the appointments panel: 2.1 Do the work and if necessary set sel_data. This is the case when deleting, adding or pasting an item, and when turning an ordinary item into a recurrent one. 2.2 Call do_storage(). 3. In do_storage(): 3.1 If sel_data is empty, set it to the current selection. 3.2 Rebuild the day vector. 3.3 Set the selection from sel_data. 3.4 Set sel_data to empty. Further remarks --------------- The selection is found in the new day vector by searching for the saved (order, item.<pointer>) pair. Previously the item.<pointer> alone sufficed and in some cases it still does. In case the item cannot be found, the selection stays in the same day as before the rebuild. An attempt at more consistently named APP-related functions has led to: ui_day_sel_date() replaces ui_day_sel_day() ui_day_get_sel() replaces ui_day_selitem() Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Introduce multiple days in the appointments panelLars Henriksen2019-05-226-49/+115
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Overview of existing implementation ----------------------------------- The APP panel displays the 'day_items' vector in the 'lb_apt' listbox. A listbox consists of a scrollwin (structure) in which a number of items is displayed. The listbox keeps track of: - the number of items - the selected item - the type of each item in an array type[] - the height of each item (ie. how many screen lines) in an array ch[] - how to display an item (on the screen) The latter three are handled by functions fn_type(), fn_height(), fn_draw(). The first two are used to fill in the corresponding array entry, type[] or ch[], for item number i, the third draws item number i. The items are taken from the global variables vector_t day_items int day_items_nb in day.c. Items include captions (DAY_HEADING, DAY_SEPARATOR). Everything is sorted for display (DAY_HEADING, events, DAY_SEPARATOR, appts). These are filled in ("stored") [by day_store_items() for the selected day in the calendar], before being "loaded" into the listbox. See do_storage() in calcurse.c and ui_day_item_add() in ui-day.c. New APP panel design -------------------- Several days are displayed in the APP panel by loading them with day_store_items(). With several days come several headings and separators. DAY_SEPARATOR is reinterpreted to separate days, and a new separator, EVNT_SEPARATOR, separates events from appointments. To sort everything, an 'order' member of type time_t is added to the day_item structure. It is set for headings and separators as well as for appointments and events as follows: item order --------------------- DAY_HEADING BGNOFDAY (= midnight) EVNT_SEPARATOR BGNOFDAY DAY_SEPARATOR ENDOFDAY event start time (midnight) appointment start time (first day) BGNOFDAY (following days, if any) The sort function day_cmp() (used by vector_sort) is extended to sort by order first. The order field always indicates the day to which an item belongs. This comes in handy, because with several days in the APP panel it is necessary to distinguish between the selected day in the calendar and the selected day in the APP panel. This raises the question which day should actions (commands) operate on: the one selected in the calendar or the one selected in the APP panel? Unquestionably the one on the APP panel which is the one tacitly implied. In most cases it is not a problem, though, because actions work on the selected item and the selected day does not come into play. But in some cases it does: delete item When deleting an occurrence of a repeated item, the selected day is the exception day to add. view item day_popup_item() needs the day of the selected item for display of correct start/end times. cut/paste item Paste needs the selected day in which to paste. add item The day of the new item is taken from the calendar. Instead a dummy event is inserted in an empty day. This makes the day selectable, which is otherwise impossible with only the DAY_HEADING displayed. The dummy event is selectable but cannot be edited or deleted (but viewed or piped). With more than one day in the day_items vecter, an appointment spanning more than one day may occur more than once in the vector (with start/end times suitably adjusted for display). A day_item is no longer (always) identified by the aptev_ptr (item) value. Instead the combination (order, item.<ptr>) is used; order is roughly the day. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Simplify day storageLars Henriksen2019-05-226-44/+15
| | | | | | | | | | | The function day_process_storage() is a wrapper for day_store_items(). It has an unused second argument, and is only used twice to load the selected day. It has been removed. A new function, get_slctd_day(), is the equivalant of get_today() and replaces the very awkwardly named ui_calendar_get_slctd_day_sec(). Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Fix initialization of the day_items vectorLars Henriksen2019-05-221-0/+1
| | | | | | | | | | | | | | | | This patch fixes all failings tests, but one, in PR #193. Until now the missing initialization of day_items_nb has caused no problems, because the variable was assigned to (=) before being used. In the Multiple days implementation it is repeatedly increased (+=) in a loop without being initialized first. Indeed, this may considered an easily fixed bug. But the initialization really belongs in day_init_vector() so that the call day_item_count(0) returns 0 if done right after the call day_init_vector(). The bug only shows up in command line mode because day_items_nb is not used in interactive mode. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Refactor listbox codeLars Henriksen2019-05-223-40/+49
| | | | | | | | | | | | | | | | | | | | | | | | | The changes are related to the selected item and the visible lines in the scroll window viewport. In particular, the function listbox_fix_visible_region() has been eliminated, and functions previously only called by it have been removed. It performed several tasks that are now elsewhere. One was removed in an earlier commit (scroll window pad improvement). The task of making a multi-line item visible has been moved to listbox_item_in_view(). The task of making a caption line above a text line visible is listbox specific (for the ap_list) and will be moved to ui_day_sel_move(), where it is needed. Boundary checks for the listbox selection have been moved to listbox_fix_sel(). For future use listbox_sel_move() returns success or failure. The function wins_scrollwin_ensure_visible() has been renamed wins_scrollwin_in_view(). Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Improve scroll window padLars Henriksen2019-05-224-24/+16
| | | | | | | | | | | | | | | | | | | A scroll window consists of a pad to write on, and a window through which to view the pad, the viewport. The pad may change in size when new contents are loaded into the scroll window. If so, the pad size is set with wins_scrollwin_set_linecount(). But the offset into the pad (the top line to be displayed in the viewport) is not adjusted, although it may not be appropriate for the new pad size. The same is the case when a scroll window is resized and the viewport changes size. This is probably the cause of the problem solved by commit 0b46ad4, Avoid blank space after the last list box item, and the fix has been removed. The wins_scrollwin_set_linecount() has been renamed wins_scrollwin_set_pad() and sets size as well as offset. The offset is only changed if necessary. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Impossible dates in recurrence rulesLars Henriksen2019-05-201-0/+12
| | | | | | | | | | | | | | | According to RFC 5545 dates like 30 February and 31 June must be ignored when derived from a recurrence rule. calcurse relies on mktime() "normalization" of dates (e.g. turning 32 December 2019 into 1 January 2020 when moving from 31 December to the next day). Normalization may also lead to impossible dates in monthly and yearly recurrence rules, and this must be avoided. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Fix display of time left before next appointmentLars Henriksen2019-04-132-7/+12
| | | | | | | | | | | | | | | | | | In the notify bar, the clock is shown in hours, minutes and seconds, whereas the time left to the next appointment is shown in hours and minutes only. When you read the clock in hours and minutes (discarding the seconds), you are mentally rounding down to the nearest minute. To agree with that reading, the time left (in seconds) should be (programmatically) rounded up to the nearest minute for display. In that way the time left is counted down whenever the minute "hand" of the clock "ticks", and reaches zero when the clock reaches the time of the next appointment, not one minute before. Also, the clock (in hours and minutes) and the time left always add up to the time of the next appointment. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Fix daemon notification for short warning periodsLars Henriksen2019-04-131-2/+3
| | | | | | | | | | | | When the warning period for notifications is less than 60 seconds (DAEMON_SLEEP_TIME), the daemon may be at sleep when the appointment comes up. If that happens, no notification is launched. In stead, the daemon should launch the notification early. Addresses GitHub issue #204, part 2. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Fix one-second warning period for notificationsLars Henriksen2019-04-132-2/+2
| | | | | | | Adresses GitHub issue #204, the interactive part. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Use ICALDATETIMEFMT for EXDATEHenrik Grimler2019-04-131-2/+2
| | | | | | Some servers (Radicale) cannot handle YYYYMM. Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Avoid deadlock in config_save()Lars Henriksen2019-03-211-7/+8
| | | | | | | | | Must not exit with nbar.mutex locked. Addresses GitHub issue #201. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Fix calendar (re)drawLars Henriksen2019-03-131-10/+4
| | | | | | | | | Window erasure is moved to the drawing functions. Adresses GitHub issue #196. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Fix vector_remove()Lars Henriksen2019-03-131-1/+1
| | | | | Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Change -C and -D long option namesvxid2019-03-131-2/+6
| | | | | | | | | | The config dir long option has been changed from --conf to --confdir. The data dir long option has been changed from --directory to --datadir. Both old options are kept for backward compatibility but are removed from the manual. Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* View or edit exception days of a recurrent itemLars Henriksen2019-02-283-1/+72
| | | | | | | | | | | | The exception days are presented for viewing/editing as a string of space-separated dates (in the user-preferred input format). After editing the string is checked for valid dates, but there is no check that a date is meaningful (an occurrence day of the item between start day and until day). Although possible, it is best to add exception days in the usual way by deletion of occurrences. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Fix empty dynamic stringLars Henriksen2019-02-281-0/+1
| | | | | Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Check for KEY_ENTER in getstring()Lukas Fleischer2019-02-101-1/+2
| | | | | | | | In some cases (e.g., TERM=pccon0) wgetch(3) can return KEY_ENTER instead of '\n' when the return key is pressed, causing getstring() to fail. Suggested-by: Mikolaj Kucharski <mikolaj@kucharski.name> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Use portable default day heading formatLukas Fleischer2019-02-101-1/+1
| | | | | | | | The %-d format string is not standards-compliant. Use %e instead. Reported-by: Mikolaj Kucharski <mikolaj@kucharski.name> Suggested-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Close stream after exporting iCal itemcrvs2019-02-041-0/+1
| | | | | | Fixes GitHub issue #178. Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Invalidate calendar cache when adding an exceptionLukas Fleischer2019-02-021-1/+3
| | | | | | | Removing an occurrence of a recurrent item can turn a busy day into a free day. Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Fix deletion of a multi-day recurrent appointmentLars Henriksen2019-02-021-2/+11
| | | | | | | | | | When the selected day in the calendar is a continuation day (not the first day) of such an appointment, deleting the occurrence does not work. The reason is that the selected day, and not the first day of the occurrence, is added as an exception day. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Refactor keys_format_label()Lukas Fleischer2019-01-191-24/+9
| | | | | | | Simplify the key formatting function and enforce display width properly using the UTF8 chopping function. Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
* Bind RETURN to view-item by defaultLukas Fleischer2019-01-191-2/+2
| | | | | | | | | Also, use the modern key name instead of the backwards compatibility name. Addresses GitHub issue #168. Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>