diff options
author | Frederic Culot <calcurse@culot.org> | 2006-07-31 21:00:02 +0000 |
---|---|---|
committer | Frederic Culot <calcurse@culot.org> | 2006-07-31 21:00:02 +0000 |
commit | ac36e94341ca73d581f0df39f1c7bbf2138b2845 (patch) | |
tree | 47de561cd962ff8f47f6d811109907f15b9ff989 | |
download | calcurse-ac36e94341ca73d581f0df39f1c7bbf2138b2845.zip |
Initial revision
-rwxr-xr-x | AUTHORS | 1 | ||||
-rwxr-xr-x | ChangeLog | 606 | ||||
-rwxr-xr-x | Makefile.am | 11 | ||||
-rwxr-xr-x | NEWS | 104 | ||||
-rwxr-xr-x | README | 31 | ||||
-rwxr-xr-x | TODO | 58 | ||||
-rwxr-xr-x | autogen.sh | 174 | ||||
-rwxr-xr-x | configure.ac | 44 | ||||
-rwxr-xr-x | doc/manual_de.html | 728 | ||||
-rwxr-xr-x | doc/manual_en.html | 783 | ||||
-rwxr-xr-x | doc/manual_fr.html | 898 | ||||
-rwxr-xr-x | po/LINGUAS | 4 | ||||
-rwxr-xr-x | po/POTFILES.in | 14 | ||||
-rwxr-xr-x | po/calcurse.pot | 760 | ||||
-rwxr-xr-x | po/fr.po | 966 | ||||
-rwxr-xr-x | src/Makefile.am | 14 | ||||
-rwxr-xr-x | src/apoint.c | 235 | ||||
-rwxr-xr-x | src/apoint.h | 56 | ||||
-rwxr-xr-x | src/args.c | 431 | ||||
-rwxr-xr-x | src/args.h | 41 | ||||
-rwxr-xr-x | src/calcurse.1 | 158 | ||||
-rwxr-xr-x | src/calcurse.c | 1156 | ||||
-rwxr-xr-x | src/calendar.c | 227 | ||||
-rwxr-xr-x | src/calendar.h | 41 | ||||
-rwxr-xr-x | src/custom.c | 178 | ||||
-rwxr-xr-x | src/custom.h | 42 | ||||
-rwxr-xr-x | src/day.c | 362 | ||||
-rwxr-xr-x | src/day.h | 66 | ||||
-rwxr-xr-x | src/event.c | 135 | ||||
-rwxr-xr-x | src/event.h | 48 | ||||
-rwxr-xr-x | src/help.c | 375 | ||||
-rwxr-xr-x | src/help.h | 41 | ||||
-rwxr-xr-x | src/i18n.h | 54 | ||||
-rwxr-xr-x | src/io.c | 484 | ||||
-rwxr-xr-x | src/io.h | 42 | ||||
-rwxr-xr-x | src/recur.c | 355 | ||||
-rwxr-xr-x | src/recur.h | 87 | ||||
-rwxr-xr-x | src/todo.c | 80 | ||||
-rwxr-xr-x | src/todo.h | 41 | ||||
-rwxr-xr-x | src/utils.c | 614 | ||||
-rwxr-xr-x | src/utils.h | 55 | ||||
-rwxr-xr-x | src/vars.c | 85 | ||||
-rwxr-xr-x | src/vars.h | 69 |
43 files changed, 10754 insertions, 0 deletions
@@ -0,0 +1 @@ +Frederic Culot <frederic@culot.org> diff --git a/ChangeLog b/ChangeLog new file mode 100755 index 0000000..e459b35 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,606 @@ +27 Jul 2006: + back to work after my ibook's logic board crash :( + autogen.sh created + +25 Jun 2006: + app_arg() updated to take recurrent items into account + recur_apoint_s2apoint_s() created + added help text concerning possible formats to be entered when using + '-h' flag in non-interactive mode + fixed a bug related to localtime() which returns a statically + allocated structure that can be overwritten by subsequent calls + to the function (which was the case with recurrent items) + load_app(), recur_event_scan(), recur_apoint_scan(), recur_item_inday(), + recur_event_write() and recur_apoint_write() updated to take endless + recurrent items into account + +24 Jun 2006: + cvs keywords added inside source files + apoint_sec2str() and display_item_date() modified to take recurrent + items into account + day_check_if_item() created + +18 Jun 2006: + day_store_recur_events() and day_store_recur_apoints() created + recur_item_inday() created + +17 Jun 2006: + day_popup_item() created + pointers to number_events_inday and number_apoints_inday passed to + day_store_items() + day_write_pad() updated to reallocate memory for day_saved_item structure + +16 Jun 2006: + free_aday() and free_eday() suppressed and replaced by day_free_list() + day_store_items() created + store_day() updated to call day_store_items() + eday_store() and aday_store suppressed and replaced by day_store_events() + and day_store_apoints() + edayadd() and edayadd() suppressed and replaced by day_add_event() + and day_add_apoint() + write_app_pad() suppressed and replaced by day_write_pad() + day_item_s2apoint_s() created + +14 Jun 2006: + day.c and day.h created to store processes related to the currently + selected day inside calendar (this is to ease the implementation of + recursive items) + src/Makefile.am updated + +08 Jun 2006: + recur_save_data() created + recur_char2def() created + +07 Jun 2006: + recur_apoint_scan() and recur_event_scan() created + load_app() updated to read recursive events from file + +06 Jun 2006: + bugfix: Debian Bug Report #369550 regarding the segfault which + appeared when calcurse was launched in non-interactive mode without + data files + recur.h and recur.c added to implement recursive events + src/Makefile.am updated + recur_event_new()and recur_apoint_new() created + recur_def2char(), recur_apoint_write() and recur_event_write() created + +15 May 2006: 1.4 + TODO, README, manpage and manual updated + +13 May 2006: + NEWS file updated + +11 May 2006: + manual_de.html finished : many thanks to Michael Schulz + manual_fr.html updated + +08 May 2006: + manual_en.html updated + bugfix: added test at the end of color_config() to check the need + of using colorization or not + +07 May 2006: + french translation finished + manpage updated + +05 May 2006: + added LOCALEDIR definition in configure.ac + usage_try() created + +27 Apr 2006: + removed VERSION definition from vars.h to only use the one from + configure.ac + include config.h added in calcurse.c + +26 Apr 2006: + updated exit() calls by using EXIT_SUCCESS and EXIT_FAILURE + end of source preparation for i18n + replaced required confirmation string from 'yes' and 'no' to 'y' and 'n' + 'gettextization' of source package: + * Makefile.am (SUBDIRS): Add po. + (ACLOCAL_AMFLAGS): New variable. + (EXTRA_DIST): Add config.rpath, mkinstalldirs, m4/ChangeLog. + * configure.ac (AC_OUTPUT): Add po/Makefile.in. + +25 Apr 2006: + updated parts related to general config variables to handle i18n: + general config variables type changed to boolean + fill_config_var() created + switch_option() suppressed + +23 Apr 2006: + progress_bar() modified to better fit the data file structure + user_conf_t created to allow translation of configuration variables + +22 Apr 2006: + translatable strings marked for i18n + manual_de.html added (german translation of calcurse manual, + thanks to Michael Schultz) + +20 Apr 2006: + i18n.h added to prepare for internationalization + src/Makefile.am updated + +18 Apr 2006: + code cleanup: color_config() simplified + +17 Apr 2006: + variable 'colorize' added + color number '0' added to be able to run calcurse in black&white + even on color terminals + +16 Apr 2006: + border_nocolor() created to correctly handle panel borders in + non-color terminals + 'week_begins_on_monday' option added, giving the ability to change + the first day of the week (thanks to Joe's remarks) + +09 Apr 2006: + bugfix: stderr replaced by stdout in version_arg(), help_arg(), + todo_arg(), app_arg(), date_arg(), arg_print_date(), usage() + (thanks go to Soren for reporting that bug) + +08 Apr 2006: + html manual translated in french (manual_fr.html created) + +05 Apr 2006: + README file rewritten to take into account the new documentation structure + +02 Apr 2006: + support for non-color terminals added : + window attribute levels defined in vars.h + attribute_s structure created in custom.h + custom_init_attr(), custom_apply_attr(), and + custom_remove_attr() created in custom.c + init_vars() updated in calcurse.c + +30 Mar 2006: + doc/ repertory created to contain calcurse documentation and its + translations. Makefile.am updated to take the new repertory into + account + +23 Mar 2006: + manual_en.html created, in order to replace the actual documentation + contained in the README file + +17 Mar 2006: 1.3 + bugfix: newpad added in init_vars to correct a bug causing core dump on + Solaris + bugfix: no more wrong event duration when entering end time in [hh:mm] + format + bugfix: first_todo_onscreen corrected to avoid the disappearing of + todo items + updated the copyright text which appears with the -v flag + manpage updated + README updated + online help updated + TODO list updated + +14 Mar 2006: + replaced true and false #define by stdbool.h + +13 Mar 2006: + online help screens updated + +09 Mar 2006: + typedef help_page_t added to add a title to each help page + help_screen() and write_help_pad() updated to use new help_page_t type + +07 Mar 2006: + #define true and false added in vars.h + online help screens updated + +06 Mar 2006: + source file headers updated + +26 Feb 2006: + get_help_lines() created + scrollbar added inside help screens + +25 Feb 2006: + help_screen() updated, now using a pad to display help screens + write_help_pad() created + +19 Feb 2006: + display structure updated to take into account the scrollbars + previous_item_mark() and next_item_mark() suppressed, scrollbar used instead + bugfix: hilt_tod and hilt_app were not updated when deleting an item + day_changed variable added and store_day() updated + bugfix: pad scrolling was not updated when deleting an item in the + appointment panel + bugfix: scrollbar length and top position were not correct in some + cases + +18 Feb 2006: + enum window_number created + bugfix: start and end time now properly displayed when viewing an + appointment in popup window + bugfix: wrong highlited item when changing day fixed + draw_scrollbar() created to display a real bar inside panels instead + of 'v' and '^' marks + update_todo_panel() and update_app_panel updated to display the scrollbar + +16 Feb 2006: + del_apoint() updated to take events into account + +11 Feb 2006: + AC_HEADR_STDBOOL added in configure.ac + init_vars() created + do_storage variable added to check if we really need to update the + appointment panel items inside pad + free_aday() and free_eday() created + +09 Feb 2006: + pad_s structure created + get_item_line(), scroll_pad_down() and scroll_pad_up() created + +05 Feb 2006: + get_item_line() created + +04 Feb 2006: + work on the way appointment panel scrolls + updated the way appointments are displayed in popup windows + +28 Jan 2006: + write_app_pad() improved + +26 Jan 2006: + improved the windows refresh order in update_windows() + +25 Jan 2006: + changed MAX_LENGTH to 512 + the pad used to display appointments has a fixed length now + +14 Jan 2006: + store_day() created to speed up the appointment panel update + create_app_pad(), write_app_pad(), show_app_pad() created to + improve the way appointment panel scrolls + +10 Jan 2006: + added ifndef..define tests at the beggining of .h + +08 Jan 2006: + added definition of CTRL keys in vars.h + added the ability to erase characters with CTRL-H when entering + text (to fix a problem reported by Brendan who was not able to + delete with its English keyboard) + +07 Jan 2006: + progress_bar() created in order to see progression while saving + data to file + 'skip_progress_bar' option added + changed color 5 to be yellow on black and color 7 to be black on + yellow (this is to draw the newly created progress bar) + +31 Dec 2005: + removed the -lpanel that was left in src/Makefile.am + README updated + add_item() and check_time() modified so that : + o an appointment start time can now be entered in both + hh:mm and h:mm formats + o for the appointment end time, either a duration in + minutes or the appointment end time can be entered + help_arg() and app_arg() updated to take events into account + when running calcurse in non-interactive mode + arg_print_date() created to simplify app_arg() structure + +27 Dec 2005: + work on a better way to handle appointment and todo panels with the + use of ncurses scrolling functions + +26 Dec 2005: + bugfix: fixed compiler warnings, thanks to Uwe + +11 Dec 2005: + bugfix: fixed the January 0 bug + bugfix: current date is no longer highlighted in every year of the + future and the past (thanks to Michael for reporting that bug) + improved the way items are shown inside popup windows (variable + 'show_apoint' removed, call to item_in_popup added when 'V' pressed) + +10 Dec 2005: + update_app_panel() and update_todo_panel() improved + +04 Dec 2005: + update_app_panel() updated to show events: now events are displayed + first in the appointment panel, followed by an horizontal line + update_cal_panel() updated to highlight days containing events + in calendar view + +03 Dec 2005: + Loading of events implemented: load_app() updated + +30 Nov 2005: + Saving of events implemented + +29 Nov 2005: + Continuation of events item implementation + add_apts() updated (it is now called add_item) to check if + an appointment or an event is entered + +28 Nov 2005: + Replaced everything related to 'event' by 'apoint' (appointments) + to prepare the incoming event items (meaning all-day long items) + event.c and event.h created to deal with events + Makefile.am updated + +26 Nov 2005: 1.2 + Fixed problems with scroller() within the help screen + +20 Nov 2005: + Improved the way help screens are refreshed + Removed call to doupdate() inside scroller(), to prevent redondancy + config_bar() and check_data_files() updated + 'skip_system_dialogs' option added + +19 Nov 2005: + reinit_wins() created to redraw windows after resizing or layout + change + redraw_screen() improved and renamed it into get_screen_config() + fixed cursor position (did not manage to hide it :-( + +08 Nov 2005: + changed all mvprintvw() calls to mvwprintw(), to improve the way + calcurse interface is refreshed. + +06 Nov 2005: + Work on window handling : + o erase_panel() suppressed because no longer used + +05 Nov 2005: + Handling of status bar improved : + o creation of an ncurses window instead of using stdscr + o erase_status_bar() replaced by erase_window_part() + cal_error() replaced by status_mesg() + +03 Nov 2005: + ncurses library use improved: screen no longer flickers when + refreshed + +02 Nov 2005: + erase_window_part() written to erase parts of windows + +01 Nov 2005: + changed abbreviation for 'Wednesday' from 'Wen' to 'Wed' + panel library removed, calcurse does not use it anymore + work on the windows refreshing process : update_all() created + +29 Oct 2005: 1.1 + source code cleaning + version 1.1 released + +25 Oct 2005: + bugfix : Debian Bug Report #335430 regarding the GoTo today + function which goes to the day calcurse was started instead of + the current day is now fixed + +23 Oct 2005: + '-c' flag added to allow the use of multiple calendars + +20 Oct 2005: + manpage and README file updated + configure.ac improved with the help of Michael + +19 Oct 2005: + '-d' flag added to list appointments for the N upcoming days or + for a given day + +15 Oct 2005: + Cleaning up of the source code so that it follows the K&R style + '-t' flag added to list todos in non interactive mode + '-a' flag added to list current day's appointments in non + interactive mode + +13 Oct 2005: + functions created to handle command-line arguments (written in + args.c and args.h) + '-h' and -'v' flag added to display help and version in non + interactive mode + +08 Oct 2005: 1.0 -> first stable release + help screen updated + manpage and TODO updated + +06 Oct 2005: + bugfix : Debian Bug Report #330869 regarding the October 0 which + does not exist, is now fixed + +05 Oct 2005: + default options "auto-save", "confirm-quit", and + "confirm-delete" set to "yes" + +03 Oct 2005: + manpage written + README updated + +13 Sep 2005: 1.0rc4 + bugfix release : + o some people reported a segfault while changing general + options in the config screen, this no longer happens + o the Makefile was not linking to proper library (-lcurse + instead of -lncurse), this is fixed + o Calcurse no longer ends while trying to delete an event + which was just created (thanks to Alex's patch) + o changed date format to be like September 13, 2005 instead + of September, 13 2005 + +11 Sep 2005: 1.0rc3 -> first public release + adding of licence header in source files + +04 Sep 2005: + source code splitted : creation of custom.c, custom.h + update of the Makefile + layout_config() : previous layout is now saved to restore it if + no choice is made + color_config() : previous colour is also saved as in + layout_config() + +31 Aug 2005: + source code splitted : creation of vars.c, vars.h, io.c, io.h, + help.c, help.h + update of the Makefile + modification of the cal_error function + +30 Aug 2005: + source code splitted : creation of calendar.c & calendar.h, + update of the Makefile + +29 Aug 2005: + source code splitted : creation of utils.c & utils.h, update of + the Makefile + +03 Jul 2005: + redraw_screen() created for initialization of screen + draw_screen() optimization for slow machine + +02 Jul 2005 : + help screen updated + is_all_digit() created to check if a string is made of digits + check_event_time() created to check a new appointment time format + bugfixes -> + when 'G' pressed, no crash when invalid day is entered + when 'V' pressed, no crash when no event is highlited + Calcurse is now started in calendar view + scrolling problems fixed in app or todo view + first event is highlited if it is the first time a panel is visited + check if an new appointment format is valid + we can now move from year to year in calendar view + config screen is ok in OpenBSD too now + +26 Jun 2005 : 1.0rc2 + translation of the Changelog + writing of the README file + comments in the code + use of gnu autotools for building CalCurse package + -> CalCurse v1.0rc2 + +19 Jun 2005 : + scroller() improvement : the line is cut at the end of the last word, + not in the middle of it, and the 'next page' and 'previous page' + function was added + bug concerning the event printing in popup windows solved + +18 Jun 2005 : + help improved + +17 Jun 2005 : + writing of a function to erase appointments + +14 Jun 2005 : + writing of a function to erase todo events + adding of the confirm_delete variable + +12 Jun 2005 : + improvement of the status bar, it is now dependant of the terminal + size + adding of the terminal minimum size test + adding of a scrolling function in the ToDo panel if there is more + events than the panel lines + creation of the ~/.calcurse repertory if it does not exist when + CalCurse is launched + +04 Jun 2005 : + colorization of the selected event + view function created to print out an event in a popup window (ok for + ToDo events) + active panel is now colorized + +26 May 2005 : + update_todo_panel() now improved :) (3 dots are added at the end of + the event if it is longer than the panel size) + erase_tod() created to erase the todo panel + erase_tod(), erase_app() and erase_cal() linked in one single function + : erase_panel() + popup() created to print a popup window + +25 May 2005 : + tries for improving update_todo_panel() :( + +18 May 2005 : + changing of the status bar (different bars for calendar and other + panels) + +14 May 2005 : + possibility to change the selected panel with TAB key + +12 May 2005 : + scroller() improved + +20 Apr 2005 : + scroller() function created + help screen improved, with scroller description + +10 Apr 2005 : + the bug concerning the erasing of calendar lines is solved : a + refresh() was missing :( + -> CalCurse testing version is now almost over :) + +08 Apr 2005: + help menu improved, with a description for each possible action in + Calcurse + +07 Apr 2005 : + adding of the auto-save and auto-confirm variables with tests when + quitting Calcurse + adding of general options in the config menu (auto-save and + confirm-quit added) + writing of general_config(), print_general_options(), switch_options + and print_option_incolor() + improvement of functions to read and save user config, to take those + two new options into account + +02 Apr 2005 : 1.0rc1 + test function (e key) suppressed + add_apts() finished + goto_day() finished (we can now enter any day to go to) + -> CalCurse v. 1.0rc1 ;) + +01 Apr 2005 : + work with Alex : + ToDo events are put in right order + writing of todo.h and todo.c + writing of date2sec() + improvement of the function to create and print the + Appointments, which are now put in right order + writing of event_delete_bynum() + writing of a function to colorize a day which contains an + event + improvement of the Makefile + +27 Mar 2005 : + do_modifs_todo() finished : the ToDo events are now properly erased + +06 Mar 2005 : + improvements of do_modifs_todo() + +05 Mar 2005 : + extract_data() created to read the user conf from file + extract_todo() becomes extract_data() + -> the user config is now properly read + +03 Mar 2005 : + load_conf() created to load the user config + +02 Mar 2005 : + improvement of save_cal() to save the user configuration + (creation of the file .calcurse/conf, update of check_data_files) + +01 Mar 2005 : + improvement of do_modifs_todo() + writing of the test function (when 'e' is pressed) + +27 Feb 2005: + layout_config() finished + adding of the GPL licence + +26 Feb 2005: + adding of the layout variable + writing of layout_config() started + +25 Feb 2005 : + adding of a DEFINE for version number + creation of the help page + creation of the configuration menu, with color changing for now on + +15 Mar 2004: + beggining of the project diff --git a/Makefile.am b/Makefile.am new file mode 100755 index 0000000..56617b8 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,11 @@ +# $calcurse: Makefile.am,v 1.1 2006/07/31 21:00:02 culot Exp $ + +AUTOMAKE_OPTIONS= gnu +SUBDIRS = po src +EXTRA_DIST = ABOUT-NLS \ + doc/manual_en.html \ + doc/manual_fr.html \ + doc/manual_de.html + +ACLOCAL_AMFLAGS = -I m4 + @@ -0,0 +1,104 @@ +[15 May 2006] +Version 1.4 +- New features: + * Support for i18n added + + * Support for non-color terminals added + + * Option added to choose which day is the first of the week + (monday or sunday) + + * Documentation improved, with translated html manuals + +- Bugfixes: + * When confirmation is requested, it is now done by pressing + 'y' or 'n' instead of 'yes' or 'no' + +- Translation: + * french translation + + * french and german manuals + + +[17 Mar 2006] +Version 1.3 +- New features: + * Adding of all-day long events + + * Many GUI improvements: + o better scrolling (with the use of ncurses pad functions) + o scrollbars added + o progress bar added + + * Appointment duration can now be entered either in minutes or in + hh:mm format + +- Bugfixes: + * January 0 bug fixed + + * Current day is no longer highlighted in every year of the future + and the past (thanks to Michael for reporting that bug) + + * Fixed compiler warnings (thanks to Uwe for reporting this) + + * Removed -lpanel link during compilation + + * Characters can now be erased with CTRL-H (to fix a problem + reported by Brendan) + + +[26 Nov 2005] +Version 1.2 +- New features: + * An option was added to skip system dialogs + + * Configure script was improved + +- Bugfixes: + * Ncurses library use improved: screen refreshing is faster, + windows do not flicker anymore when updated, and memory + footprint is much smaller + + * Changed abbreviation for 'Wednesday' from 'Wen' to 'Wed' + + +[29 Oct 2005] +Version 1.1 +- New features: + * Command-line options which allows to display appointments and + todo list without entering the interactive mode + + * Manpage and documentation updated + + * Configure script improved + +- Bugfixes: + * Debian Bug Report #335430 regarding the GoTo today function + is now fixed + + +[08 Oct 2005] +Version 1.0 First stable release +- New features: + * Calcurse now comes with a manpage + +- Bugfixes: + * Debian Bug Report #330869 regarding the October 0 which does not + exist is now fixed + + * Default options "auto-save", "confirm-quit", and + "confirm-delete" were set to 'yes' + + +[11 Sep 2005] +Version 1.0rc3 Firtst public release + + +[26 Jun 2005] +Version 1.0rc2 +beta version + + +[02 Apr 2005] +Version 1.0rc1 +beta version
\ No newline at end of file @@ -0,0 +1,31 @@ + README file for the calcurse package + +See the file INSTALL for instructions on how to build and install calcurse. +See the file Changelog for a release history and bug-fix notes. +See the file TODO for things that still need doing. + +Browse the file doc/manual_xx.html (where xx stands for a language +abbreviation) for narrative descriptions of how to use calcurse. + + +PACKAGE OVERVIEW: + + You should be reading this file in a directory called: calcurse-x.x, + where x.x is the current version number. There should be two + subdirectories : 'src' and 'doc'. + Detailed documentation in html format can be found in the 'doc' + directory. Calcurse sources can be found in the 'src' directory. + + +AUTHOR: + + Frederic Culot + + +CONTRIBUTORS: + + Michael Schulz: calcurse manual german translation. + + See also the 'Thanks' section in doc/manual_xx.html for a list of + people who have contributed by reporting bugs, sending fixes, or + suggesting improvements. @@ -0,0 +1,58 @@ + + Calcurse TODO list : + -------------------- + +Here are listed the modifications I will perform on Calcurse in future +releases. They are ordered into three different parts, depending on the +priority. Feel free to send me an email (see the AUTHORS file) if you +would like to see a feature added in Calcurse which does not appear in +this list. + +------------------------------------------------------------- +Recur: + o ecrire routines pour demander a l'utilisateur de rentrer les + evenements recursifs + + o lorsque j'ai à la fois des évenements et des rdv récurrents, ils ne + sont pas affichés dans le bon ordre, et il n'y a pas de traits entre + chaque + + o implémenter la suppression des elements recursifs + + o mettre à jour les fichiers po/ + + o tagger les fichiers avec marqueurs CVS + + o rajouter dans les remerciements du manuel + les personnes qui me font les autres + paquets calcurse +------------------------------------------------------------- + + +High +---- + o Implement recursive events and appointments + o Add a cron interface to get noticed of events by mail + o Add a week view in the calendar panel + o Add a clock to show current time and date + + +Average +------- + o Add import capabilities to read ical files inside calcurse + o Add export capabilities to create html (or other format) files + o Accept dates entered in other formats such as d/m/yyyy or d/m/yy, + make the date format user configurable + o Make keys user configurable + + +Low +--- + o Add shortcuts which would apply everywhere (for exemple A to add an + appointment even if you are in the calendar panel) + o Add 't' alias for 'g - Enter' + o Create external calendars which would contain hollydays and such (in ics + format, as in mozilla sunbird).. + o All status bars should be terminal-size dependant (config_bar is not) + o Improve check_event_time() using sscanf as in goto_day() + o Get rid of the scroller() function diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..aa44551 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,174 @@ +#!/bin/sh +# +# Copyright (c) 2004-2006 Frederic Culot +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# +# Send your feedback or comments to : calcurse@culot.org +# Calcurse home page : http://culot.org/calcurse +# +# $calcurse: autogen.sh,v 1.1 2006/07/31 21:00:02 culot Exp $ +# +# +# autogen.sh - Generates all the necessary files to build calcurse from +# cvs tree. +# + +PKG_NAME=calcurse +AC_VERSION="2 59" +AUTOCONF_VERSION=2.59 +AC_FLAGS= +AM_VERSION="1 9" +AUTOMAKE_VERSION=1.9 +AM_FLAGS="--gnu --copy --add-missing" +GETTEXT_VERSION="0 14" +GETTEXT_FLAGS="--copy --no-changelog" +ACLOCAL_FLAGS="-I m4" +SRCDIR=`dirname $0` +test -z "$SRCDIR" && SRCDIR=. +export AUTOMAKE_VERSION AUTOCONF_VERSION + +# Function to check if we are at the top level of calcurse package. +check_directory_level() +{ + (test -f $SRCDIR/configure.ac) || { + printf "\n\n**Error**: Directory "\`$SRCDIR\'" does not appear to" + printf "\nbe the top-level $PKG_NAME directory.\n" + exit 1 + } +} + +# Clean previous files before running scripts +clean_old_files() +{ + printf "Cleaning old files ... " + rm -rf configure config.log aclocal.m4 \ + config.status config autom4te.cache \ + po/Makefile.in.in + printf "done\n" +} + +# Clean useless backup files +clean_backup_files() +{ + printf "Cleaning backup files ... " + rm -rf configure.ac\~ Makefile.am\~ + printf "done\n" +} + +# Function to check for a program availability +check_program() +{ + PROGRAM=$1 + printf "Checking for $PROGRAM ... " + ($PROGRAM --version) < /dev/null > /dev/null 2>&1 || { + printf "\n\n**Error**: You must have $PROGRAM installed." + printf "\nDownload the appropriate package for your distribution," + printf "\nor get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + printf "\n" + exit 1 + } + FOUND=`which $PROGRAM` + printf "$FOUND\n" +} + +# Function to check a program's version +# (there must be a better way, but I am not good at sed...) +check_program_version() +{ + PROGRAM=$1; MAJOR=$2; MINOR=$3 + printf "Checking that $PROGRAM version is at least $MAJOR.$MINOR ... " + VERSION=`$PROGRAM --version |head -n 1|sed 's/([^)]*)//g;s/^[a-zA-Z\.\ \ + \-]*//;s/ .*$//'` + MAJOR_FOUND=`echo $VERSION | cut -d. -f1` + MINOR_FOUND=`echo $VERSION | sed s/[-,a-z,A-Z].*// | cut -d. -f2` + [ -z "$MINOR_FOUND" ] && MINOR_FOUND=0 + + WRONG= + if [ -z "$MAJOR_FOUND" -lt "$MAJOR" ]; then + WRONG=1 + elif [ "$MAJOR_FOUND" -eq "$MAJOR" ]; then + if [ "$MINOR_FOUND" -lt "$MINOR" ]; then + WRONG=1 + fi + fi + if [ ! -z "$WRONG" ]; then + printf "\n\n**Error**: found version $MAJOR_FOUND.$MINOR_FOUND," + printf "\nwhich is too old. You should upgrade $PROGRAM." + printf "\nDownload the appropriate package for your distribution," + printf "\nor get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + printf "\n" + exit 1 + else + printf "OK, found $MAJOR_FOUND.$MINOR_FOUND\n" + fi +} + +# Dirty hack to run gettextize: problem is that it demands to +# press Return no matter what... This gets rid of that demand. +run_gettext() +{ + PROGRAM=gettextize + printf "Running $PROGRAM $GETTEXT_FLAGS ... " + sed 's:read .*< /dev/tty::' `which $PROGRAM` > my-gettextize + chmod +x my-gettextize + (printf "\n" | ./my-gettextize $GETTEXT_FLAGS > /dev/null 2>&1) || { + printf "\n\n**Error**: $PROGRAM failed.\n" + exit 1 + } + + # now restore the files modified by gettextize + (test -f configure.ac~) && mv -f configure.ac~ configure.ac + (test -f Makefile.am~) && mv -f Makefile.am~ Makefile.am + mv -f po/Makevars.template po/Makevars + rm my-gettextize + printf "OK\n" +} + +# Function to run a program +run_program() +{ + PROGRAM=$1 + shift + PROGRAM_FLAGS=$@ + printf "Running $PROGRAM $PROGRAM_FLAGS ... " + $PROGRAM $PROGRAM_FLAGS > /dev/null 2>&1 || { + printf "\n\n**Error**: $PROGRAM failed.\n" + exit 1 + } + printf "OK\n" +} + +# Main + +echo " --- $PKG_NAME autogen script ---\n" +check_directory_level +clean_old_files +check_program gettext +check_program_version gettext $GETTEXT_VERSION +check_program aclocal +check_program autoheader +check_program automake +check_program_version automake $AM_VERSION +check_program autoconf +check_program_version autoconf $AC_VERSION +run_gettext +run_program aclocal $ACLOCAL_FLAGS +run_program autoheader +run_program automake $AM_FLAGS +run_program autoconf $AC_FLAGS +clean_backup_files +printf "\nYou can now run the configure script to obtain $PKG_NAME Makefile.\n" diff --git a/configure.ac b/configure.ac new file mode 100755 index 0000000..bfaf4bb --- /dev/null +++ b/configure.ac @@ -0,0 +1,44 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. +# +# $calcurse: configure.ac,v 1.1 2006/07/31 21:00:02 culot Exp $ + +AC_PREREQ(2.59) +AC_INIT(calcurse, 1.4, frederic@culot.org) +AM_INIT_AUTOMAKE +AM_GNU_GETTEXT([external]) +AC_CONFIG_SRCDIR([src/calcurse.c]) +AC_CONFIG_HEADER([config.h]) + +# Checks for programs. +AC_PROG_CC + +# Checks for ncurses. +AC_CHECK_HEADERS([ncurses.h], [ + AC_CHECK_LIB(ncurses, initscr, [ + LIBS="$LIBS -lncurses" + AC_DEFINE(HAVE_LIBNCURSES, 1, [Define to 1 if you have the 'ncurses' library (-lncurses).]) + ], AC_MSG_ERROR(The ncurses library is required in order to build the program!)) +], AC_MSG_ERROR(The ncurses header is required in order to build the program!)) + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([stdlib.h string.h sys/time.h time.h stdio.h unistd.h \ +sys/types.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_STRUCT_TM +AC_HEADER_STDBOOL + +# Checks for library functions. +AC_FUNC_MALLOC +AC_FUNC_MKTIME +AC_FUNC_STRFTIME +AC_CHECK_FUNCS([floor mkdir strchr]) + +# Define LOCALEDIR +AC_DEFINE_UNQUOTED(LOCALEDIR, "${prefix}/share/locale", + [The directory in which locale data will be stored]) + +AC_OUTPUT(Makefile src/Makefile po/Makefile.in po/Makefile) diff --git a/doc/manual_de.html b/doc/manual_de.html new file mode 100755 index 0000000..1568096 --- /dev/null +++ b/doc/manual_de.html @@ -0,0 +1,728 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<!-- +/* + * $calcurse: manual_de.html,v 1.1 2006/07/31 21:00:05 culot Exp $ + * + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ +--> + +<html> +<head> +<title>CALCURSE documentation</title> +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> +</head> +<body bgcolor="white" text="black" link="blue" vlink="navy"> + +<h1><code>CALCURSE - textbasierender Terminkalender</code></h1> +<p> +<p><hr><p> + +<h1>Inhaltsverzeichnis</h1> +<ul> +<li><a href="#intro">Einleitung</a> +<li><a href="#overview">Überblick</a> +<ul> +<li><a href="#overview_history">Anlass</a> +<li><a href="#overview_features">Wichtige Eigenschaften</a> +</ul> +<li><a href="#install">Installation</a> +<ul> +<li><a href="#install_requirements">Vorraussetzungen</a> +<ul> +<li><a href="#install_requirements_ncurses"><code>ncurses</code> Bibliothek</a> +<li><a href="#install_requirements_gettext"><code>gettext</code> Bibliothek</a> +</ul> +<li><a href="#install_process">Installationsprozess</a> +</ul> +<li><a href="#basics"><code>calcurse</code> Grundlagen</a> +<ul> +<li><a href="#basics_invocation">Programmaufruf</a> +<ul> +<li><a href="#basics_invocation_commandline">Programmargumente</a> +<li><a href="#basics_invocation_variable">Umgebungsvariable für i18n</a> +</ul> +<li><a href="#basics_interface">Benutzer-Interface</a> +<ul> +<li><a href="#basics_interface_noninteractive">Nicht-interaktiver Modus</a> +<li><a href="#basics_interface_interactive">Interaktiver Modus</a> +</ul> +<li><a href="#basics_files"><code>calcurse</code> Dateien</a> +<li><a href="#basics_help">Onlinehilfe</a> +</ul> +<li><a href="#options">Optionen</a> +<ul> +<li><a href="#options_general">Allgemeine Optionen</a> +<li><a href="#options_colors">Einstellen der Terminalfarben</a> +<li><a href="#options_layout">Einstellen des Layouts</a> +</ul> +<li><a href="#known_bugs">Bekannte Fehler</a> +<li><a href="#bugs">Mitteilung von Fehlern und Anregungen</a> +<li><a href="#contribute">Wie kann ich einen Beitrag leisten?</a> +<ul> +<li><a href="#contribute_documentation">Übersetzung der Dokumentation</a> +<li><a href="#contribute_i18n"><code>calcurse</code> i18n</a> +<ul> +<li><a href="#contribute_i18n_overview">Überblick</a> +<li><a href="#contribute_i18n_translator">Aufgaben des Übersetzers</a> +<li><a href="#contribute_i18n_po-files">po-Dateien</a> +</ul> +</ul> +<li><a href="#links">Links</a> +<ul> +<li><a href="#links_homepage"><code>calcurse</code> Internetseite</a> +<li><a href="#links_list"><code>calcurse</code> Ankündigungsliste</a> +</ul> +<li><a href="#thanks">Danksagungen</a> +</ul> +<p><hr><p> + + +<a name="intro"></a><h1>Einleitung</a></h1> +<p> +<code>calcurse</code> ist ein textbasierender persönlicher Terminkalender, der +Ihnen bei der Organisation von Terminen und täglichen Aufgaben +hilft. Er beinhaltet einen Kalender sowie eine 'todo'-Liste, die Ihre +Termine ordnet. Das Benutzer-Interface ist einstellbar. Terminalfarben +und Layout lassen sich individuell anpassen. Alle Kommandos sind +dokumentiert und können zur Laufzeit jederzeit erfragt werden. + + +<a name="overview"></a><h1>Überblick</h1> +<a name="overview_history"></a><h2>Anlass</h2> +<p> +Nachdem ich mein Diplom in Astrophysik absolviert hatte, kam mir die +Idee dieses Programm zu schreiben. Alles begann etwas unorganisiert zu +werden. Ein Programm, dass mir bei meiner Terminplanung etwas hilft, +war wirklich vonnöten. ;)<br> +Ich mag Programme mit Textinterfaces, weil sie einfach, schnell, +portabel und effizient sind. Also dachte ich darüber nach ein +Programm mit textorientiertem Benutzer-Interface zu entwickeln. +Darüber hinaus wollte ich meine Kenntnisse in der Programmiersprache +<code>C</code> erweitern. Im Grundstudium kam ich mit <code>C</code> +erstmals in Kontakt. Ich denke es ist eine gute Idee ein solches +Projekt zu beginnen und dabei meine Kenntnisse in <code>C</code> zu +erweitern! Mein Diplom habe ich nun absolviert, <code>calcurse</code> +ist aber noch immer nicht fertig. Nach wie vor entwickle ich dieses +Programm weiter, in der Hoffnung, dass es für andere von Nutzen sein +wird. Also hier ist es...<br> +<br> +Doch warum nenne ich es 'calcurse'? Nun, es ist einfach +zusammengesetzt aus den Wörtern 'CALendar' und 'nCurses', dem Namen +der Bibliothek die für das Benutzer-Interface verwendet wird. + + +<a name="overview_features"></a><h2>Wichtige Eigenschaften</h2> +<p> +<code>Calcurse</code> ist portabel und setzt sich zum Ziel klein, +schnell und sicher zu sein. Es ist auf einer Konsole oder einem +Terminal zu verwenden, entweder lokal oder auf einem entfernten System +mithilfe einer ssh-Verbindung (oder ähnlichem).<br> +<code>Calcurse</code> kann in zwei unterschiedlichen Modi gestartet +werden: ein interaktiver und nicht-interaktiver Modus. Der erste Modus +erzeugt Dank des textbasierenden Interfaces die Ansicht eines eigenen +persönlichen Terminkalenders. Mit dem zweiten Modus ist es möglich +sich ein Erinnerungstool (Reminder) zu erstellen, wenn +<code>calcurse</code> mit den entsprechenden Argumenten in 'cron tab' +oder einem 'init script' eingebunden wird.<br> +Darüber hinaus ist <code>calcurse</code> für Benutzer erstellt worden, +mit der Absicht so benutzerfreundlich wie möglich zu sein. Das +bedeutet, dass eine komplette Onlinehilfe im Programm zu Verfügung +steht, sowie alle mögliche Aktionen zu jeder Zeit in einer Statuszeile +ersichtlich sind. Das Benutzer-Interface ist ebenfalls +einstellbar. Ebenso kann man verschiedene Textfarben und Layouts +wählen. + + +<a name="install"></a><h1>Installation</h1> +<a name="install_requirements"></a><h2>Voraussetzungen</h2> +<a name="install_requirements_ncurses"></a><h3><code>ncurses</code> Bibliothek</h3> +<p> +<code>Calcurse</code> benötigt einen C-Compiler wie etwa +<code>cc</code> oder <code>gcc</code>. Ferner wird die +ncurses-Bibliothek benötigt, dass aber auf den meisten Unix-Systemen +verfügbar sein sollte. Falls nicht, kann es von folgender URL herunter +laden:<br> +<pre> + http://ftp.gnu.org/pub/gnu/ncurses/ +</pre> + +<a name="install_requirements_gettext"></a><h3><code>gettext</code> Bibliothek</h3> +<p> + + <code>calcurse</code> unterstützt die Internationalisierung + (künftig <em>i18n</em>) durch <code>gettext</code>. + Das bedeutet, dass <code>calcurse</code> mehrsprachige Mitteilungen + erzeugen kann, wenn es mit der entsprechenden Sprachunterstützung + kompiliert wurde (z.B. <em>NLS</em>). + Dennoch, <em>NLS</em> ist optional und wenn keine mehrsprachigen Mitteilungen + gewünscht sind, kann diese Eigenschaft abgestellt werden. Einfach die Option <code>--disable-nls</code> dem <code>configure</code> Skript übergeben + (siehe Abschnitt <ahref="#install_process">Installationsprozess</a>). <br> + Um zu überprüfen, ob <code>gettext</code> auf dem System installiert ist, + kann man nach der <code>libintl.h</code> Datei suchen: + <pre> + locate libintl.h + </pre> + Wenn diese Datei nicht gefunden wird, kann <code>gettext</code> von folgender URL herunter geladen werden:<br> + <pre> + http://ftp.gnu.org/pub/gnu/gettext/ + </pre> + <u>Beachte:</u> Auch wenn <code>libintl.h</code> auf dem System + gefunden wurde, kann es erforderlich sein den Pfad dieser Datei während des <ahref="#install_process"> Installationsprozesses</a> anzugeben. Die entsprechende + Option für das <code>configure</code> Skript lautet dann <code>--with-libintl-prefix</code>. + Das <code>configure</code> Skript wird natürlich vorzeitig abbrechen, wenn die dazugehörige Bibliothek nicht gefunden wurde. + + +<a name="install_process"></a><h2>Installationsprozess</h2> +<p> +Als erstes müssen die Dateien entpackt werden: +<pre> + tar zxvf calcurse-1.4.tar.gz +</pre> +Wenn Sie die Voraussetzungen erfüllen und das Archiv entpackt +vorliegen, sind nur noch die drei üblichen Schritte erforderlich: +<OL> + <li><code>./configure</code> + <li><code>make</code> + <li><code>make install</code> (mit Root-Rechten) +</OL> +Benutzen Sie <code>./configure --help</code> um eine Liste mit den +verfügbaren Optionen zu erhalten. + + +<a name="basics"></a><h1><code>calcurse</code> Grundlagen</h1> +<a name="basics_invocation"></a><h2>Programmaufruf</h2> +<a name="basics_invocation_commandline"></a><h3>Programmargumente</h3> +<p> +<code>Calcurse</code> kann mit folgenden Optionen aufgerufen werden: + +<dl compact> +<dt><code>-a</code> +<dd>Gibt die Termine eines anzugebenen Tags aus.<br> +<u>Beachte:</u> Die Kalender-Datei, von der die Termine gelesen +werden sollen, kann mit mithilfe der -c Option angegeben werden.<br> +<br> +<dt><code>-c</code> +<dd> +Gibt die zu lesende Kalender-Datei an.<br> +Der Standardkalender ist <code>~/.calcurse/apts</code> (beachte auch +Abschnitt: <a href="#basics_files"><code>calcurse</code> Dateien</a>).<br> +<br> +<dt><code>-d</code> +<dd> +Gibt die Termine eines angegebenen Datums aus oder gibt alle Termine +der anzugebenen nachfolgenden Tage aus. Somit sind zwei mögliche +Formate möglich: +<ul> +<li>Datum: 'MM/TT/JJJJ' (Monat, Tag, Jahr). +<li>Anzahl der Tage: 'n'. +</ul> +Im ersten Fall wird eine Liste mit allen Terminen des anzugebenen +Datums ausgegeben. Der zweite Fall listet alle folgenden Termine auf, +die in den nächsten 'n' Tagen zu erledigen sind.<br> +Beispiel: die Eingabe <code>calcurse -d 3</code> gibt alle Termine von +heute, morgen und übermorgen aus.<br> +<br> +<dt><code>-h</code> +<dd> +Gibt eine Hilfe zu den Unterstützten Optionen aus.<br> +<br> +<dt><code>-t</code> +<dd> +Gibt die 'todo' Liste aus.<br> +<br> +<dt><code>-v</code> +<dd> +Gibt die aktuelle Version von Calcurse aus. +</dl> + + +<a name="basics_invocation_variable"></a><h3>Umgebungsvariable für i18n</h3> +<p> + + <code>calcurse</code> kann mit einer Unterstützung für die Muttersprache + kompiliert werden (siehe <a + href="#install_requirements_gettext"><code>gettext</code> + Bibliothek</a>). Wenn Meldungen in der Muttersprache gewünscht sind, + sollte zunacht geprüft werden, ob die <code>po/LINGUAS</code> Datei verfügbar ist. + Diese Datei zeigt alle verfügbaren Sprachen durch + zweibuchstabige Kürzel an (z. B., <em>fr</em> + steht für französisch). Wenn Ihre Sprache nicht aufgeführt ist, wäre es + natürlich grossartig, wenn Sie sich an der Übersetzung von <code>calcurse</code> + in andere Sprachen beteiligen könnten (siehe Abschnitt <a href="#contribute">Wie kann + ich einen Beitrag leisten?</a>).<br> + Wenn Ihre Sprache verfügbar ist, starten Sie + <code>calcurse</code> mit dem folgenden Aufruf: + <pre> + LC_ALL=fr_FR calcurse + </pre> + wobei <em>fr_FR</em> der Name der gewünschten Spracheausgabe ist und durch + das Kürzel Ihrer Sprache ersetzt werden kann. + + +<a name="basics_interface"></a><h2>Benutzer-Interface</h2> +<a name="basics_interface_noninteractive"></a><h3>Nicht interaktiver Modus</h3> +<p> +Wird <code>calcurse</code> mit den Optionen:<br> +<code>-a</code>, <code>-d</code>, <code>-t</code>, +<code>-h</code>, <code>-v</code><br> +gestartet, wird das Programm im nicht-interaktiven Modus +ausgeführt. Das bedeutet, dass die gewünschten Informationen +ausgegeben werden und das Programm anschließend sofort wieder beendet +wird. So ist es möglich mit dem Aufruf <code>calcurse -ta</code> eine +Liste aller Termine eines bestimmten Tages zu erhalten. + + +<a name="basics_interface_interactive"></a><h3>Interaktiver Modus</h3> +<p> +Ohne Angabe einer Option oder nur die Option -c startet +<code>calcurse</code> im interaktiven Modus. In diesem Modus erhält +man ein Interface mit drei unterschiedlichen Panels, die mit der +'TAB'-Taste angesteuert werden können, sowie eine Status-Zeile (siehe +unten). +<pre> + + Termin-Panel---. .---Kalender-Panel + | | + v v + +------------------------------------++----------------------------+ + | Termine || Kalender | + |------------------------------------||----------------------------| + | 6. April 2006 || April 2006 | + | ||Mon Die Mit Don Frei Sam Son| + | || 1 2 | + | || 3 4 5 6 7 8 9 | + | || 10 11 12 13 14 15 16 | + | || 17 18 19 20 21 22 23 | + | || 24 25 26 27 28 29 30 | + | || | + | |+----------------------------+ + | |+----------------------------+ + | || Zu erledigen | todo- + | ||----------------------------| Panel + | || | | + | || | | + | || |<--. + | || | + | || | + | || | + +------------------------------------++----------------------------+ + | ? Hilfe R Neu zeichnen H/L -/+1 Tag G Gehe zu C Einstellung | + | Q Verlassen S Speichern J/K -/+1 Woche Tab ändere Ansicht |<-. + +------------------------------------------------------------------+ | + | + Statuszeile + +</pre> + +Das Kalender-Panel hebt den gewünschten Tag farblich hervor, während +das Termin-Panel die Liste mit Terminen des angesteuerten Tags +anzeigt. Das todo-Panel dagegen zeigt eine Liste mit den zu +erledigenden Aufgaben, die keinem bestimmten Tage zugeordnet sind. +Die letzten beiden Zeilen des Interfaces zeigen die Status-Zeile, die +über die möglichen Befehle und ihre entsprechenden Tasten informiert. + + +<a name="basics_files"></a><h2><code>calcurse</code> Dateien</h2> +<p> + +Die folgende Verzeichnisstruktur wird im $HOME-Verzeichnis angelegt, +wenn <code>calcurse</code> das erste mal gestartet wird: +<pre> + $HOME/.calcurse/ + |___conf + |___apts + |___todo +</pre> + + +Die <em>conf</em> Datei enthält die Informationen zur Benutzerkonfiguration.<br> +Die <em>apts</em> Datei enthält alle Termine.<br> +Die <em>todo</em> Datei enthält die todo-Liste. + + +<a name="basics_help"></a><h2>Online Hilfe</h2> +<p> +Das integrierte Hilfe-System kann jederzeit mit '?' aufgerufen +werden. Informationen über bestimmte Befehle können mit der +entsprechenden Taste des Befehls aufgerufen werden. + + +<a name="options"></a><h1>Optionen</h1> +<p> +Alle <code>calcurse</code> Parameter sind im Konfigurationsmenü +einstellbar. Drücke Sie dazu die 'C'-Taste. Ein weiteres Untermenü +erscheint mit drei weiteren Auswahlpunkten: Ein erneutes Betätigen der +'C'-Taste führt zur Farbeinstellung, die 'L'-Taste erlaubt die Auswahl +eines anderen Layouts, das heisst die Anordnung der drei Panel kann +hier geändert werden. Mit der 'G'-Taste gelangt man zur Auswahl +allgemeiner Optionen. + + +<a name="options_general"></a><h1>Allgemeine Optionen</h1> +<p> +Diese Optionen steuert das allgemeine Verhalten von +<code>calcurse</code> wie im folgenden beschrieben wird: +<ul> +<li><code>auto_save</code> (Voreinstellung: <em>yes</em>)<br> +Diese Option erlaubt es die Benutzerdaten automatisch beim Verlassen +zu speichern. Warnung: Es werden keine Daten gespeichert, wenn die +auto_save Option auf <em>no</em> gesetzt wird. Das bedeutet, dass der Benutzer +'s' betätigen muss, wenn Eingaben gespeichert werden sollen.<br> +<br> +<li><code>confirm_quit</code> (Vorenstellung: <em>yes</em>)<br> +Wenn diese Option auf <em>yes</em> eingestellt ist, wird nachgefragt, ob das +Programm wirklich beenden werden soll. Ist die Option auf <em>no</em> gestellt, +wird das Programm durch Eingabe von 'Q' ohne Nachfrage sofort beendet.<br> +<br> +<li><code>confirm_delete</code> (Voreinstellung: <em>yes</em>)<br> +Ist diese Option auf <em>yes</em> eingestellt, fragt das Programm nach, ob ein +Eintrag wirklich gelöscht werden soll (entweder ein todo-Eintrag oder +ein Termin). Ist confirm_delete auf <em>no</em>, wird durch Betätigung der +'D'-Taste ohne Nachfrage gelöscht.<br> +<br> +<li><code>skip_system_dialogs</code> (Voreinstellung: <em>no</em>)<br> +Durch setzen auf <em>yes</em> werden die Dialoge beim Speichern und +Laden umgangen. Nützlich, wenn es mal schnell gehen muss.<br> +<br> +<li><code>skip_progress_bar</code> (Voreinstellung: <em>no</em>)<br> +Wenn auf <em>yes</em> gesetzt ist, erscheint der Zustandsbalken nicht +mehr, der gewöhnlich angezeigt wird, wenn Daten gespeichert +werden. Ist diese Option auf <em>yes</em> eingestellt, erscheint ein +Zustandsbalken zusammen mit dem Namen der zu speichernden Datei (siehe +Abschnitt <a href="#basics_files">Calcurse Dateien</a>).<br> +<br> +<li><code>week_begins_on_monday</code> (Voreinstellung: <em>yes</em>)<br> +Es ist möglich zwischen Montag und Sonntag als ersten Wochentag zu wählen. +Wird die Option <em>week_begins_on_monday</em> auf yes gesetzt, erscheint Montag als +erster Wochentag. Ist diese Option auf no gesetzt, beginnt die Woche mit Sonntag. +</ul> + + +<a name="options_colors"></a><h2>Textfarben einstellen</h2> +<p> +Die verwendeten Textfarben können nach eigenen Vorlieben eingestellt +werden. Durch Betätigung der entsprechenden Taste kann die gewünschte +Farbkombination ausgewählt werden. Die gewählte Farbkombination werden +dem Rahmen, dem Titel und der Status-Zeilen zugeordnet. + + Eine schwarz/weiss Kombination ist ebenfalls verfügbar, um Terminals ohne Farben zu unterstützen.<br> + <u>Beachte:</u> + <ul> + <li> In Abhängigkeit des verwendeten Terminals und dem zugeordneten Wert der Umgebungsvariable <code>$TERM</code> werden Farben unterstützt oder nicht. + Eine Fehlermeldung erscheint, wenn versucht wird die Farben zu ändern obwohl + das Terminal keine Farben unterstützt.<br> + <br> + <li> Wenn sie sicher sind, dass ihr Terminal Farben darstellen kann aber keine Farben + in <code>calcurse</code> erscheinen, versuchen sie die <code>$TERM</code> Variable + auf einen anderen Wert zu setzen (wie etwa <em>xterm-xfree86</em>). + </ul> + + +<a name="options_layout"></a><h2>Layout einstellen</h2> +<p> +Das Layout bezieht sich auf die Positionen der einzelnen Panel. Das +Standard-Layout zeigt das Kalender-Panel in der oberen linken Ecke des +Terminals, das todo-Panel befindet sich in der unteren rechten Ecke +und das Termin-Panel auf der linken Seite des Terminals (siehe die +Zeichnung im Abschnitt <a +href="#basics_interface_interactive">Interaktiver Modus</a>, die das +Beispiel des Standard-Layouts zeigt).<br> +Durch Auswahl eines anderen Layouts kann der Benutzer das +Erscheinungsbild von <code>calcurse</code> nach seinen Wünschen +anpassen. + + +<a name="known_bugs"></a><h1>Bekannte Fehler</h1> +<p> + + Es kommt vor, dass Wörter bei Verwendung der schwarz/weiss Farbkombination + falsch hervorgehoben werden, wenn die <code>$TERM</code> + Variable auf <em>xterm-color</em> gesetzt ist. + Um diesen Fehler zu umgehen, sollte nach Aussage von + Thomas E. Dickey (zuständig für das <code>xterm</code>), + <em>xterm-xfree86</em> an Stelle für <em>xterm-color</em> als + <code>$TERM</code> Variable gesetzt werden:<br> + <blockquote> + "The xterm-color value for $TERM is a bad choice for XFree86 xterm + because it is commonly used for a terminfo entry which happens to + not support bce. Use the xterm-xfree86 entry which is distributed + with XFree86 xterm (or the similar one distributed with ncurses)." + </blockquote> + + + +<a name="bugs"></a><h1>Mitteilung von Fehlern und Anregungen</h1> +<p> +Bitte mailt Fehler oder auch Anregungen an: +<pre> + calcurse@culot.org +</pre> +oder an den Autor: +<pre> + frederic@culot.org +</pre> + + +<a name="contribute"></a><h1>Wie kann ich einen Beitrag leisten?</h1> +<p> +Wenn Sie gerne dieses Projekt unterstützen möchten, können Sie mir +zuerst eine kurze Rückmeldung geben. Was finden Sie gut an diesem +Programm oder was könnte besser sein. Gibt es vielleicht Programmeigenschaften, +die Sie vermissen? Teilen Sie es mir mit!<br> + + Von nun an ist es auch möglich sich an der Übersetzung der Prgrammmitteilungen + und der Dokumentation von <code>calcurse</code> zu beteiligen. <br> + <br> + <u>Beachte:</u> Jegliche Unterstützung <code>calcurse</code> + in andere Sprachen zu übersetzen ist sehr willkommen. Doch bevor Sie beginnen, sollten + Sie eine Mail an <code>calcurse-i18n@culot.org</code> senden, um zu erfahren, ob jemand + die Übersetzung in Ihrer Sprache schon begonnen hat. + + + +<a name="contribute_documentation"></a><h2>Übersetzung der Dokumentation</h2> +<p> + + Das <em>doc/</em> Verzeichnis des Source-Packets enthält bereits + übesetzte Versionen der <code>calcurse</code> Anleitung. + Wenn eine Übersetzung in Ihrer Sprache noch nicht vorhanden ist, + wäre es grossartig, wenn Sie eine solche erstellen könnten.<br> + Kopieren Sie dazu eine der vorhandenen Version mit dem Dateinamen + <code>manual_XX.html</code>, wobei <em>XX</em> + das entsprechende Kürzel Ihrer Sprache ist. Anschliessend übersetzen Sie diese + Datei und senden Sie dann an den Author (siehe <a href="#bugs">Mitteilung von Fehlern und Anregungen</a>), so dass Ihre Übersetzung für die nächste Ausgabe von <code>calcurse</code> ins Packet integriert werden kann. + +<a name="contribute_i18n"></a><h2><code>calcurse</code> i18n</h2> +<p> + Wie bereits erwähnt, verwendet <code>calcurse</code> die <code>gettext</code> Utilities um mehrsprachige Programmmitteilungen zu erzeugen. + Dieser Abschnitt informiert darüber, wie Programmmitteilungen in Ihrer Muttersprache + übersetzt werden. Dieses howto zur Übersetzung von <code>calcurse</code> mit <code>gettext</code> ist natürlich nur ein Einstieg und wohl zu kurz. Um umfassendere Informationen + zu erhalten und sich die weite Welt der Sprachübersetzung für Software zu erschliessen, + sollten Sie die Seite der <code>GNU gettext</code> Anleitung besuchen: + <pre> + http://www.gnu.org/software/gettext/manual/ + </pre> + Eigentlich sind drei verschiedene Entwickler an der Übersetzung beteiligt: + Programmierer, Sprachkoordinator und Übersetzer. + Nach einem kurzen Überblick, wie so etwas funktioniert, werden anschliessend die + Aufgaben des Übersetzers beschrieben. + + +<a name="contribute_i18n_overview"></a><h3>Überblick</h3> +<p> +Um Text in der Muttersprache des Benutzers erscheinen zu lassen, sind zwei Schritte nötig: + <em>Internationalisierung</em> + (i18n) und <em>Lokalisierung</em> (l10n). + Bei der i18n geht es darum ein Buch für mehrere Sprachen vorzubereiten. + Das wird vom Programmierer durchgeführt, der die zu übersetzenden Texte markiert + und es somit ermöglicht, dass zur Laufzeit des Programms der Text übersetzt erscheint. + Bei der l10n geht es darum, dem i18n markierten Pragramm <code>calcurse</code> die entsprechende Übersetzung des Benutzers zukommen zu lassen. Die zuvor vom Programmierer + markierten Texte werden durch das richtige Setzen der Umgebung für <code>calcurse</code> übersetzt.<br> + <br> + + Also, die zu übersetzenden Texte werden zunächst vom Programmierer in der <code>C</code> Source-Datei markiert und in einer Template + Datei (<em>calcurse.pot</em> - die <em>pot</em> Dateierweiterung bedeutet + <em>portable object template</em>) gesammelt. + Der Inhalt dieser Template Datei wird dann mit den Dateien, die die Übersetzungen enthalten + (<em>fr.po</em> für französisch, hier steht <em>po</em> für <em>portable object</em>, + dieses Format kann man lesen und verändern), + zusammengeführt. Ein Übersetzer kann diese Datei dazu öffnen, die enthaltenen Texte übersetzen + und sie dann an den Programmierer zurück senden. + Wenn das Programm kompiliert wird, erzeugt der Kompiler (aus Gründen der Effizienz) + eine binäre Version dieser Datei (<em>fr.mo</em> - <em>mo</em> steht für <em>machine + object</em>, dieses Format kann nur von Programmen gelesen werden), die dann installiert wird. <code>calcurse</code> nutzt diese Datei zur Laufzeit, um die + Texte in Abhängigkeit zur lokalen Einstellung des Benutzers zu übersetzen. + + +<a name="contribute_i18n_translator"></a><h3>Aufgaben des Übersetzers</h3> +<p> + Wenn Sie mit der Übersetzung in eine neue Sprache beginnen möchte sind hier die Schritte dazu: + <ul> + <li>Finden Sie zunächst heraus, wie die Kürzel der Sprache definiert sind. + Beispielsweise sind die Kürzel für die französische 'fr_FR', oder einfacher + 'fr'. Das ist der Wert, den der Benutzer als Umgebungsvariable <code>LC_ALL</code> für die Programme setzen muss (siehe <a href="#basics_invocation_variable">Umgebungsvariable für i18n</a>).<br> + <br> + <li>Wechseln Sie dann ins <em>po/</em> Verzeichnis und erzeugen Sie eine neue po-Datei aus der Template Datei mit folgendem Aufruf: + <pre> + 'msginit -i calcurse.pot -o fr.po -l fr --no-translator' + </pre> + Wenn <code>msginit</code> nicht auf Ihrem System installiert ist, kopieren Sie einfach die Datei <em>calcurse.pot</em> nach <em>fr.po</em> und änderen Sie den Dateikopf manuel.<br> + Wenn die Datei <em>fr.po</em> erstellt ist, kann mit der eigentlichen Übersetzung begonnen werden. + </ul> + + +<a name="contribute_i18n_po-files"></a><h3>po-Dateien</h3> +<p> + Das Format der po-Dateien ist relativ einfach. po-Dateien bestehen aus fünf Teilen: + <ol> + <li><em>location Zeilen:</em> geben an, wo sich der Text befindet (Name der Datei und Zeilennummer). + <li><em>msgid Zeilen:</em> der zu übersetzende Text. + <li><em>msgstr Zeilen:</em> der übersetzte Text. + <li><em>Zeilen, die mit '#' beginnen:</em> Kommentare (einige mit spezieller Bedeutung, + wie wir weiter unten noch sehen werden). + </ol> + Übersetzen Sie die <em>msgid</em> Zeilen und tragen Sie den übersetzten Text in die mit + <em>msgstr</em> gekennzeichneten Zeilen ein. + <p> + <u>Einige Anmerkungen:</u> + <ul> + <li><em>Fuzzy Texte</em><br> + Einige Texte sind mit <code>"#, fuzzy"</code> + kommentiert. <code>calcurse</code> nutzt derart markierte Texte nicht. + Ein Text, der als fuzzy markiert ist, deutet entweder darauf hin, dass + der Text schon übersetzt wurde, aber die Stelle im Programmcode verändert wurde, oder + aber es handelt sich um einen neuen Text, für welchen <code>gettext</code> eine sog. 'wild guess' vornimmt, also selbst eine Übersetzung versucht. + Das beduetet, die Übersetzung sollte noch einmal überarbeitet werden. + Manchmal wurde der Originaltext verändert, weil ein Rechtschreibfehler korrigiert wurde. In einem solchen Fall muss nichts verändert werden. + Manchmal ist die Übersetzung aber nicht optimal gelungen und muss dann verändert werden. + Wenn die Übersetzung fertig ist, entferne die <code>"#, fuzzy"</code> Zeilen. Die Übersetzung + wird wieder in <code>calcurse</code> verwendet.<br> + <br> + <li><em>c-Format Texte and besondere Sequenzen</em><br> + Einige Texte haben folgende Kommentare: <code>"#, + c-format"</code>. + Dieser Kommentar bedeutet, dass Teile dieses Textes eine besondere Bedeutung haben + und dieser Text unverändert bleiben werden sollte. + Beispielsweise die %-Sequenzen, wie <code>"%s"</code>. + Diese bedeuten, dass <code>calcurse</code> dort Text einfügen wird. + Es ist also wichtig, diese nicht zu verändern. + Ebenso kommen \-Sequenzen vor, wie <code>\n</code> oder + <code>\t</code>. Auch nicht verändern. + Das erste stellt das Zeilenende dar, das zweite eine Tabulation.<br> + <br> + <li><em>Übersetzungen können in Blöcke geschrieben werden</em><br> + Wenn Zeilen zu lang werden, können sie auf mehrere verteilt werden: + <pre> + msgid "" + "some very long line" + "another line" + </pre> + <li><em>po-Dateikopf</em><br> + Ganz zu Anfang einer po-Datei befindet sich der Kopf. Dort stehen einige Informationen. + Die wichtigste Information dort ist der Zeichensatz. Er sollte diesem ähnlich sein + <pre> + "Content-Type: text/plain; charset=utf-8\n" + </pre> + + Auch das Übersetzer-Feld sollte ausgefüllt sein, damit andere potentielle Mitstreiter, die sich an der Übersetzung beteiligen wollen, Kontakt mit Ihnen aufnehmen können. Ebenso können von anderen entdeckte Fehler an den Übersetzer gemeldet werden. Man kann entweder seinen Namen oder seine Mail dort angeben: + <pre> + "Last-Translator: Frederic Culot <frederic@culot.org>\n" + </pre> + <li><em>Kommentare</em><br> + Das Hinzufügen von Kommentaren (Zeilen beginnen mit dem '#' Zeichen) ist eine gute Möglichkeit + Probleme und Übersetzungsschwierigkeiten besser zu lösen. Die Übersetzungsarbeit wird besser + lesbar.<br> + <br> + <li><em>Längen der Texte</em><br> + <code>calcurse</code> + ist ein curses/Konsolen Programm und kann somit von der Grösse des Terminals (Anzahl der + Zeilen) abhängen. Dies sollte bei der Übersetzung berücksichtigt werden. + Häufig müssen Texte in eine Zeile passen (Standardlänge ist 80 Zeichen). + Übersetzen Sie nicht blind, versuchen Sie herauszufinden, wo der Text erscheint um die Übersetzung richtig anzupassen. + <br> + <br> + <li><em>Ein paar nützliche Programme</em><br> + Das po-Dateiformat ist sehr einfach und kann mit einem Editor geändert werden. + Es gibt aber auch einige spezielle Tools die das Erstellen und Änder der po-Dateien + vereinfachen: + <ul> + <li><code>poEdit</code> (<a + href="http://www.poedit.org/" target="_blank"> + http://www.poedit.org/</a>) + <li><code>KBabel</code> (<a + href="http://i18n.kde.org/tools/kbabel/" target="_blank"> + http://i18n.kde.org/tools/kbabel/</a>) + <li><code>GTranslator</code> (<a + href="http://gtranslator.sourceforge.net/" target="_blank"> + http://gtranslator.sourceforge.net/</a>) + <li><code>Emacs</code> po mode + <li><code>Vim</code> po mode + </ul> + <br> + <li><em>Zu Schluss noch</em><br> + Ich hoffe es wird Ihnen Freude bereiten, wenn Sie sich an diesem Projekt und + seiner Internationalisierung beteiligen :). Wenn noch Fragen offen sind, + scheuen Sie sich nicht mir eine Mail zu schreiben, <em>frederic@culot.org</em>. + </ul> + + +<a name="links"></a><h1>Links</h1> +<p> +Dieser Abschnitt enthält Links und Angaben, die Sie interessieren +könnten. + + +<a name="links_homepage"></a><h2><code>calcurse</code> Internetseite</h2> +<p> +Die Internetseite des Projekts <code>calcurse</code> lautet: +<pre> + http://culot.org/calcurse +</pre> + + +<a name="links_list"></a><h2><code>calcurse</code> Ankündigungsliste</h2> +<p> +Wenn Interesse an Calcurse besteht und Sie gerne über Neuerscheinungen +informiert werden möchten, können Sie gerne auf eine Liste gesetzt +werden, die Sie per Mail über die neusten Eigenschaften von +<code>calcurse</code> informiert, sobald ein neuer Release +erscheint.<br> +Um sich in die Liste eintragen zu lassen, senden Sie eine Mail an +<ode>calcurse-announce@culot.org</code> mit "subscribe" im Betreff. + + +<a name="thanks"></a><h1>Danksagungen</h1> +<p> +Folgenden Leuten möchte ich gerne für Ihre Unterstützung danken, ohne +die dieses Projekt nicht möglich gewesen wäre. Hier ist die Liste +derjenigen, denen ich Danke sagen möchte: +<ul> +<li>Alex für die Patches, Hilfen und Erläuterungen zur <code>C</code> Programmierung. +<li>Gwen fürs Testen und Anregungen, wie <code>calcurse</code> verbessert werden kann. +<li>Kevin und Ryan für das Binary-Packet auf Debian. +<li>Steffen für das Binary-Packet auf Archlinux +<li>Alexandre für das Binary-Packet auf Mac OsX. +<li>Joel für sein Kalender-Skript das mich zum Calcurse-Layout inspiriert hat. +<li>Michael Schulz für die deutsche übersetzung der Dokumentation +<li>Leute die Programme geschrieben haben, die ich mag und mich inspiriert haben, insbesondere : +<ul> +<li><code>vim</code> für die Befehlssteuerung +<li><code>orpheus</code> und <code>abook</code> für die Dokumentation +<li><code>pine</code> und <code>aptitude</code> für das Text-Benutzer-Interface +</ul> +</ul> +Und zuletzt, vielen vielen Dank an alle <code>calcurse</code> +Benutzer, die mir Ihr Feedback mitgeteilt haben. + + +<hr> +<small><em> +Copyright (c) 2004-2006 Frédéric Culot<br> +German translation by Michael Schulz <code><bloodshower.at.web.dot.de></code><br> +Calcurse version 1.4 - Last change: May 07, 2006 +<em></small> + + +</body> +</html> diff --git a/doc/manual_en.html b/doc/manual_en.html new file mode 100755 index 0000000..3b1420b --- /dev/null +++ b/doc/manual_en.html @@ -0,0 +1,783 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<!-- +/* + * $calcurse: manual_en.html,v 1.1 2006/07/31 21:00:04 culot Exp $ + * + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ +--> + +<html> +<head> +<title>CALCURSE documentation</title> +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> +</head> +<body bgcolor="white" text="black" link="blue" vlink="navy"> + +<h1><code>CALCURSE - text-based organizer</code></h1> +<p> +<p><hr><p> + +<h1>Table of Contents</h1> +<ul> +<li><a href="#intro">Introduction</a> +<li><a href="#overview">Overview</a> +<ul> +<li><a href="#overview_history">Creation history</a> +<li><a href="#overview_features">Important features</a> +</ul> +<li><a href="#install">Installation</a> +<ul> +<li><a href="#install_requirements">Requirements</a> +<ul> +<li><a href="#install_requirements_ncurses"><code>ncurses</code> library</a> +<li><a href="#install_requirements_gettext"><code>gettext</code> library</a> +</ul> +<li><a href="#install_process">Install process</a> +</ul> +<li><a href="#basics"><code>calcurse</code> basics</a> +<ul> +<li><a href="#basics_invocation">Invocation</a> +<ul> +<li><a href="#basics_invocation_commandline">Command line arguments</a> +<li><a href="#basics_invocation_variable">Environment variable for i18n</a> +</ul> +<li><a href="#basics_interface">User interface</a> +<ul> +<li><a href="#basics_interface_noninteractive">Non-interactive mode</a> +<li><a href="#basics_interface_interactive">Interactive mode</a> +</ul> +<li><a href="#basics_files"><code>calcurse</code> files</a> +<li><a href="#basics_help">Online help</a> +</ul> +<li><a href="#options">Options</a> +<ul> +<li><a href="#options_general">General options</a> +<li><a href="#options_colors">Color themes</a> +<li><a href="#options_layout">Layout configuration</a> +</ul> +<li><a href="#known_bugs">Known bugs</a> +<li><a href="#bugs">Reporting bugs and feedback</a> +<li><a href="#contribute">How to contribute?</a> +<ul> +<li><a href="#contribute_documentation">Translating documentation</a> +<li><a href="#contribute_i18n"><code>calcurse</code> i18n</a> +<ul> +<li><a href="#contribute_i18n_overview">Overview</a> +<li><a href="#contribute_i18n_translator">Translator tasks</a> +<li><a href="#contribute_i18n_po-files">po-files</a> +</ul> +</ul> +<li><a href="#links">Links</a> +<ul> +<li><a href="#links_homepage"><code>calcurse</code> homepage</a> +<li><a href="#links_list"><code>calcurse</code> announce list</a> +</ul> +<li><a href="#thanks">Thanks</a> +</ul> +<p><hr><p> + + +<a name="intro"></a><h1>Introduction</a></h1> +<p> + <code>calcurse</code> is a text-based personal organizer + which helps keeping track of events and everyday tasks. + It contains a calendar, a 'todo' list, and puts your + appointments in order. The user interface is configurable, + and one can choose between different color schemes and + layouts. All of the commands are documented within an + online help system. + + +<a name="overview"></a><h1>Overview</h1> +<a name="overview_history"></a><h2>Creation history</h2> +<p> + I started thinking about this project when I was finishing + my Ph.D. in Astrophysics... It started to be a little hard + to organize myself, and I really needed a good tool to help + me in that difficult task ;)<br> + I like programs which use Text User Interfaces, because they + are simple, fast, portable and efficient, so I thought about + working on coding a simple calendar using such an interface. + Moreover, I wanted to go on learning the <code>C</code> + language, which I only used for a while during my undergraduate + studies. So I thought that would be the good project to start + in order to get organized and to learn about a few + <code>C</code> things ! + Unfortunately, I finished my Ph.D. before finishing + <code>calcurse</code>, + but anyway, I still wanted to work on it, hoping it would + be helpful to other people. So here it is...<br> + <br> + But why 'calcurse' anyway ? Well, it is simply the + concatenation of 'CALendar' and 'nCURSEs', the name of the + library used to build the user interface. + + +<a name="overview_features"></a><h2>Important features</h2> +<p> + <code>Calcurse</code> is multi-platform and intended to be + lightweight, fast and reliable. It is to be used inside a + console or terminal, locally or on a distant machine within + an ssh (or similar) connection. <br> + <code>Calcurse</code> can be run in two different modes : + interactive or non-interactive mode. The first mode allows + oneself to view its own personal organizer almost everywhere, + thanks to the text-based interface. + The second mode permits to easily build reminders just by adding + <code>calcurse</code> with appropriate command line arguments + inside a cron tab or within a shell init script.<br> + Moreover, <code>calcurse</code> was created with the end-user + in mind, and tends to be as friendly as possible. This means + a complete on-line help system, together with having all of + the possible actions displayed at any time inside a status bar. + The user interface is also configurable, and one can choose + between several color and layout combinations. + + +<a name="install"></a><h1>Installation</h1> +<a name="install_requirements"></a><h2>Requirements</h2> +<a name="install_requirements_ncurses"></a><h3><code>ncurses</code> library</h3> +<p> + <code>Calcurse</code> requires only a <code>C</code> compiler, such as + <code>cc</code> or <code>gcc</code>, and the <code>ncurses</code> + library. + It would be very surprising not to have a valid <code>ncurses</code> + library already installed on your computer, but if not, you can + find it at the following url :<br> + <pre> + http://ftp.gnu.org/pub/gnu/ncurses/ + </pre> + +<a name="install_requirements_gettext"></a><h3><code>gettext</code> library</h3> +<p> + <code>calcurse</code> supports internationalization + (<em>i18n</em> hereafter) through the <code>gettext</code> + utilities. This means <code>calcurse</code> can produce + multi-lingual messages if compiled with native language + support (i.e. <em>NLS</em>). However, <em>NLS</em> is + optionnal and if you do not want to have support for + multi-lingual messages, you can disable this feature. This is + done by giving the <code>--disable-nls</code> option to + <code>configure</code> (see section <a + href="#install_process">Install process</a>). <br> + To check if the <code>gettext</code> utilities are + installed on your system, you can search for the + <code>libintl.h</code> header file for instance: + <pre> + locate libintl.h + </pre> + If this header file is not found, then you can obtain the + <code>gettext</code> sources at the following url :<br> + <pre> + http://ftp.gnu.org/pub/gnu/gettext/ + </pre> + <u>Note:</u> Even if <code>libintl.h</code> is found on your + system, it can be wise to specify its location during the <a + href="#install_process">install process</a>, by using the + <code>--with-libintl-prefix</code> option with + <code>configure</code>. Indeed, the <code>configure</code> + could fail to locate this library if installed in an uncommon + place. + + +<a name="install_process"></a><h2>Install process</h2> +<p> + First you need to gunzip and untar the source archive: + <pre> + tar zxvf calcurse-1.4.tar.gz + </pre> + Once you meet the requirements and have extracted the archive, + the install process is quite simple, and follows the standard + three steps process: + <OL> + <li><code>./configure</code> + <li><code>make</code> + <li><code>make install</code> (may require root privilege) + </OL> + Use <code>./configure --help</code> to obtain a list of + possible options. + + +<a name="basics"></a><h1><code>calcurse</code> basics</h1> +<a name="basics_invocation"></a><h2>Invocation</h2> +<a name="basics_invocation_commandline"></a><h3>Command line arguments</h3> +<p> + <code>calcurse</code> takes the following options from the + command line: + + <dl compact> + <dt><code>-a</code> + <dd> + Print the appointments for the current day and exit.<br> + <u>Note:</u> the calendar from which to read the appointments + can be specified using the '-c' flag.<br> + <br> + <dt><code>-c</code> + <dd> + Specify the calendar file to use.<br> + The default calendar is <code>~/.calcurse/apts</code> + (see section <a href="#basics_files"><code>calcurse</code> files</a>).<br> + <br> + <dt><code>-d</code> + <dd> + Print the appointments for the given date or for the + given number of upcoming days, depending on the argument + format. Two possible formats are supported: + <ul> + <li>a date of the form 'mm/dd/yyyy'. + <li>a number 'n'. + </ul> + In the first case, the appointment list for the + specified date will be returned, while in the second + case the appointment list for the 'n' upcoming days + will be returned.<br> + As an example, typing <code>calcurse -d 3</code> + will display your appointments for today, tomorrow, + and the day after tomorrow.<br> + <u>Note:</u> as for the '-a' flag, the calendar from + which to read the appointments can be specified using + the '-c' flag.<br> + <br> + <dt><code>-h</code> + <dd> + Print a short help text describing the supported + command-line options, and exit.<br> + <br> + <dt><code>-t</code> + <dd> + Print the 'todo' list and exit.<br> + <br> + <dt><code>-v</code> + <dd> + Display <code>calcurse</code> version and exit. + </DL> + +<a name="basics_invocation_variable"></a><h3>Environment variable for i18n</h3> +<p> + <code>calcurse</code> can be compiled with native language + support (see <a + href="#install_requirements_gettext"><code>gettext</code> + library</a>). Thus, if you wish to have messages displayed + into your native language, first make sure it is available by + looking at the <code>po/LINGUAS</code> file. + This file indicates the set of available languages by showing + the two-letters corresponding code (for exemple, <em>fr</em> + stands for french). If you do not find your language, it + would be greatly appreciated if you could help translating + <code>calcurse</code> (see the <a href="#contribute">How to + contribute?</a> section).<br> + If your language is available, run + <code>calcurse</code> with the following command: + <pre> + LC_ALL=fr_FR calcurse + </pre> + where <em>fr_FR</em> is the locale name in this exemple, but + should be replaced by the locale corresponding to the desired + language. + +<a name="basics_interface"></a><h2>User interface</h2> +<a name="basics_interface_noninteractive"></a><h3>Non-interactive mode</h3> +<p> + When called with at least one of the following arguments:<br> + <code>-a</code>, <code>-d</code>, <code>-t</code>, + <code>-h</code>, <code>-v</code><br> + <code>calcurse</code> is started in non-interactive mode. + This means the desired information will be displayed, and + after that, <code>calcurse</code> simply quits and you are + driven back to the shell prompt.<br> + That way, one can add a line such as <code>'calcurse -ta'</code> + in its init config file to display at logon the list of tasks + and appointments scheduled for the current day. + + +<a name="basics_interface_interactive"></a><h3>Interactive mode</h3> +<p> + When called without any argument or only with the + <code>-c</code> option, <code>calcurse</code> is started in + interactive mode. In this mode, you are shown an interface + containing three different panels which you can browse using + the 'TAB' key, plus a status bar (see figure below). + <pre> + + appointment panel---. .---calendar panel + | | + v v + +------------------------------------++----------------------------+ + | Appointments || Calendar | + |------------------------------------||----------------------------| + | April 6, 2006 || April 2006 | + | ||Mon Tue Wed Thu Fri Sat Sun | + | || 1 2 | + | || 3 4 5 6 7 8 9 | + | || 10 11 12 13 14 15 16 | + | || 17 18 19 20 21 22 23 | + | || 24 25 26 27 28 29 30 | + | || | + | |+----------------------------+ + | |+----------------------------+ + | || ToDo | todo + | ||----------------------------| panel + | || | | + | || | | + | || |<--. + | || | + | || | + | || | + +------------------------------------++----------------------------+ + | ? Help R Redraw H/L -/+1 Day G GoTo C Config | + | Q Quit S Save J/K -/+1 Week Tab Chg View |<-. + +------------------------------------------------------------------+ | + | + status bar + + </pre> + The first panel represents a calendar which allows to highligth + a particular day, the second one contains the list of the events + and appointments on that day, and the last one contains a list + of tasks to do but which are not assigned to any specific day. + In the bottom line of the screen there is a status bar, which + indicates the possible actions and the corresponding keystrokes. + + +<a name="basics_files"></a><h2><code>calcurse</code> files</h2> +<p> + The following structure is created in your <code>$HOME</code> + directory the first time <code>calcurse</code> is run : + <pre> + $HOME/.calcurse/ + |___conf + |___apts + |___todo + </pre> + The <em>conf</em> file contains the user configuration.<br> + The <em>apts</em> file contains all of the events and + user's appointments.<br> + The <em>todo</em> file contains the todo list. + + +<a name="basics_help"></a><h2>Online help</h2> +<p> + At any time, the built-in help system can be invoked by + pressing the '?' key. Once viewing the help screens, + informations on a specific command can be accessed by pressing + the keystroke corresponding to that command. + +<a name="options"></a><h1>Options</h1> +<p> + All of the <code>calcurse</code> parameters are configurable from the + Configuration menu available when pressing 'C'. You are then + driven to a submenu with three possible choices : pressing 'C' + again will lead you to the Color scheme configuration, + pressing 'L' allows you to choose the layout of the main + <code>calcurse</code> screen (in other words, where to put the three + different panels on screen), and last you can choose between + different general options by pressing 'G'. + +<a name="options_general"></a><h2>General options</h2> +<p> + These options control <code>calcurse</code> general behavior, + as described below: + <ul> + <li><code>auto_save</code> (default: <em>yes</em>)<br> + This option allows to automatically save the user's data + (if set to <em>yes</em>) when quitting.<br> + <em>warning:</em> No data will be automatically saved if + <code>auto_save</code> is set to <em>no</em>. This means + the user must press 'S' (for saving) in order to retrieve its + modifications.<br> + <br> + <li><code>confirm_quit</code> (default: <em>yes</em>)<br> + If set to <em>yes</em>, confirmation is required before + quitting, otherwise pressing 'Q' will cause <code>calcurse</code> + to quit without prompting for user confirmation.<br> + <br> + <li><code>confirm_delete</code> (default: <em>yes</em>)<br> + If this option is set to <em>yes</em>, pressing 'D' for + deleting an item (either a <em>todo</em>, <em>appointment</em>, + or <em>event</em>), will lead to a prompt asking for user + confirmation before removing the selected item from the list. + Otherwise, no confirmation will be needed before deleting the + item.<br> + <br> + <li><code>skip_system_dialogs</code> (default: <em>no</em>)<br> + Setting this option to <em>yes</em> will result in skipping the + system dialogs related to the saving and loading of data. + This can be useful to speed up the input/output processes.<br> + <br> + <li><code>skip_progress_bar</code> (default: <em>no</em>)<br> + If set to <em>yes</em>, this will cause the disappearing of the + progress bar which is usually shown when saving data to file. + If set to <em>no</em>, this bar will be displayed, together with + the name of the file being saved + (see section <a href="#basics_files"><code>calcurse</code> files</a>).<br> + <br> + <li><code>week_begins_on_monday</code> (default: <em>yes</em>)<br> + One can choose between Monday and Sunday as the first day of the + week. If the option <em>week_begins_on_monday</em> is set to + <em>yes</em>, Monday will be first in the calendar view. Else if + the option is set to <em>no</em>, then Sunday will be the first + day of the week. + </ul> + + +<a name="options_colors"></a><h2>Color themes</h2> +<p> + <code>calcurse</code> color theme is configurable and is to be + chosen by typing the number corresponding to the desired + theme. This color will then be applied to the panel borders, + to the titles, to the keystrokes, and to general informations + displayed inside status bar. A black and white theme is also + available, in order to support non-color terminals.<br> + <u>Notes:</u> + <ul> + <li> Depending on your terminal type and on the value of the + <code>$TERM</code> environnement variable, color could or + could not be supported. An error message will appear if you + try to change colors whereas your terminal does not support + this feature.<br> + <br> + <li> If you do know your terminal supports colors but could + not get <code>calcurse</code> to display them, try to set your + <code>$TERM</code> variable to another value (such as + <em>xterm-xfree86</em> for instance). + </ul> + + +<a name="options_layout"></a><h2>Layout configuration</h2> +<p> + The layout corresponds to the position of the panels inside + <code>calcurse</code> screen. The default layout makes the + calendar panel to be displayed on the top-right corner of the + terminal, the todo panel on the bottom-right corner, while the + appointment panel is displayed on the left hand-side of the + screen (see the figure in section + <a href="#basics_interface_interactive">Interactive mode</a> + for an exemple of the default layout).<br> + By choosing another layout in the configuration screen, user + can customize <code>calcurse</code> appearence to best suit + his needs by placing the different panels where needed. + + +<a name="known_bugs"></a><h1>Known bugs</h1> +<p> + Incorrect highlighting of items appear when using calcurse + black and white theme together with a <code>$TERM</code> + variable set to <em>xterm-color</em>. + To fix this bug, and as advised by Thomas E. Dickey + (<code>xterm</code> maintainer), <em>xterm-xfree86</em> + should be used instead of <em>xterm-color</em> to set + the <code>$TERM</code> variable:<br> + <blockquote> + "The xterm-color value for $TERM is a bad choice for XFree86 xterm + because it is commonly used for a terminfo entry which happens to + not support bce. Use the xterm-xfree86 entry which is distributed + with XFree86 xterm (or the similar one distributed with ncurses)." + </blockquote> + +<a name="bugs"></a><h1>Reporting bugs and feedback</h1> +<p> + Please send bug reports and feedback to: + <pre> + calcurse@culot.org + </pre> + or to the author: + <pre> + frederic@culot.org + </pre> + +<a name="contribute"></a><h1>How to contribute?</h1> +<p> + If you would like to contribute to the project, + you can first send your feedback on what you like or dislike, + and if there are features you miss in <code>calcurse</code>. + For now on, possible contributions concern the translation + of <code>calcurse</code> messages and documentation. <br> + <br> + <u>Note:</u> Any help in getting <code>calcurse</code> + internationalized would be very welcomed, but before + contributing, send a mail to + <code>calcurse-i18n@culot.org</code> to know if someone + already started the translation process into your language. + +<a name="contribute_documentation"></a><h2>Translating documentation</h2> +<p> + The <em>doc/</em> directory of the source package already + contains translated version of <code>calcurse</code> + manual. However, if the manual is not yet available into your + native language, it would be appreciated if you could help + translating it.<br> + To do so, just copy one of the existing manual + file to <code>manual_XX.html</code>, where <em>XX</em> + identifies your language. Then translate this newly created + file and send it to the author (see <a href="#bugs">Reporting + bugs and feeback</a>), so that it can be included in the + next <code>calcurse</code> release. + +<a name="contribute_i18n"></a><h2><code>calcurse</code> i18n</h2> +<p> + As already mentioned, <code>gettext</code> utilities are used + by <code>calcurse</code> to produce multi-lingual + messages. This section provides informations about how to + translate those messages into your native language. However, + this howto is deliberately incomplete, focusing on working + with <code>gettext</code> for <code>calcurse</code> + specifically. For more comprehensive informations or to grasp + the Big Picture of Native Language Support, you should refer + to the <code>GNU gettext</code> manual at: + <pre> + http://www.gnu.org/software/gettext/manual/ + </pre> + Basically, three different people get involved in the + translation chain: coders, language coordinator, and + translators. After a quick overview of how things work, the + translator tasks will be described hereafter. + + +<a name="contribute_i18n_overview"></a><h3>Overview</h3> +<p> + To be able to display texts in the native language of the + user, two steps are required: <em>internationalization</em> + (i18n) and <em>localization</em> (l10n). i18n is about making + <code>calcurse</code> support multiple languages. It is + performed by coders, who will mark translatable texts and + provide a way to display them translated at runtime. l10n is + about making the i18n'ed <code>calcurse</code> adapt to the + specific language of the user, ie translating the strings + previously marked by the developers, and setting the + environment correctly for <code>calcurse</code> to use the + result of this translation.<br> <br> + + So, translatable strings are first marked by the coders within + the <code>C</code> source files, then gathered in a template + file (<em>calcurse.pot</em> - the <em>pot</em> extension + meaning <em>portable object template</em>). The content of + this template file is then merged with the translation files + for each language (<em>fr.po</em> for french, for instance - + with <em>po</em> standing for <em>portable object</em>, ie + meant to be read and edited by humans). A given translation + team will take this file, translate its strings, and send it + back to the developers. At compilation time, a binary version + of this file (for efficiency reasons) will be produced + (<em>fr.mo</em> - <em>mo</em> stands for <em>machine + object</em>, ie meant to be read by programs), and then + installed. Then <code>calcurse</code> will use this file at + runtime, translating the strings according to the locale + settings of the user. + + +<a name="contribute_i18n_translator"></a><h3>Translator tasks</h3> +<p> + Suppose someone wants to initiate the translation of a new + language. Here are the steps to follow: + <ul> + <li>First, find out what the locale name is. For instance, for + french, it is 'fr_FR', or simply 'fr'. This is the value the + user will have to put in his <code>LC_ALL</code> environment + variable for software to be translated (see <a + href="#basics_invocation_variable">Environment variable for + i18n</a>).<br> + <br> + <li>Then, go into the <em>po/</em> directory, and create a new po-file + from the template file using the following command: + <pre> + 'msginit -i calcurse.pot -o fr.po -l fr --no-translator' + </pre> + If you do not have <code>msginit</code> installed on your + system, simply copy the <em>calcurse.pot</em> file to + <em>fr.po</em> and edit the header by hand.<br> + Now, having this <em>fr.po</em> file, the translator is ready + to begin. + </ul> + + +<a name="contribute_i18n_po-files"></a><h3>po-files</h3> +<p> + The format of the po-files is quite simple. Indeed, po-files + are made of four things: + <ol> + <li><em>location lines:</em> tells you where the strings can + be seen (name of file and line number), in case you need to + see a bit of context. + <li><em>msgid lines:</em> the strings to translate. + <li><em>msgstr lines:</em> the translated strings. + <li><em>lines prefixed with '#':</em> comments (some with a + special meaning, as we will see below). + </ol> + Basically, all you have to do is fill the <em>msgstr</em> + lines with the translation of the above <em>msgid</em> + line. + <p> + <u>A few notes:</u> + <ul> + <li><em>Fuzzy strings</em><br> + You will meet strings marked with a <code>"#, fuzzy"</code> + comment. <code>calcurse</code> won't use the translations of + such strings until you do something about them. A string + being fuzzy means either that the string has already been + translated but has since been changed in the sources of the + program, or that this is a new string for which + <code>gettext</code> made a 'wild guess' for the translation, + based on other strings in the file. It means you have to + review the translation. Sometimes, the original string has + changed just because a typo has been fixed. In this case, you + won't have to change anything. But sometimes, the translation + will no longer be accurate and needs to be changed. Once you + are done and happy with the translation, just remove the + <code>"#, fuzzy"</code> line, and the translation will be used + again in <code>calcurse</code>.<br> + <br> + <li><em>c-format strings and special sequences</em><br> + Some strings have the following comment: <code>"#, + c-format"</code>. This tells that parts of the string to + translate have a special meaning for the program, and that you + should leave them alone. For instance, %-sequences, like + <code>"%s"</code>. These means that <code>calcurse</code> will + replace them with another string. So it is important it + remains. There are also \-sequences, like <code>\n</code> or + <code>\t</code>. Leave them, too. The former represents an end + of line, the latter a tabulation.<br> + <br> + <li><em>Translations can be wrapped</em><br> + If lines are too long, you can just break them like this: + <pre> + msgid "" + "some very long line" + "another line" + </pre> + <li><em>po-file header</em><br> + At the very beginning of the po-file, the first string form a + header, where various kind of information has to be filled + in. Most important one is the charset. It should resemble + <pre> + "Content-Type: text/plain; charset=utf-8\n" + </pre> + You should also fill in the Last-Translator field, so that + potential contributors can contact you if they want to join + you in the translation team, or have remarks/typo fixes to + give about the translations. You can either just give your + name/nick, or add an email address, for exemple: + <pre> + "Last-Translator: Frederic Culot <frederic@culot.org>\n" + </pre> + <li><em>Comments</em><br> + Adding comments (lines begining with the '#' character) can be + a good way to point out problems or translation difficulties + to proofreaders or other members of your team.<br> + <br> + <li><em>Strings size</em><br> + <code>calcurse</code> is a curses/console program, thus it can + be heavily dependant on the terminal size (number of + columns). You should think about this when translating. Often, + a string must fit into a single line (standard length is 80 + characters). Don't translate blindly, try to look where your + string will be displayed to adapt your translation.<br> + <br> + <li><em>A few useful tools</em><br> + The po-file format is very simple, and the file can be edited + with a standard text editor. But if you prefer, there are few + specialized tools you may find convenient for translating: + <ul> + <li><code>poEdit</code> (<a + href="http://www.poedit.org/" target="_blank"> + http://www.poedit.org/</a>) + <li><code>KBabel</code> (<a + href="http://i18n.kde.org/tools/kbabel/" target="_blank"> + http://i18n.kde.org/tools/kbabel/</a>) + <li><code>GTranslator</code> (<a + href="http://gtranslator.sourceforge.net/" target="_blank"> + http://gtranslator.sourceforge.net/</a>) + <li><code>Emacs</code> po mode + <li><code>Vim</code> po mode + </ul> + <br> + <li><em>And finally</em><br> + I hope you'll have fun contributing to a more + internationalized world. :) If you have any more questions, + don't hesitate to contact me at <em>frederic@culot.org</em>. + </ul> + + +<a name="links"></a><h1>Links</h1> +<p> + This section contains links and references that may be of + interest to you. + + +<a name="links_homepage"></a><h2><code>calcurse</code> homepage</h2> +<p> + The <code>calcurse</code> homepage can be found at + <pre> + http://culot.org/calcurse + </pre> + +<a name="links_list"></a><h2><code>calcurse</code> announce list</h2> +<p> + If you are interested in the project and want to be warned + when a new release comes out, you can subscribe to the + <code>calcurse</code> announce list. In doing so, you will + receive an email as soon as a new feature appears in + <code>calcurse</code>.<br> + To subscribe to this list, send a message to + <code>calcurse-announce@culot.org</code> with "subscribe" + in the subject field. + + +<a name="thanks"></a><h1>Thanks</a></h1> +<p> + Its time now to thank other people without whom this program + would not exist! So here is a list of contributing persons I + would like to thank : + <ul> + <li>Alex for its patches, help and advices with <code>C</code> programming + <li>Gwen for testing and general discussions about how to + improve <code>calcurse</code> + <li>Kevin and Ryan for packaging <code>calcurse</code> for Debian + <li>Steffen for packaging <code>calcurse</code> for Archlinux + <li>Alexandre for packaging <code>calcurse</code> for Mac OsX + <li>Joel for its calendar script which inspired <code>calcurse</code> + calendar view + <li>Michael Schulz for the german translation of + <code>calcurse</code> manual + <li>people who write softwares I like and which inspired me, + especially : + <ul> + <li><code>vim</code> for the displacement keys + <li><code>orpheus</code> and <code>abook</code> for documentation + <li><code>pine</code> and <code>aptitude</code> + for the text user interface + </ul> + </ul> + <br> + And last, many many thanks to all of the <code>calcurse</code> + users who sent me their feedback. + +<hr> +<small><em> +Copyright (c) 2004-2006 Frédéric Culot<br> +Calcurse version 1.4 - Last change: May 07, 2006 +<em></small> + + +</body> +</html> diff --git a/doc/manual_fr.html b/doc/manual_fr.html new file mode 100755 index 0000000..d7fbf6e --- /dev/null +++ b/doc/manual_fr.html @@ -0,0 +1,898 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<!-- +/* + * $calcurse: manual_fr.html,v 1.1 2006/07/31 21:00:05 culot Exp $ + * + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ +--> + +<html> +<head> +<title>documentation de CALCURSE</title> +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> +</head> +<body bgcolor="white" text="black" link="blue" vlink="navy"> + +<h1><code>CALCURSE - organiseur en mode texte</code></h1> +<p> +<p><hr><p> + +<h1>Table des matières</h1> +<ul> +<li><a href="#intro">Introduction</a> +<li><a href="#overview">Aperçu du logiciel</a> +<ul> +<li><a href="#overview_history">Origine de Calcurse</a> +<li><a href="#overview_features">Caractéristiques importantes</a> +</ul> +<li><a href="#install">Installation</a> +<ul> +<li><a href="#install_requirements">Pré-requis</a> +<ul> +<li><a href="#install_requirements_ncurses">Librairie <code>ncurses</code></a> +<li><a href="#install_requirements_gettext">Librairie <code>gettext</code></a> +</ul> +<li><a href="#install_process">Processus d'installation</a> +</ul> +<li><a href="#basics">Présentation générale</a> +<ul> +<li><a href="#basics_invocation">Invocation</a> +<ul> +<li><a href="#basics_invocation_commandline">Arguments en ligne de commande</a> +<li><a href="#basics_invocation_variable">Variable d'environnement pour l'i18n</a> +</ul> +<li><a href="#basics_interface">Interface utilisateur</a> +<ul> +<li><a href="#basics_interface_noninteractive">Mode non-interactif</a> +<li><a href="#basics_interface_interactive">Mode Interactif</a> +</ul> +<li><a href="#basics_files">Fichiers</a> +<li><a href="#basics_help">Aide en ligne</a> +</ul> +<li><a href="#options">Options</a> +<ul> +<li><a href="#options_general">Options générales</a> +<li><a href="#options_colors">Thèmes graphiques</a> +<li><a href="#options_layout">Disposition des panneaux</a> +</ul> +<li><a href="#known_bugs">Bogues connus</a> +<li><a href="#bugs">Rapporter les bogues et commentaires</a> +<li><a href="#contribute">Comment contribuer?</a> +<ul> +<li><a href="#contribute_documentation">Traduction de la documentation</a> +<li><a href="#contribute_i18n">Traduction de <code>calcurse</code></a> +<ul> +<li><a href="#contribute_i18n_overview">Aperçu</a> +<li><a href="#contribute_i18n_translator">Etapes de la traducion</a> +<li><a href="#contribute_i18n_po-files">Fichiers <em>po</em></a> +</ul> +</ul> +<li><a href="#links">Liens</a> +<ul> +<li><a href="#links_homepage">Site internet de <code>calcurse</code></a> +<li><a href="#links_list">Liste de diffusion de <code>calcurse</code></a> +</ul> +<li><a href="#thanks">Remerciements</a> +</ul> +<p><hr><p> + + +<a name="intro"></a><h1>Introduction</a></h1> +<p> + <code>calcurse</code> est un organiseur personnel en mode texte, + qui a pour but de gérer les rendez-vous et les tâches + à faire. Il est composé d'un calendrier, d'une + liste de tâches, et classe les rendez-vous. + L'interface utilisateur est configurable, et l'on peut + choisir entre différents thèmes graphiques (couleur et + disposition des élements de l'interface). + Toutes les commandes sont documentées dans un système + d'aide en ligne. + + +<a name="overview"></a><h1>Aperçu du logiciel</h1> +<a name="overview_history"></a><h2>Origine de Calcurse</h2> +<p> + J'ai commencé à penser à ce projet à la fin de mon doctorat + en astrophysique... Je commençais en effet à avoir de plus + en plus de mal à m'organiser, et j'avais vraiment besoin d'un + bon outil pour m'aider dans cette tâche difficile ;)<br> + D'autre part, j'apprécie beaucoup les logiciels qui font + appel à des Interfaces en Mode Texte, parce que je les trouve + plus simples, plus rapides, plus portables et plus efficaces. + J'ai alors commencé à programmer un calendrier rudimentaire + qui utilisait une interface de ce type. + En plus de cela, je voulais améliorer mes connaissances en + <code>C</code>, langage de programmation que je n'avais + utilisé jusqu'alors que dans le cadre de petits projets pendant + mes études. J'ai donc pensé que ce serait une bonne chose de me + lancer dans ce projet, puisque cela me permettrait à la fois de + mieux m'organiser, et d'apprendre à mieux programmer en + <code>C</code>! + Malheureusement, j'ai obtenu mon doctorat avant de terminer + <code>calcurse</code>, mais j'ai tout de même voulu continuer + à travailler + sur ce projet, en espérant que ce programme serait utile à + d'autres personnes. Voilà comment est né + <code>calcurse</code>...<br> + <br> + Mais au fait, pourquoi 'calcurse' ? Et bien ce nom provient + simplement de la concaténation de 'CALendrier' et de 'nCURSEs', + qui est le nom de la librairie utilisée pour construire + l'interface utilisateur. + + +<a name="overview_features"></a><h2>Caractéristiques importantes</h2> +<p> + <code>Calcurse</code> est multi-plateformes et est conçu pour + être léger, rapide et fiable. Il doit être utilisé dans un + terminal ou une console, soit localement ou bien sur une + machine distante par l'intermediaire d'une liaison ssh (ou + similaire).<br> + <code>Calcurse</code> peut être lancé dans deux modes différents: + soit interactif, soit non-interactif. Le premier mode permet + de visualiser son organiseur personnel pratiquement sous + n'importe quel environnement, grâce à l'interface en mode texte. + Le deuxième mode permet de créer facilement des penses-bête en + ajoutant <code>calcurse</code> avec les arguments appropriés dans + la table cron ou dans le script d'initialisation du shell.<br> + De plus, <code>calcurse</code> a été créé en prenant en compte + l'utilisateur final à chaque étape de sa conception, c'est-à-dire + en essayant d'être le plus intuitif possible. Cela implique + la présence d'une aide en ligne exhaustive, ainsi que le rappel de + toutes les commandes possibles dans la barre de status. + L'interface utilisateur est également configurable, et l'on peut + choisir parmis de nombreuses combinaisons possibles de couleurs + et de positions des fenêtres. + + +<a name="install"></a><h1>Installation</h1> +<a name="install_requirements"></a><h2>Pré-requis</h2> +<a name="install_requirements_ncurses"></a><h3>Librairie <code>ncurses</code></h3> +<p> + L'installation de <code>Calcurse</code> ne nécessite qu'un + compilateur <code>C</code>, comme <code>cc</code> ou <code>gcc</code>, + et la librairie <code>ncurses</code>. + Il serait très surprenant que vous n'ayez pas déjà la librairie + <code>ncurses</code> d'installée sur votre machine, mais si + c'est le cas, vous pourrez la trouver à l'adresse suivante :<br> + <pre> + http://ftp.gnu.org/pub/gnu/ncurses/ + </pre> + + +<a name="install_requirements_gettext"></a><h3>Librairie <code>gettext</code></h3> +<p> + <code>calcurse</code> s'aide de la librairie + <code>gettext</code> pour le support de l'internationalisation + (noté <em>i18n</em> ci-après). + Cela signifie que <code>calcurse</code> peut fournir des + messages multilingues si il est compilé avec le support + NLS (<em>Native Language Support</em> - <em>Support de Langage + Natif</em>). Cependant, ce support est optionnel et si vous + n'avez pas besoin de la traduction des messages + affichés, vous pouvez sésactiver cette option. + La désactivation du support <em>NLS</em> s'effectue en + passant l'option <code>--disable-nls</code> à + <code>configure</code> (voir la section <a + href="#install_process">Processus d'Installation</a>). <br> + Pour vérifier que les utilitaires <code>gettext</code> + sont bien installés sur votre systsème, vous + pouvez par exemple vérifier la présence du + fichier <code>libintl.h</code> en tapant : + <pre> + locate libintl.h + </pre> + Dans l'éventualité où ce fichier ne + serait pas trouvé, vous pouvez obtenir les sources de + <code>gettext</code> à l'adresse suivante :<br> + <pre> + http://ftp.gnu.org/pub/gnu/gettext/ + </pre> + <u>Remarque:</u> Même si <code>libintl.h</code> est bien + localisé par la commande précédente, il + peut être utile de spécifier son emplacement au + moment de lancer le <a href="#install_process">processus + d'installation</a>, en passant l'option + <code>--with-libintl-prefix</code> au script + <code>configure</code>. En effet, ce script pourrait + ne pas trouver le fichier <code>libintl.h</code> si celui-ci + n'est pas installé dans un endroit usuel. + + +<a name="install_process"></a><h2>Processus d'installation</h2> +<p> + Vous devez tout d'abord décompresser l'archive source de la + manière suivante : + <pre> + tar zxvf calcurse-1.4.tar.gz + </pre> + Une fois que vous remplissez tous les pré-requis nécessaires à + l'installation, le processus de compilation est simple et suit + les trois étapes usuelles : + <OL> + <li><code>./configure</code> + <li><code>make</code> + <li><code>make install</code> (peut nécessiter les privilèges + super-utilisateur) + </OL> + Vous pouvez obtenir la liste des options possibles en tapant + <code>./configure --help</code>. + + +<a name="basics"></a><h1>Présentation générale</h1> +<a name="basics_invocation"></a><h2>Invocation</h2> +<a name="basics_invocation_commandline"></a><h3>Arguments en ligne de commande</h3> +<p> + Lors de son appel en ligne de commande, <code>calcurse</code> + accepte les arguments suivants : + + <dl compact> + <dt><code>-a</code> + <dd> + Affiche les rendez-vous pour la date du jour, puis quitte.<br> + <u>Remarque:</u> le calendrier à utiliser peut être + spécifié en utilisant l'option '-c'.<br> + <br> + <dt><code>-c</code> + <dd> + Spécifie le fichier calendrier à uiliser.<br> + Le calendrier par défaut est celui contenu dans + <code>~/.calcurse/apts</code> + (voir la section <a href="#basics_files">Fichiers</a>).<br> + <br> + <dt><code>-d</code> + <dd> + Affiche les rendez-vous pour la date ou pour le nombre de + jours indiqués, suivant le format de l'argument. Deux + formats différents sont acceptés : + <ul> + <li>une date sous la forme 'mm/jj/aaaa'. + <li>un nombre 'n'. + </ul> + Dans le premier cas, la liste des rendez-vous pour la + date spécifiée sera affichée, alors que dans le + deuxième cas, la liste des rendez-vous pour les 'n' + jours à venir sera retournée.<br> + Par exemple, taper <code>calcurse -d 3</code> fera + s'afficher les rendez-vous pour aujourd'hui, demain + et après-demain.<br> + <u>Remarque:</u> comme pour l'option '-a', le fichier + contenant le calendrier à lire peut être spécifié en + utilisant l'option '-c'.<br> + <br> + <dt><code>-h</code> + <dd> + Affiche l'aide décrivant les options en ligne de commande, + puis quitte.<br> + <br> + <dt><code>-t</code> + <dd> + Affiche la liste des 'todo', puis quitte.<br> + <br> + <dt><code>-v</code> + <dd> + Affiche la version de <code>calcurse</code>, puis quitte. + </DL> + + +<a name="basics_invocation_variable"></a><h3>Variable d'environnement +pour l'i18n</h3> +<p> + <code>calcurse</code> peut être compilé avec le + support <em>NLS</em> (voir <a + href="#install_requirements_gettext">Librairie + <code>gettext</code></a>). Ainsi, si vous voulez que les + messages affichés apparaissent dans votre langue + natale, assurez-vous tout d'abord que celle-ci est + présente dans le fichier <code>po/LINGUAS</code>. + Ce fichier indique toutes les traductions disponibles par + l'intermédiaire d'un code de deux lettres (par exemple, + <em>fr</em> représente le français). Si vous ne + trouvez pas votre langue, il serait très + apprécié que vous apportiez votre aide pour + traduire <code>calcurse</code> (voir la partie <a + href="#contribute">Comment contribuer?</a>).<br> + Si votre langue est disponible, lancez <code>calcurse</code> + en utilisant la commande suivante : + <pre> + LC_ALL=fr_FR calcurse + </pre> + où <em>fr_FR</em> doit être remplacé par + la <em>locale</em> (code de la langue suivi du code pays) + correspondant à la traduction voulue. + + +<a name="basics_interface"></a><h2>Interface utilisateur</h2> +<a name="basics_interface_noninteractive"></a><h3>Mode non-interactif</h3> +<p> + Lorsque il est appelé avec au moins un des arguments suivants:<br> + <code>-a</code>, <code>-d</code>, <code>-t</code>, + <code>-h</code>, <code>-v</code><br> + <code>calcurse</code> est lancé en mode non-interactif. + Cela signifie que l'information demandée sera affichée, + puis <code>calcurse</code> quittera et vous serez ramené + au prompt de l'interpréteur de commandes.<br> + De ce manière, il est possible de rajouter une ligne telle + que <code>'calcurse -ta'</code> dans le fichier d'initialisation + de son environnement, afin de faire s'afficher à chaque + début de session la liste des tâches à faire et des rendez-vous + planifiés pour la journée. + + +<a name="basics_interface_interactive"></a><h3>Mode interactif</h3> +<p> + Lorsqu'il est appelé sans aucun argument ou uniquement avec + l'option <code>'-c'</code>, <code>calcurse</code> est lancé + en mode interactif. Dans ce mode s'affiche une interface qui + contient trois panneaux différents, qu'il est possible de + sélectionner cycliquement en utilisant la touche 'TAB', ainsi + que d'une barre de status (voir la figure ci-dessous). + <pre> + + panneau rendez-vous---. .---panneau calendrier + | | + v v + +------------------------------------++----------------------------+ + | Rendez-vous || Calendrier | + |------------------------------------||----------------------------| + | Avril 6, 2006 || Avril 2006 | + | ||Lun Mar Mer Jeu Ven Sam Dim | + | || 1 2 | + | || 3 4 5 6 7 8 9 | + | || 10 11 12 13 14 15 16 | + | || 17 18 19 20 21 22 23 | + | || 24 25 26 27 28 29 30 | + | || | + | |+----------------------------+ + | |+----------------------------+ + | || Tâches | panneau + | ||----------------------------| tâches à + | || | faire + | || | | + | || |<--. + | || | + | || | + | || | + +------------------------------------++----------------------------+ + | ? Aide R Retracer H/L -+1 Jour G Aller à C Config | + | Q Quitter S Sauver J/K -+1 Sem. Tab Chg vue |<-. + +------------------------------------------------------------------+ | + | + barre de status + + </pre> + Le premier panneau représente un calendrier qui permet de + sélectionner un jour en particulier. Le second panneau contient + une liste d'évènements et les rendez-vous du jour, et le dernier + contient une liste des tâches à faire, mais qui ne sont pas + assignée à une journée en particulier. + En bas de l'écran on retrouve une barre de status, qui indique + les actions possibles en fonction du contexte, ainsi que la + touche qui doit être pressée pour effectuer cette action. + + +<a name="basics_files"></a><h2>Fichiers</h2> +<p> + La structure de fichiers suivante est créée dans le répertoire + <code>$HOME</code> de l'utilisateur la première fois que + <code>calcurse</code> est lancé : + <pre> + $HOME/.calcurse/ + |___conf + |___apts + |___todo + </pre> + Le fichier <em>conf</em> contient la configuration de l'utilisateur.<br> + Le fichier <em>apts</em> contient tous les évenements ainsi que + les rendez-vous de l'utilisateur.<br> + Le fichier <em>todo</em> contient la liste des tâches à effectuer. + + +<a name="basics_help"></a><h2>Aide en ligne</h2> +<p> + A n'importe quel moment, le système d'aide en ligne peut être + appelé en pressant la touche '?'. Une fois rentré dans l'aide, + les informations sur une commande spécifique peuvent être + obtenues en appuyant sur la touche correspondant à cette + commande. + + +<a name="options"></a><h1>Options</h1> +<p> + Tous les paramètres de <code>calcurse</code> sont configurables + à partir du menu <em>Configuration</em>, accessible en appuyant + sur 'C'. L'utilisateur se voit alors présenté un second menu + avec trois choix possibles : appuyer à nouveau sur 'C' amène + au menu de sélection des couleurs de l'interface, appuyer sur + 'L' permet de choisir parmis différents emplacements pour les + panneaux de la fenêtre principale de <code>calcurse</code>, + et enfin les options générales peuvent être fixées en pressant + 'G'. + + +<a name="options_general"></a><h2>Options générales</h2> +<p> + Ces options contrôlent le comportement général de + <code>calcurse</code>, comme décrit ci-dessous : + <ul> + <li><code>sauvegarde_automatique</code> (valeur par défaut: <em>oui</em>)<br> + Cette option permet de sauvegarder automatiquement les + données de l'utilisateur avant de quitter, si elle est + fixée à <em>oui</em>.<br> + <em>attention:</em> Aucune donnée ne sera automatiquement + sauvegardée si cette variable est fixée à <em>non</em>. + Cela signifie que l'utilisateur doit appuyer sur 'S' + (pour sauvegarder) pour retrouver ses modifications au prochain + lancement de <code>calcurse</code>.<br> + <br> + <li><code>confirmer_pour_quitter</code> (valeur par défaut: <em>oui</em>)<br> + Si cette option est fixée à <em>oui</em>, la confirmation + de l'utilisateur est nécessaire avant de pouvoir quitter. + Autrement, appuyer sur 'Q' provoquera l'arrêt de + <code>calcurse</code> sans demander confirmation.<br> + <br> + <li><code>confirmer_pour_effacer</code> (valeur par défaut: <em>oui</em>)<br> + Si cette option est fixée à <em>oui</em>, appuyer sur 'D' + pour effacer un élement (soit une tâche, un rendez-vous ou bien + un évenement) provoquera l'apparition d'un message demandant + la confirmation de l'utilisateur avant d'effacer cet élement. + Si cette option est fixée à <em>non</em>, aucune confirmation + ne sera demandée avant l'effacement d'un élement.<br> + <br> + <li><code>masquer_messages_système</code> (valeur par défaut: <em>non</em>)<br> + Fixer cette option à <em>oui</em> provoque la disparition des + messages relatifs aux enregistrements ou lectures des fichiers + de données. Ceci peut être utile pour accélerer les processus + d'entrées/sorties.<br> + <br> + <li><code>masquer_barre_progression</code> (valeur par défaut: <em>non</em>)<br> + Si elle est fixée à <em>oui</em>, cette option provoque la + disparition de la barre de progression qui est normalement chargée + d'indiquer l'étât d'avancement de l'enregistrement des fichiers + de données. Si cette option est fixée à <em>non</em>, cette barre + sera affichée, en même temps que le nom du fichier de données + actuellement en cours d'écriture + (voir la section <a href="#basics_files">Fichiers</a>).<br> + <br> + <li><code>semaine_commence_lundi</code> (valeur par défaut: <em>oui</em>)<br> + Il est possible dans <code>calcurse</code> d'indiquer quel est le premier + jour de la semaine, à savoir soit le lundi, soit le dimanche. + Si l'option <em>semaine_commence_lundi</em> est fixée à + <em>oui</em>, les semaines du calendrier commenceront le lundi. + Par contre si cette option est fixée à <em>non</em>, + les semaines débuteront le dimanche. + </ul> + + +<a name="options_colors"></a><h2>Thèmes graphiques</h2> +<p> + Le thème graphique de <code>calcurse</code> est + configurable et doit être choisi en appuyant sur le + numéro correspond à la couleur voulue. Cette + couleur est alors appliquée à la bordure des + panneaux, aux titres, aux combinaisons de touches, et aux + informations générales affichées dans la + barre de status. Un thème en noir et blanc est + également disponible, afin de supporter les terminaux + monochromes.<br> + <u>Remarques:</u> + <ul> + <li> Suivant le type de terminal que vous utilisez, et suivant + la valeur de la variable d'environnement <code>$TERM</code>, + la couleur peut être supportée ou non. Un message + d'erreur apparaîtra si vous essayez d'appliquer un + thème graphique en couleur alors que votre terminal est + monochrome.<br> + <br> + <li> Si vous savez que votre terminal supporte les couleurs + mais que <code>calcurse</code> ne veut pas les afficher, + essayez de changer la valeur de la variable d'environnement + <code>$TERM</code> (appliquez par exemple la valeur + <em>xterm-xfree86</em>). + </ul> + + +<a name="options_layout"></a><h2>Disposition des panneaux</h2> +<p> + La disposition des panneaux à l'intérieur de la fenêtre de + <code>calcurse</code> peut être paramétrée. Par défaut, le + panneau contenant le calendrier se situe en haut à droite de + la fenêtre, le panneau contenant la liste des tâches est situé + en bas à droite, et le panneau contenant les rendez-vous se + trouve sur la partie gauche de l'écran (voir la figure dans la + section <a href="#basics_interface_interactive">Mode interactif</a> + pour un exemple de la disposition par défaut).<br> + En choisissant une autre disposition pour les éléments composants + la fenêtre de <code>calcurse</code>, l'utilisateur peut adapter + à ses besoins l'interface du programme. + + +<a name="known_bugs"></a><h1>Bogues connus</h1> +<p> + Une coloration incorrecte des objets peut résulter + d'une utilisation conjointe d'un thème graphique en + noir et blanc et d'une variable <code>$TERM</code> + fixée à <em>xterm-color</em>. Pour supprimer ce + bogue, et comme le conseille Thomas E. Dickey (le + résponsable du projet <code>xterm</code>), + <em>xterm-xfree86</em> devrait être assigné + à la variable <code>$TERM</code> en lieu et place de + <em>xterm-color</em> : + <blockquote> + "La valeur xterm-color pour la variable $TERM est un mauvais + choix pour les terminaux XFree86 parce qu'elle est couramment + utilisée pour les entrées terminfo qui ne + supportent pas bce. Utilisez plutôt l'entrée + xterm-xfree86 qui est distribuée avec le xterm + d'XFree86 (ou par celui, similaire, distribué avec ncurses)." + </blockquote> + + +<a name="bugs"></a><h1>Rapporter les bogues et commentaires</h1> +<p> + Merci de renvoyer vos rapports de bogues et vos commentaires à + l'adresse suivante : + <pre> + calcurse@culot.org + </pre> + ou directement à l'auteur : + <pre> + frederic@culot.org + </pre> + +<a name="contribute"></a><h1>Comment contribuer?</h1> +<p> + Si vous désirez contribuer au projet, vous pouvez tout d'abord + envoyer vos commentaires sur ce qui vous plais ou déplais ou sur + ce qui vous manque dans <code>calcurse</code>.<br> + Pour le moment, les contributions possibles concernent + la traduction des messages de <code>calcurse</code> ainsi que + de la documentation.<br> + <br> + <u>Remarque:</u> toute contribution à la traduction de + <code>calcurse</code> serait très + appréciée, mais avant tout, envoyez un mail + à <code>calcurse-i18n@culot.org</code> pour savoir si + quelqu'un a déjà commencé le processus de + traduction dans votre langue. + + +<a name="contribute_documentation"></a><h2>Traduction de la documentation</h2> +<p> + Le répertoire <em>doc/</em> du paquet source contient + déjà des versions traduites de la documentation. + Cependant, si celle-ci n'est pas encore disponible dans votre + langue, votre aide pour sa traduction serait très + appréciée.<br> + Pour cela, il suffit de copier un des fichiers existant et de + renommer cette copie en <code>manual_XX.html</code>, où + <em>XX</em> représente votre langue. Il faut ensuite + traduire ce fichier nouvellement créé et de + l'envoyer à l'auteur (voir <a href="#bugs">Rapporter + les bogues et commentaires</a>), pour qu'il soit inclus dans + la prochaine version de <code>calcurse</code>. + + +<a name="contribute_i18n"></a><h2>Traduction de <code>calcurse</code></h2> +<p> + Comme mentionné plus haut, les utilitaires + <code>gettext</code> sont utilisés par + <code>calcurse</code> pour produire des messages + multilingues. Cette section explique comment traduire ces + messages dans votre langue. Cependant, cette notice est + délibérément incomplète, + puisqu'elle ne se concentre que sur l'utilisation de + <code>gettext</code> avec <code>calcurse</code>. Pour avoir + une vision plus large du Support de Langage Natif + (<em>NLS</em>), il est préférable de se + référer au manuel de <code>GNU gettext</code> + que l'on peut trouver à l'adresse suivante : + <pre> + http://www.gnu.org/software/gettext/manual/ + </pre> + Pour résumer, trois catégories de personnes sont + impliquées dans la chaîne de traduction : les + programmeurs, les coordinateurs de la traduction, et les + traducteurs. Après un rapide aperçu de la + manière de procéder pour traduire le logiciel, + nous décrirons plus en détails les tâches du + traducteur. + + +<a name="contribute_i18n_overview"></a><h3>Aperçu</h3> +<p> + Afin de pouvoir afficher du texte dans la langue natale de + l'utilisateur, deux étapes sont nécessaires : + l'<em>internationalisation</em> (i18n), et la + <em>localisation</em> (l10n). + l'i18n permet à <code>calcurse</code> d'être + multilingues. C'est un processus qui est mis en place par les + programmeurs, qui marquent les phrases à traduire au + sein du code source, et qui fournissent les outils pour que + ces phrases soient traduites automatiquement pendant le + déroulement du programme. + La l10n correspond quant à elle au processus qui permet + à <code>calcurse</code> de s'adapter à la langue + de l'utilisateur. C'est-à-dire qu'il traduit les + phrases précédemment marquée par les + programmeurs, et qu'il fixe correctement les variables + d'environnement afin que <code>calcurse</code> puisse utiliser + les résultats de cette traduction.<br> + <br> + Ainsi, les phrases traduisibles sont tout d'abord + marquées par les programmeurs dans le code source, puis + rassemblées dans un fichier référence + (<code>calcurse.pot</code> - l'extension <em>pot</em> signifiant + <em>portable object template</em>, objet portable de + référence). Le contenu de ce fichier est alors + associé aux fichiers contenant la traduction pour + chacune des différentes langues (fichier <em>fr.po</em> + pour le français par exemple - <em>po</em> siginifiant + <em>portable object</em>, objet portable - qui peut être + lu par les humains). Le traducteur devra se servir de ce + fichier, et traduira les phrases qu'il contient, puis + l'enverra auw développeurs. Ensuite, au niveau de la + compilation du programme, une version binaire de ce fichier + sera produite (pour des raisons d'efficacité), puis + installée. Cette version binaire a pour extension + <em>.mo</em>, où <em>mo</em> signifie <em>machine + object</em> - objet machine, c'est-à-dire qui peut + être lu par le programme. Pour finir, + <code>calcurse</code> se servira de ce fichier <em>mo</em> + lors de son execution pour traduire les phrases dans la langue + de l'utilisateur. + + +<a name="contribute_i18n_translator"></a><h3>Etapes de la traduction</h3> +<p> + Supposons que quelqu'un veuille commencer une traduction dans + une nouvelle langue. Voici les étapes à suivre + pour ce faire : + <ul> + <li>Premièrement, trouver quel est le nom de la locale + correspondant à la langue à traduire. Par + exemple, pour le français, il s'agit de 'fr_FR', ou + simplement 'fr'. C'est cette valleur que l'utilisateur devra + mettre dans la variable d'environnement <code>LC_ALL</code> + pour obtenir la version traduite du logiciel (voir <a + + href="#basics_invocation_variable">Variable d'environnement + pour l'i18n</a>).<br> + <br> + <li>Ensuite, il faut se rendre dans le répertoire + <em>po/</em>, et créer un nouveau fichier <em>.po</em> + à partir du fichier de référence en + utilisant la commande suivante : + <pre> + 'msginit -i calcurse.pot -o fr.po -l fr --no-translator' + </pre> + Si vous n'avez pas <code>msginit</code> installé sur + votre système, vous pouvez plus simplement copier + <em>calcurse.pot</em> en <em>fr.po</em> par exemple, et editer + l'en-tête du fichier nouvellement créé + manuellement.<br> + Maintenant, ayant à disposition ce fichier + <em>fr.po</em>, la traduction peut commencer. + </ul> + + +<a name="contribute_i18n_po-files"></a><h3>Fichiers <em>po</em></h3> +<p> + Le format des fichiers <em>po</em> est assez simple. En effet, + ils ne contiennent que quatre éléments + différents : + <ol> + <li><em>ligne d'emplacement:</em> renseigne sur l'emplacement + de la phrase dans le fichier source (donne le nom du fichier + ainsi que le numéro de ligne), afin de retrouver + simplement le contexte d'où est issu la phrase à + traduire. + <li><em>ligne msgid:</em> indique la phrase à traduire. + <li><em>ligne msgstr:</em> ligne indiquant la phrase traduite. + <li><em>lignes commençant par '#'</em>: indiquent des + commentaires (certains ont une signification spéciale, + comme nous le verrons plus tard). + </ol> + Pour résumer, un traducteur doit simplement remplir les + champs <em>msgstr</em> avec la traduction des lignes + trouvées juste au dessus dans la partie <em>msgid</em>. + <p> + <u>Remarques:</u> + <ul> + <li><em>Phrases marquées Fuzzy</em><br> + Vous pourrez rencontrer des phrases commençant par le + commentaire <code>"#, fuzzy"</code>. + <code>calcurse</code> n'utilisera pas les traductions + commençant par ce commentaire, à moins que vous + ne transformiez ces phrases. En effet, le commentaire + <em>fuzzy</em> signifie que la phrase a déjà + été traduite mais qu'elle a depuis + été changée dans le source du programme, + ou bien que <em>gettext</em> a effectué lui-même + uen traduction, en se basant sur une phrase similaire. Cela + implique donc que vous devez vérifier la traduction. + Parfois, la phrase originale a changé suite à + une correction de faute de frappe. Dans ce cas, vous n'aurez + pas besoin de modifier la traduction. Mais dans d'autres cas, + cette traduction peut ne plus être valable et + nécessitera alors une mise à jour. Une fois + cette mise à jour effectuée, vous pouvez + supprimer + le commentaire <code>"#, fuzzy"</code>, et la traduction sera + alors à nouveau prise en compte par <code>calcurse</code>.<br> + <br> + <li><em>Lignes au format C et séquences spéciales</em><br> + Certaines phrases ont le commentaire suivant: <code>"#, + c-format"</code>. Cela signifie que des parties du texte + à traduire ont une signification particulière + pour le programme, et qu'il ne faut pas les modifier. Par + exemple, les séquences contenant des <em>%</em>, comme + <code>"%s"</code>. Cela signifie que <code>calcurse</code> + remplacera ces séquences par d'autres expressions. Il + est donc important de ne pas les modifier. Il existe + également des séquences contenant des + <em>/</em>, comme <code>\n</code> ou <code>\t</code>. Il ne + faut pas les modifier non plus. En effet, la première + séquence représente une fin de ligne, et la + deuxième une tabulation.<br> + <br> + <li><em>Découpage des traductions</em><br> + Si certaines lignes sont trop longues, il est possible de + découper les phrases comme dans l'exemple ci-après: + <pre> + msgid "" + "une ligne très longue" + "une autre ligne" + </pre> + <li><em>En-tête des fichiers po</em><br> + Au tout début du fichier <em>po</em>, la + première phrase forme un en-tête où + différentes informations doivent être + renseignées. La plus importante est le jeu de + caractès utilisé. Cette information devrait + ressembler à + <pre> + "Content-Type: text/plain; charset=utf-8\n" + </pre> + Il est également nécessaire de remplir le champ + <em>Last-Translator</em> - <em>Dernier Traducteur</em>, afin + que d'autres traducteurs potentiels puissent se mettre en + relation avec la dernière personne ayant + retouché le fichier. De cette manière, il est + plus simple de coordonner les efforts de traduction. Il est + possible de rajouter son adresse de courrier + électronique, par exemple: + <pre> + "Last-Translator: Frederic Culot <frederic@culot.org>\n" + </pre> + <li><em>Commentaires</em><br> + Ajouter des commentaires (lignes commençant par '#') + peut être un bon moyen de signaler des problèmes ou + difficultés de traduction aux autres traducteurs.<br> + <br> + <li><em>Taille des phrases</em><br> + <code>calcurse</code> est un programme comportant une + interface console/curses, il dépend donc de la taille + du terminal utilisé (plus particulièrement du + nombre de colonnes). Il est important de garder ceci en + mémoire au moment de la traduction. Souvent, la phrase + à traduire doit tenir dans une seule ligne (soit en + général 80 caractères). Il faut en tenir + compte, et essayer de voir où la phrase sera + placée pour adapter sa traduction.<br> + <br> + <li><em>Quelques outils utiles</em><br> + Le format des fichiers <em>po</em> est relativement simple, et + ils peuvent être modifiés avec un éditeur + de texte standard. Mais il est également possible + d'utiliser des outils spécialisés pour cette + tâche: + <ul> + <li><code>poEdit</code> (<a + href="http://www.poedit.org/" target="_blank"> + http://www.poedit.org/</a>) + <li><code>KBabel</code> (<a + href="http://i18n.kde.org/tools/kbabel/" target="_blank"> + http://i18n.kde.org/tools/kbabel/</a>) + <li><code>GTranslator</code> (<a + href="http://gtranslator.sourceforge.net/" target="_blank"> + http://gtranslator.sourceforge.net/</a>) + <li><code>Emacs</code> et son mode <em>po</em> + <li><code>Vim</code> et son mode <em>po</em> + </ul> + <br> + <li><em>Finallement...</em><br> + J'éspère que vous prendrez plaisir à + contribuer à l'internationalisation du monde des + logiciels libres. :) Si vous avez d'autres questions + concernant ce processus, n'hésitez pas à me + contacter à l'adresse <em>frederic@culot.org</em>. + </ul> + + +<a name="links"></a><h1>Liens</h1> +<p> + Cette section contient des liens en relation avec + <code>calcurse</code> qui peuvent vous être utiles. + + +<a name="links_homepage"></a><h2>Site internet de <code>calcurse</code></h2> +<p> + La page web de <code>calcurse</code> est à l'adresse suivante : + <pre> + http://culot.org/calcurse + </pre> + +<a name="links_list"></a><h2>Liste de diffusion de <code>calcurse</code></h2> +<p> + Si vous êtes interessé par ce projet et que vous souhaitez + être prévenu lorsqu'une nouvelle version est diffusée, vous + pouvez souscrire à la liste de diffusion de <code>calcurse</code>. + De cette manière, vous recevrez un mél dès qu'une nouvelle + version est disponible.<br> + Pour souscrire à cette liste, envoyez un message à l'adresse + <code>calcurse-announce@culot.org</code> avec "subscribe" dans + le sujet du mél. + + +<a name="thanks"></a><h1>Remerciements</a></h1> +<p> + Je voudrais remercier ici toutes les personnes sans qui ce projet + n'aurait jamais pu voir le jour! En particulier : + <ul> + <li>Alex pour ses patches, aides et conseils sur la programmation en + <code>C</code> + <li>Gwen pour les tests et les discussions sur la manière d'améliorer + <code>calcurse</code> + <li>Kevin et Ryan pour la maintenance du paquet <code>calcurse</code> + pour Debian + <li>Steffen pour la maintenance du paquet <code>calcurse</code> pour + Archlinux + <li>Alexandre pour la maintenance du paquet <code>calcurse</code> pour + Mac OsX + <li>Joel pour son script de calendrier qui a inspiré celui de + <code>calcurse</code> + <li>Michael Schulz pour la traduction allemande du manuel de <code>calcurse</code> + <li>les personnes qui écrivent des logiciels que j'apprécie et qui + m'ont inspiré lors de la conception de ce projet, en particulier : + <ul> + <li><code>vim</code> pour les touches de déplacement + <li><code>orpheus</code> et <code>abook</code> pour la documentation + <li><code>pine</code> et <code>aptitude</code> + pour l'interface en mode texte + </ul> + </ul> + Et pour terminer, un très grand merci à tous les utilisateurs de + <code>calcurse</code> qui m'ont fait parvenir leur commentaires. + +<hr> +<small><em> +Copyright (c) 2004-2006 Frédéric Culot<br> +Calcurse version 1.4 - Dernière modification: 7 Mai 2006 +<em></small> + + +</body> +</html> diff --git a/po/LINGUAS b/po/LINGUAS new file mode 100755 index 0000000..bc1af0a --- /dev/null +++ b/po/LINGUAS @@ -0,0 +1,4 @@ +# $calcurse: LINGUAS,v 1.1 2006/07/31 21:00:03 culot Exp $ +# +# Set of available languages. +fr diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100755 index 0000000..a59886e --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,14 @@ +# $calcurse: POTFILES.in,v 1.1 2006/07/31 21:00:03 culot Exp $ + +# List of source files which contain translatable strings. +src/apoint.c +src/args.c +src/calcurse.c +src/calendar.c +src/custom.c +src/event.c +src/help.c +src/io.c +src/todo.c +src/utils.c +src/vars.c diff --git a/po/calcurse.pot b/po/calcurse.pot new file mode 100755 index 0000000..60a34a7 --- /dev/null +++ b/po/calcurse.pot @@ -0,0 +1,760 @@ +# $calcurse: calcurse.pot,v 1.1 2006/07/31 21:00:04 culot Exp $ + +# Copyright (c) 2004-2006 Frederic Culot <frederic@culot.org> +# This file is distributed under the same license as the calcurse package. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: calcurse-i18n@culot.org\n" +"POT-Creation-Date: 2006-05-07 17:15+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/apoint.c:179 +msgid "FATAL ERROR in apoint_scan: date error in the appointment\n" +msgstr "" + +#: src/apoint.c:205 +msgid "FATAL ERROR in apoint_delete_bynum: no such appointment\n" +msgstr "" + +#: src/args.c:140 +msgid "" +"\n" +"Copyright (c) 2004-2006 Frederic Culot.\n" +"This is free software; see the source for copying conditions.\n" +msgstr "" + +#: src/args.c:143 src/args.c:169 +#, c-format +msgid "Calcurse %s - text-based organizer\n" +msgstr "" + +#: src/args.c:155 +msgid "" +"\n" +"Miscellaneous:\n" +" -h\t\tprint this help and exit.\n" +" -v\t\tprint calcurse version and exit.\n" +"\n" +"Options:\n" +" -c <file>\tspecify the calendar <file> to use.\n" +"\n" +"Non-interactive:\n" +" -a \t\tprint events and appointments for current day and exit.\n" +" -d <date|num>\tprint events and appointments for <date> or <num> upcoming\n" +"\t\tdays and exit.\n" +" -t\t\tprint todo list and exit.\n" +"\n" +"For more information, type '?' from within Calcurse, or read the manpage.\n" +"Mail bug reports and suggestions to <calcurse@culot.org>.\n" +msgstr "" + +#: src/args.c:184 +msgid "to do:\n" +msgstr "" + +#: src/args.c:299 +msgid "Argument to the '-d' flag is not valid\n" +msgstr "" + +#: src/args.c:300 +msgid "Possible argument formats are : 'mm/dd/yyyy' or 'n'\n" +msgstr "" + +#: src/args.c:301 +msgid "" +"\n" +"For more information, type '?' from within Calcurse, or read the manpage.\n" +msgstr "" + +#: src/args.c:303 +msgid "Mail bug reports and suggestions to <calcurse@culot.org>.\n" +msgstr "" + +#: src/args.c:370 +msgid "Usage: calcurse [-h | -v] [-at] [-d date|num] [-c file]\n" +msgstr "" + +#: src/args.c:378 +msgid "Try 'calcurse -h' for more information.\n" +msgstr "" + +#: src/calcurse.c:127 +msgid "" +"Sorry, colors are not supported by your terminal\n" +"(Press [ENTER] to continue)" +msgstr "" + +#: src/calcurse.c:129 +msgid "Do you really want to quit ?" +msgstr "" + +#: src/calcurse.c:200 +msgid "" +"Please resize your terminal screen\n" +"(to at least 80x24),\n" +"and restart calcurse.\n" +msgstr "" + +#: src/calcurse.c:260 +msgid "Event :" +msgstr "" + +#: src/calcurse.c:263 +msgid "Appointment :" +msgstr "" + +#: src/calcurse.c:267 +msgid "To do :" +msgstr "" + +#: src/calcurse.c:537 +msgid "FATAL ERROR in update_windows: no window selected\n" +msgstr "" + +#: src/calcurse.c:617 +#, c-format +msgid "Calendar" +msgstr "" + +#: src/calcurse.c:620 +#, c-format +msgid "Appointments" +msgstr "" + +#: src/calcurse.c:623 +#, c-format +msgid "ToDo" +msgstr "" + +#: src/calcurse.c:655 +msgid "Enter an option number to change its value [Q to quit] " +msgstr "" + +#: src/calcurse.c:661 +#, c-format +msgid "CalCurse %s | general options" +msgstr "" + +#: src/calcurse.c:698 +msgid "auto_save = " +msgstr "" + +#: src/calcurse.c:699 +msgid "confirm_quit = " +msgstr "" + +#: src/calcurse.c:700 +msgid "confirm_delete = " +msgstr "" + +#: src/calcurse.c:701 +msgid "skip_system_dialogs = " +msgstr "" + +#: src/calcurse.c:702 +msgid "skip_progress_bar = " +msgstr "" + +#: src/calcurse.c:703 +msgid "week_begins_on_monday = " +msgstr "" + +#: src/calcurse.c:712 +msgid "(if set to YES, automatic save is done when quitting)" +msgstr "" + +#: src/calcurse.c:718 +msgid "(if set to YES, confirmation is required before quitting)" +msgstr "" + +#: src/calcurse.c:724 +msgid "(if set to YES, confirmation is required before deleting an event)" +msgstr "" + +#: src/calcurse.c:730 +msgid "" +"(if set to YES, messages about loaded and saved data will not be displayed)" +msgstr "" + +#: src/calcurse.c:736 +msgid "(if set to YES, progress bar will not be displayed when saving data)" +msgstr "" + +#: src/calcurse.c:742 +msgid "(if set to YES, monday is the first day of the week, else it is sunday)" +msgstr "" + +#: src/calcurse.c:757 +msgid "yes" +msgstr "" + +#: src/calcurse.c:760 +msgid "no" +msgstr "" + +#: src/calcurse.c:764 +msgid "option not defined - Problem in print_option_incolor()" +msgstr "" + +#: src/calcurse.c:781 +msgid "Do you really want to delete this item ?" +msgstr "" + +#: src/calcurse.c:782 +msgid "Do you really want to delete this task ?" +msgstr "" + +#: src/calcurse.c:854 +msgid "Enter the new ToDo item : " +msgstr "" + +#: src/calcurse.c:875 +msgid "" +"Enter start time ([hh:mm] or [h:mm]), leave blank for an all-day event : " +msgstr "" + +#: src/calcurse.c:876 +msgid "Enter end time ([hh:mm] or [h:mm]) or duration (in minutes) : " +msgstr "" + +#: src/calcurse.c:877 +msgid "Enter description :" +msgstr "" + +#: src/calcurse.c:878 +msgid "You entered an invalid start time, should be [h:mm] or [hh:mm]" +msgstr "" + +#: src/calcurse.c:879 +msgid "You entered an invalid end time, should be [h:mm] or [hh:mm] or [mm]" +msgstr "" + +#: src/calcurse.c:880 +msgid "Press [Enter] to continue" +msgstr "" + +#: src/calcurse.c:1137 +msgid "Failed to open config file" +msgstr "" + +#: src/calcurse.c:1138 src/calendar.c:204 src/io.c:131 src/io.c:305 +#: src/io.c:377 +msgid "Press [ENTER] to continue" +msgstr "" + +#: src/calcurse.c:1214 +msgid "FATAL ERROR in fill_config_var: wrong configuration variable format.\n" +msgstr "" + +#: src/calendar.c:203 +msgid "The day you entered is not valid" +msgstr "" + +#: src/calendar.c:205 +msgid "Enter the day to go to [ENTER for today] : dd/mm/yyyy" +msgstr "" + +#: src/custom.c:94 +msgid "Exit" +msgstr "" + +#: src/custom.c:95 +msgid "General" +msgstr "" + +#: src/custom.c:96 +msgid "Layout" +msgstr "" + +#: src/custom.c:97 +msgid "Color" +msgstr "" + +#: src/custom.c:108 +msgid "Pick the desired layout on next screen [press ENTER]" +msgstr "" + +#: src/custom.c:109 +msgid "('A'= Appointment panel, 'c'= calendar panel, 't'= todo panel)" +msgstr "" + +#: src/custom.c:110 +msgid " |Ac| |At| |cA| |tA|" +msgstr "" + +#: src/custom.c:111 +msgid "[1]|At| [2]|Ac| [3]|tA| [4]|cA|" +msgstr "" + +#: src/custom.c:146 +msgid "Pick the number corresponding to the color scheme (Q to exit) :" +msgstr "" + +#: src/custom.c:156 +msgid "([>0<] for black & white)" +msgstr "" + +#: src/event.c:161 +msgid "FATAL ERROR in event_scan: date error in the event\n" +msgstr "" + +#: src/event.c:188 +msgid "FATAL ERROR in event_delete_bynum: no such event\n" +msgstr "" + +#: src/help.c:95 +msgid " Welcome to Calcurse. This is the main help screen.\n" +msgstr "" + +#: src/help.c:97 +msgid "" +" Moving around: Press CTRL-P or CTRL-N to scroll text upward or\n" +" downward inside help screens, if necessary.\n" +"\n" +" Exit help: When finished, press 'Q' to exit help and go back\n" +" to the main Calcurse screen.\n" +"\n" +" Help topic: At the bottom of this screen you can see a panel\n" +" with different fields, represented by a letter and\n" +" a short title. This panel contains all the available\n" +" actions you can perform when using Calcurse.\n" +" By pressing one of the letters appearing in this\n" +" panel, you will be shown a short description of the\n" +" corresponding action.\n" +"\n" +" Credits: Press '@' for credits." +msgstr "" + +#: src/help.c:110 +msgid "Redraw:\n" +msgstr "" + +#: src/help.c:112 +msgid "" +"Pressing 'R' redraws the Calcurse panels.\n" +"\n" +"You might want to use this function when you resize your terminal\n" +"screen for example, and you want Calcurse to take into account the new\n" +"size of the terminal.\n" +"\n" +"This function can also be useful when garbage appears in the display,\n" +"and you want to clean it." +msgstr "" + +#: src/help.c:119 +msgid "Save:\n" +msgstr "" + +#: src/help.c:121 +msgid "" +"Pressing 'S' saves the Calcurse data.\n" +"\n" +"The data is splitted into three different files which contains :\n" +"\n" +" / ~/.calcurse/conf -> the user configuration\n" +" | (layout, color, general options)\n" +" | ~/.calcurse/apts -> the data related to the appointments\n" +" \\ ~/.calcurse/todo -> the data related to the todo list\n" +"\n" +"In the config menu, you can choose to save the Calcurse data\n" +"automatically before quitting." +msgstr "" + +#: src/help.c:131 +msgid "Displacement keys:\n" +msgstr "" + +#: src/help.c:133 +msgid "" +"You can use either 'H','J','K','L' or the arrow keys '<','v','^','>'\n" +"to move into the calendar.\n" +"\n" +"The following scheme explains how :\n" +"\n" +" move to previous week\n" +" K ^ \n" +" move to previous day H < > L move to next day\n" +" J v \n" +" move to next week\n" +"\n" +"When the Appointment or ToDo panel is selected, the up and down keys\n" +"(respectively K or up arrow, and J or down arrow) allows you to select\n" +"an item from those lists." +msgstr "" + +#: src/help.c:145 +msgid "View:\n" +msgstr "" + +#: src/help.c:147 +msgid "" +"Pressing 'V' allows you to view the item you select in either the ToDo\n" +"or Appointment panel.\n" +"\n" +"This is usefull when an event description is longer than the available\n" +"space to display it. If that is the case, the description will be\n" +"shortened and its end replaced by '...'. To be able to read the entire\n" +"description, just press 'V' and a popup window will appear, containing\n" +"the whole event.\n" +"\n" +"Press any key to close the popup window and go back to the main\n" +"Calcurse screen." +msgstr "" + +#: src/help.c:157 +msgid "Tab:\n" +msgstr "" + +#: src/help.c:159 +msgid "" +"Pressing 'Tab' allows you to switch between panels.\n" +"The panel currently in use has its border colorized.\n" +"\n" +"Some actions are possible only if the right panel is selected.\n" +"For example, if you want to add a task in the TODO list, you need first\n" +"to press the 'Tab' key to get the TODO panel selected. Then you can\n" +"press 'A' to add your item.\n" +"\n" +"Notice that at the bottom of the screen the list of possible actions\n" +"change while pressing 'Tab', so you always know what action can be\n" +"performed on the selected panel." +msgstr "" + +#: src/help.c:169 +msgid "Goto:\n" +msgstr "" + +#: src/help.c:171 +msgid "" +"Pressing 'G' allows you to jump to a specific day in the calendar.\n" +"\n" +"Using this command, you do not need to travel to that day using\n" +"the displacement keys inside the calendar panel.\n" +"If you hit [ENTER] without specifying any date, Calcurse checks the\n" +"system current date and you will be taken to that date." +msgstr "" + +#: src/help.c:177 +msgid "Delete:\n" +msgstr "" + +#: src/help.c:179 +msgid "" +"Pressing 'D' deletes an element in the ToDo or Appointment list.\n" +"\n" +"Depending on which panel is selected when you press the delete key,\n" +"the hilighted item of either the ToDo or Appointment list will be \n" +"removed from this list.\n" +"\n" +"If the general option 'confirm_delete' is set to 'YES', then you will\n" +"be asked for confirmation before deleting the selected event.\n" +"Do not forget to save the calendar data to retrieve the modifications\n" +"next time you launch Calcurse." +msgstr "" + +#: src/help.c:188 +msgid "Add:\n" +msgstr "" + +#: src/help.c:190 +msgid "" +"Pressing 'A' allows you to add an item in either the ToDo or Appointment\n" +"list, depending on which panel is selected when you press 'A'.\n" +"\n" +"To enter a new item in the TODO list, you only need to enter the\n" +"description of this new item.\n" +"\n" +"If the APPOINTMENT panel is selected while pressing 'A', you will be\n" +"able to enter either a new appointment or a new all-day long event.\n" +"To enter a new event, press [ENTER] instead of the item start time, and\n" +"just fill in the event description.\n" +"To enter a new appointment to be added in the APPOINTMENT list, you\n" +"will need to enter successively the time at which the appointment\n" +"begins, the appointment length (either by specifying the duration in\n" +"minutes, or the end time in [hh:mm] or [h:mm] format), and the\n" +"description of the event.\n" +"\n" +"The day at which occurs the event or appointment is the day currently\n" +"selected in the calendar, so you need to move to the desired day before\n" +"pressing 'A'.\n" +"\n" +"Notes:\n" +" o if an appointment lasts for such a long time that it continues\n" +" on the next days, this event will be indicated on all the\n" +" corresponding days, and the beginning or ending hour will be\n" +" replaced by '..' if the event does not begin or end on the day.\n" +" o if you only press [ENTER] at the APPOINTMENT or TODO event\n" +" description prompt, without any description, no item will be\n" +" added.\n" +" o do not forget to save the calendar data to retrieve the new\n" +" event next time you launch Calcurse." +msgstr "" + +#: src/help.c:217 +msgid "Config:\n" +msgstr "" + +#: src/help.c:219 +msgid "" +"Pressing 'C' leads to the configuration submenu, from which you can\n" +"select between color, layout, and general options.\n" +"\n" +"The color submenu lets you choose the color theme.\n" +"\n" +"The layout submenu lets you choose the Calcurse screen layout, in other\n" +"words where to place the three different panels on the screen.\n" +"\n" +"The general options submenu brings a screen with the different options\n" +"which modifies the way Calcurse interacts with the user.\n" +"\n" +"Do not forget to save the calendar data to retrieve your configuration\n" +"next time you launch Calcurse." +msgstr "" + +#: src/help.c:229 +msgid "Calcurse - text-based organizer" +msgstr "" + +#: src/help.c:231 +msgid "" +"Copyright (c) 2004-2006 Frederic Culot\n" +"\n" +"This program is free software; you can redistribute it and/or modify\n" +"it under the terms of the GNU General Public License as published by\n" +"the Free Software Foundation; either version 2 of the License, or\n" +"(at your option) any later version.\n" +"\n" +"This program is distributed in the hope that it will be useful,\n" +"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +"GNU General Public License for more details.\n" +"\n" +"\n" +"Send your feedback or comments to : calcurse@culot.org\n" +"Calcurse home page : http://culot.org/calcurse" +msgstr "" + +#: src/help.c:252 +#, c-format +msgid "CalCurse %s | help" +msgstr "" + +#: src/io.c:74 +#, c-format +msgid "%s does not exist, create it now [y or n] ? " +msgstr "" + +#: src/io.c:79 src/io.c:96 +#, c-format +msgid "aborting...\n" +msgstr "" + +#: src/io.c:90 +#, c-format +msgid "%s successfully created\n" +msgstr "" + +#: src/io.c:91 +#, c-format +msgid "starting interactive mode...\n" +msgstr "" + +#: src/io.c:127 +msgid "Problems accessing data file ..." +msgstr "" + +#: src/io.c:130 +msgid "The data files were successfully saved" +msgstr "" + +#: src/io.c:259 +msgid "FATAL ERROR in load_app: syntax error in the item date\n" +msgstr "" + +#: src/io.c:274 +msgid "FATAL ERROR in load_app: no event nor appointment found\n" +msgstr "" + +#: src/io.c:291 +msgid "FATAL ERROR in load_app: wrong format in the appointment or event\n" +msgstr "" + +#: src/io.c:304 +msgid "Failed to open todo file" +msgstr "" + +#: src/io.c:375 +msgid "Welcome to Calcurse. Missing data files were created." +msgstr "" + +#: src/io.c:376 +msgid "Data files found. Data will be loaded now." +msgstr "" + +#: src/io.c:392 +msgid "Saving..." +msgstr "" + +#: src/io.c:393 +msgid "Loading..." +msgstr "" + +#: src/todo.c:76 +msgid "FATAL ERROR in todo_delete_bynum: no such todo\n" +msgstr "" + +#: src/utils.c:74 +msgid "Press any key to continue..." +msgstr "" + +#: src/utils.c:232 +msgid "-- Press 'N' for next page --" +msgstr "" + +#: src/utils.c:233 +msgid "-- Press 'P' for previous page --" +msgstr "" + +#: src/utils.c:368 src/utils.c:399 +msgid "Help" +msgstr "" + +#: src/utils.c:369 src/utils.c:400 +msgid "Quit" +msgstr "" + +#: src/utils.c:371 src/utils.c:402 +msgid "Redraw" +msgstr "" + +#: src/utils.c:372 src/utils.c:403 +msgid "Save" +msgstr "" + +#: src/utils.c:374 +msgid "-/+1 Day" +msgstr "" + +#: src/utils.c:376 +msgid "-/+1 Week" +msgstr "" + +#: src/utils.c:378 src/utils.c:413 +msgid "GoTo" +msgstr "" + +#: src/utils.c:380 src/utils.c:407 +msgid "Chg View" +msgstr "" + +#: src/utils.c:382 src/utils.c:417 +msgid "Config" +msgstr "" + +#: src/utils.c:405 +msgid "Up/Down" +msgstr "" + +#: src/utils.c:409 +msgid "Add Item" +msgstr "" + +#: src/utils.c:411 +msgid "Del Item" +msgstr "" + +#: src/utils.c:415 +msgid "View" +msgstr "" + +#: src/utils.c:443 +msgid "FATAL ERROR in date2sec: failure in mktime\n" +msgstr "" + +#: src/utils.c:567 +msgid "Appointment" +msgstr "" + +#: src/vars.c:41 +msgid "January" +msgstr "" + +#: src/vars.c:42 +msgid "February" +msgstr "" + +#: src/vars.c:43 +msgid "March" +msgstr "" + +#: src/vars.c:44 +msgid "April" +msgstr "" + +#: src/vars.c:45 +msgid "May" +msgstr "" + +#: src/vars.c:46 +msgid "June" +msgstr "" + +#: src/vars.c:47 +msgid "July" +msgstr "" + +#: src/vars.c:48 +msgid "August" +msgstr "" + +#: src/vars.c:49 +msgid "September" +msgstr "" + +#: src/vars.c:50 +msgid "October" +msgstr "" + +#: src/vars.c:51 +msgid "November" +msgstr "" + +#: src/vars.c:52 +msgid "December" +msgstr "" + +#: src/vars.c:55 src/vars.c:62 +msgid "Sun" +msgstr "" + +#: src/vars.c:56 +msgid "Mon" +msgstr "" + +#: src/vars.c:57 +msgid "Tue" +msgstr "" + +#: src/vars.c:58 +msgid "Wed" +msgstr "" + +#: src/vars.c:59 +msgid "Thu" +msgstr "" + +#: src/vars.c:60 +msgid "Fri" +msgstr "" + +#: src/vars.c:61 +msgid "Sat" +msgstr "" diff --git a/po/fr.po b/po/fr.po new file mode 100755 index 0000000..812a4b9 --- /dev/null +++ b/po/fr.po @@ -0,0 +1,966 @@ +# French translations for calcurse package. +# Copyright (C) 2006 Frederic Culot <frederic@culot.org> +# This file is distributed under the same license as the calcurse package. +# Frederic Culot <frederic@culot.org>, 2006. +# +msgid "" +msgstr "" +"Project-Id-Version: calcurse 1.4\n" +"Report-Msgid-Bugs-To: calcurse-i18n@culot.org\n" +"POT-Creation-Date: 2006-05-07 17:15+0200\n" +"PO-Revision-Date: 2006-05-13 14:37+0200\n" +"Last-Translator: Frederic Culot <frederic@culot.org>\n" +"Language-Team: French <calcurse-i18n@culot.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: src/apoint.c:179 +msgid "FATAL ERROR in apoint_scan: date error in the appointment\n" +msgstr "" +"ERREUR FATALE dans apoint_scan: un rendez-vous contient une date erronée\n" + +#: src/apoint.c:205 +msgid "FATAL ERROR in apoint_delete_bynum: no such appointment\n" +msgstr "ERREUR FATALE dans apoint_delete_bynum: l'élement n'existe pas\n" + +#: src/args.c:140 +msgid "" +"\n" +"Copyright (c) 2004-2006 Frederic Culot.\n" +"This is free software; see the source for copying conditions.\n" +msgstr "" +"\n" +"Copyright (c) 2004-2006 Frédéric Culot.\n" +"Ceci est un logiciel libre; voir les sources pour les conditions de " +"diffusion.\n" + +#: src/args.c:143 src/args.c:169 +#, c-format +msgid "Calcurse %s - text-based organizer\n" +msgstr "Calcurse %s - organiseur personnel en mode texte\n" + +#: src/args.c:155 +msgid "" +"\n" +"Miscellaneous:\n" +" -h\t\tprint this help and exit.\n" +" -v\t\tprint calcurse version and exit.\n" +"\n" +"Options:\n" +" -c <file>\tspecify the calendar <file> to use.\n" +"\n" +"Non-interactive:\n" +" -a \t\tprint events and appointments for current day and exit.\n" +" -d <date|num>\tprint events and appointments for <date> or <num> upcoming\n" +"\t\tdays and exit.\n" +" -t\t\tprint todo list and exit.\n" +"\n" +"For more information, type '?' from within Calcurse, or read the manpage.\n" +"Mail bug reports and suggestions to <calcurse@culot.org>.\n" +msgstr "" +"\n" +"Divers:\n" +" -h\\t\\tafficher cette aide et quitter.\n" +" -v\\t\\tafficher la version de calcurse et quitter.\n" +"\n" +"Options:\n" +" -c <fichier>\\tspécifier le <fichier> calendrier à utiliser.\n" +"\n" +"Non-intéractif:\n" +" -a \\t\\tafficher les rendez-vous et évenements de la journée et quitter.\n" +" -d <date|nb>\\tafficher les rendez-vous et évenements pour la <date> ou " +"les <nb>\n" +"\\t\\tjours à venir.\n" +" -t\\t\\tafficher la liste des tâches et quitter.\n" +"\n" +"Pour plus d'informations, tapez '?' dans Calcurse, ou lisez la page de " +"manuel.\n" +"Envoyez vos rapports de bogues et suggestions à <calcurse@culot.org>.\n" + +#: src/args.c:184 +msgid "to do:\n" +msgstr "à faire:\n" + +#: src/args.c:299 +msgid "Argument to the '-d' flag is not valid\n" +msgstr "L'argument de l'option '-d' n'est pas valide\n" + +#: src/args.c:300 +msgid "Possible argument formats are : 'mm/dd/yyyy' or 'n'\n" +msgstr "Les formats autorisés sont : 'mm/jj/aaaa' ou 'n'\n" + +#: src/args.c:301 +msgid "" +"\n" +"For more information, type '?' from within Calcurse, or read the manpage.\n" +msgstr "" +"\n" +"Pour plus d'informations, tapez '?' dans Calcurse, ou lisez la page de " +"manuel.\n" + +#: src/args.c:303 +msgid "Mail bug reports and suggestions to <calcurse@culot.org>.\n" +msgstr "Envoyez vos rapports de bogues ou suggestions à <calcurse@culot.org>\n" + +#: src/args.c:370 +msgid "Usage: calcurse [-h | -v] [-at] [-d date|num] [-c file]\n" +msgstr "Utilisation: calcurse [-h | -v] [-at] [-d date|nb] [-c fichier]\n" + +#: src/args.c:378 +msgid "Try 'calcurse -h' for more information.\n" +msgstr "Tapez 'calcurse -h' pour plus d'informations.\n" + +#: src/calcurse.c:127 +msgid "" +"Sorry, colors are not supported by your terminal\n" +"(Press [ENTER] to continue)" +msgstr "" +"Désolé, les couleurs ne sont pas supportées par votre terminal\n" +"(Appuyez sur [ENTREE] pour continuer)" + +#: src/calcurse.c:129 +msgid "Do you really want to quit ?" +msgstr "Voulez-vous vraiment quitter ?" + +#: src/calcurse.c:200 +msgid "" +"Please resize your terminal screen\n" +"(to at least 80x24),\n" +"and restart calcurse.\n" +msgstr "" +"Redimensionnez votre terminal\n" +"(au moins 80x24),\n" +"et relancez calcurse.\n" + +#: src/calcurse.c:260 +msgid "Event :" +msgstr "Evénement :" + +#: src/calcurse.c:263 +msgid "Appointment :" +msgstr "Rendez-vous :" + +#: src/calcurse.c:267 +msgid "To do :" +msgstr "Tâche :" + +#: src/calcurse.c:537 +msgid "FATAL ERROR in update_windows: no window selected\n" +msgstr "ERREUR FATALE dans update_windows: aucune fenêtre séléctionnée\n" + +#: src/calcurse.c:617 +#, c-format +msgid "Calendar" +msgstr "Calendrier" + +#: src/calcurse.c:620 +#, c-format +msgid "Appointments" +msgstr "Rendez-vous" + +#: src/calcurse.c:623 +#, c-format +msgid "ToDo" +msgstr "Tâches" + +#: src/calcurse.c:655 +msgid "Enter an option number to change its value [Q to quit] " +msgstr "Entrez un numéro d'option pour changer sa valeur [Q pour quitter] " + +#: src/calcurse.c:661 +#, c-format +msgid "CalCurse %s | general options" +msgstr "CalCurse %s | options générales" + +#: src/calcurse.c:698 +msgid "auto_save = " +msgstr "sauvegarde_automatique = " + +#: src/calcurse.c:699 +msgid "confirm_quit = " +msgstr "confirmer_pour_quitter = " + +#: src/calcurse.c:700 +msgid "confirm_delete = " +msgstr "confirmer_pour_effacer = " + +#: src/calcurse.c:701 +msgid "skip_system_dialogs = " +msgstr "masquer_messages_système = " + +#: src/calcurse.c:702 +msgid "skip_progress_bar = " +msgstr "masquer_barre_progression = " + +#: src/calcurse.c:703 +msgid "week_begins_on_monday = " +msgstr "semaine_commence_lundi = " + +#: src/calcurse.c:712 +msgid "(if set to YES, automatic save is done when quitting)" +msgstr "" +"(si fixé à OUI, une sauvegarde est automatiquement effectuée en quittant)" + +#: src/calcurse.c:718 +msgid "(if set to YES, confirmation is required before quitting)" +msgstr "(si fixé à OUI, il est nécessaire de confirmer pour quitter)" + +#: src/calcurse.c:724 +msgid "(if set to YES, confirmation is required before deleting an event)" +msgstr "" +"(si fixé à OUI, il est nécessaire de confirmer pour effacer un élement)" + +#: src/calcurse.c:730 +msgid "" +"(if set to YES, messages about loaded and saved data will not be displayed)" +msgstr "(si fixé à OUI, les messages d'accès fichiers ne seront pas affichés)" + +#: src/calcurse.c:736 +msgid "(if set to YES, progress bar will not be displayed when saving data)" +msgstr "(si fixé à OUI, la barre ne sera pas affichée lors des sauvegardes)" + +#: src/calcurse.c:742 +msgid "(if set to YES, monday is the first day of the week, else it is sunday)" +msgstr "" +"(si fixé à OUI, la semaine débute le lundi, sinon elle débute le dimanche)" + +#: src/calcurse.c:757 +msgid "yes" +msgstr "oui" + +#: src/calcurse.c:760 +msgid "no" +msgstr "non" + +#: src/calcurse.c:764 +msgid "option not defined - Problem in print_option_incolor()" +msgstr "Problème dans print_option_incolor(): option non définié" + +#: src/calcurse.c:781 +msgid "Do you really want to delete this item ?" +msgstr "Voulez-vous vraiment effacer cet élement ?" + +#: src/calcurse.c:782 +msgid "Do you really want to delete this task ?" +msgstr "Voulez-vous vraiment effacer cette tâche ?" + +#: src/calcurse.c:854 +msgid "Enter the new ToDo item : " +msgstr "Entrez la nouvelle tâche : " + +#: src/calcurse.c:875 +msgid "" +"Enter start time ([hh:mm] or [h:mm]), leave blank for an all-day event : " +msgstr "" +"Entrez l'heure de début ([hh:mm] ou [h:mm]), laissez vide pour toute la " +"journée:" + +#: src/calcurse.c:876 +msgid "Enter end time ([hh:mm] or [h:mm]) or duration (in minutes) : " +msgstr "Entrez l'heure de fin ([hh:mm] ou [h:mm]) ou la durée (en minutes):" + +#: src/calcurse.c:877 +msgid "Enter description :" +msgstr "Entrez la description :" + +#: src/calcurse.c:878 +msgid "You entered an invalid start time, should be [h:mm] or [hh:mm]" +msgstr "Erreur dans le format de l'heure de début: doit être [h:mm] ou [hh:mm]" + +#: src/calcurse.c:879 +msgid "You entered an invalid end time, should be [h:mm] or [hh:mm] or [mm]" +msgstr "" +"Erreur dans le format de l'heure de fin: doit être [h:mm] ou [hh:mm] ou [mm]" + +#: src/calcurse.c:880 +msgid "Press [Enter] to continue" +msgstr "Appuyez sur [ENTREE] pour continuer" + +#: src/calcurse.c:1137 +msgid "Failed to open config file" +msgstr "Impossible d'ouvrir le fichier de configuration" + +#: src/calcurse.c:1138 src/calendar.c:204 src/io.c:131 src/io.c:305 +#: src/io.c:377 +msgid "Press [ENTER] to continue" +msgstr "Appuyez sur [ENTREE] pour continuer" + +#: src/calcurse.c:1214 +msgid "FATAL ERROR in fill_config_var: wrong configuration variable format.\n" +msgstr "" +"ERREUR FATALE dans fill_config_var: mauvais format dans la variable de " +"configuration.\n" + +#: src/calendar.c:203 +msgid "The day you entered is not valid" +msgstr "Le jour que vous avez entré n'est pas valide" + +#: src/calendar.c:205 +msgid "Enter the day to go to [ENTER for today] : dd/mm/yyyy" +msgstr "Entrez la journée voulue [ENTREE pour aujourd'hui] : jj/mm/aaaa" + +#: src/custom.c:94 +msgid "Exit" +msgstr "Quitter" + +#: src/custom.c:95 +msgid "General" +msgstr "Général" + +#: src/custom.c:96 +msgid "Layout" +msgstr "Ecran" + +#: src/custom.c:97 +msgid "Color" +msgstr "Couleur" + +#: src/custom.c:108 +msgid "Pick the desired layout on next screen [press ENTER]" +msgstr "Choisissez la disposition voulue dans l'écran suivant [pressez ENTREE]" + +#: src/custom.c:109 +msgid "('A'= Appointment panel, 'c'= calendar panel, 't'= todo panel)" +msgstr "" +"('R'= panneau Rendez-vous, 'c'= panneau Calendrier, 't'= panneau Tâches)" + +#: src/custom.c:110 +msgid " |Ac| |At| |cA| |tA|" +msgstr " |Rc| |Rt| |cR| |tR|" + +#: src/custom.c:111 +msgid "[1]|At| [2]|Ac| [3]|tA| [4]|cA|" +msgstr "[1]|Rt| [2]|Rc| [3]|tR| [4]|cR|" + +#: src/custom.c:146 +msgid "Pick the number corresponding to the color scheme (Q to exit) :" +msgstr "" +"Choississez le numéro correspondant au thème graphique voulu (Q pour " +"quitter) :" + +#: src/custom.c:156 +msgid "([>0<] for black & white)" +msgstr "([>O<]) pour noir & blanc)" + +#: src/event.c:161 +msgid "FATAL ERROR in event_scan: date error in the event\n" +msgstr "ERREUR FATALE dans event_scan: date erronée dans l'évenement\n" + +#: src/event.c:188 +msgid "FATAL ERROR in event_delete_bynum: no such event\n" +msgstr "ERREUR FATALE dans event_delete_bynum: aucun évenement correspondant\n" + +#: src/help.c:95 +msgid " Welcome to Calcurse. This is the main help screen.\n" +msgstr " Bienvenue dans Calcurse. Vous êtes dans l'écran principal.\n" + +#: src/help.c:97 +msgid "" +" Moving around: Press CTRL-P or CTRL-N to scroll text upward or\n" +" downward inside help screens, if necessary.\n" +"\n" +" Exit help: When finished, press 'Q' to exit help and go back\n" +" to the main Calcurse screen.\n" +"\n" +" Help topic: At the bottom of this screen you can see a panel\n" +" with different fields, represented by a letter and\n" +" a short title. This panel contains all the available\n" +" actions you can perform when using Calcurse.\n" +" By pressing one of the letters appearing in this\n" +" panel, you will be shown a short description of the\n" +" corresponding action.\n" +"\n" +" Credits: Press '@' for credits." +msgstr "" +" Se déplacer: Appuyez sur CTRL-P ou CTRL-N pour déplacer le texte \n" +" vers le haut ou le bas à l'intérieur des écrans \n" +" d'aide, si nécessaire.\n" +"\n" +"Sortir de l'aide: Appuyez sur 'Q' pour sortir de l'aide et revenir à \n" +" l'écran principal de Calcurse.\n" +"\n" +"Rubriques d'aide: Au bas de l'écran vous pouvez voir un panneau avec \n" +" différents champs, représentés par une lettre et une \n" +" courte déscription.\n" +" Ce panneau contient toutes les actions accessibles \n" +" dans l'écran en cours.\n" +" En appuyant sur l'une des lettres de ce panneau, \n" +" vous obtiendrez une courte description de l'action \n" +" correspondante.\n" +"\n" +" Auteurs: Appuyez sur '@' pour obtenir l'écran présentant les \n" +" auteurs de Calcurse." + +#: src/help.c:110 +msgid "Redraw:\n" +msgstr "Retracer:\n" + +#: src/help.c:112 +msgid "" +"Pressing 'R' redraws the Calcurse panels.\n" +"\n" +"You might want to use this function when you resize your terminal\n" +"screen for example, and you want Calcurse to take into account the new\n" +"size of the terminal.\n" +"\n" +"This function can also be useful when garbage appears in the display,\n" +"and you want to clean it." +msgstr "" +"Appuyer sur 'R' redessine l'écran de Calcurse.\n" +"\n" +"Vous pouvez utiliser cette fonction par exemple après le \n" +"redimensionnement de votre terminal, pour prendre en compte la nouvelle \n" +"dimension de celui-ci.\n" +"\n" +"Cette fonction peut également être utile lorsque des caractères \n" +"parasites apparaîssent sur l'écran et que vous voulez les \n" +"supprimer." + +#: src/help.c:119 +msgid "Save:\n" +msgstr "Sauvegarde:\n" + +#: src/help.c:121 +msgid "" +"Pressing 'S' saves the Calcurse data.\n" +"\n" +"The data is splitted into three different files which contains :\n" +"\n" +" / ~/.calcurse/conf -> the user configuration\n" +" | (layout, color, general options)\n" +" | ~/.calcurse/apts -> the data related to the appointments\n" +" \\ ~/.calcurse/todo -> the data related to the todo list\n" +"\n" +"In the config menu, you can choose to save the Calcurse data\n" +"automatically before quitting." +msgstr "" +"Appuyer sur 'S' permet de sauvegarder vos données.\n" +"\n" +"Celles-ci sont séparées dans trois fichiers différents qui contiennent :\n" +"\n" +" / ~/.calcurse/conf -> la configuration de l'utilisateur\n" +" | (disposition, couleurs, options générales)\n" +" | ~/.calcurse/apts -> les données relatives aux rendez-vous\n" +" \\ ~/.calcurse/todo -> les données relatives aux tâches\n" +"\n" +"Dans le menu de configuration, vous pouvez choisir de sauvegarder les\n" +"données automatiquement avant de quitter." + +#: src/help.c:131 +msgid "Displacement keys:\n" +msgstr "Touches de déplacement:\n" + +#: src/help.c:133 +msgid "" +"You can use either 'H','J','K','L' or the arrow keys '<','v','^','>'\n" +"to move into the calendar.\n" +"\n" +"The following scheme explains how :\n" +"\n" +" move to previous week\n" +" K ^ \n" +" move to previous day H < > L move to next day\n" +" J v \n" +" move to next week\n" +"\n" +"When the Appointment or ToDo panel is selected, the up and down keys\n" +"(respectively K or up arrow, and J or down arrow) allows you to select\n" +"an item from those lists." +msgstr "" +"Vous pouvez utiliser soit 'H','J','K','L', soit les touches fléchées\n" +"'<','v','^',>' pour vous déplacer dans le calendrier.\n" +"\n" +"Le schéma suivant explique comment :\n" +"\n" +" aller à la semaine précédente\n" +" K ^ \n" +"aller au jour précédent H < > L aller au jour suivant\n" +" J v \n" +" aller à la semaine suivante\n" +"\n" +"Lorsque le panneau des rendez-vous ou celui des tâches est séléctionné,\n" +"les touches haut et bas (respectivement K ou flèche haut, et J ou\n" +"flèche bas) vous permettent de séléctionner un élément de ce panneau." + +#: src/help.c:145 +msgid "View:\n" +msgstr "Visualiser:\n" + +#: src/help.c:147 +msgid "" +"Pressing 'V' allows you to view the item you select in either the ToDo\n" +"or Appointment panel.\n" +"\n" +"This is usefull when an event description is longer than the available\n" +"space to display it. If that is the case, the description will be\n" +"shortened and its end replaced by '...'. To be able to read the entire\n" +"description, just press 'V' and a popup window will appear, containing\n" +"the whole event.\n" +"\n" +"Press any key to close the popup window and go back to the main\n" +"Calcurse screen." +msgstr "" +"Appuyer sur 'V' vous permet de visualiser l'élément en surbrillance\n" +"dans le panneau des tâches ou des rendez-vous.\n" +"\n" +"Cette commande est utile lorsque la déscription de cet élément est\n" +"trop longue pour être affichée dans l'écran principal. Si tel est\n" +"le cas, la description sera raccourcie et la fin remplacée par '...'.\n" +"Pour visualiser entièrement le texte, appuyez sur 'V' et une fenêtre\n" +"sera affichée avec la description complète de l'élément.\n" +"\n" +"Appuyez sur n'importe quelle touche pour fermer la fenêtre contenant \n" +"la description de l'élément et revenir à l'affichage principal de\n" +"Calcurse." + +#: src/help.c:157 +msgid "Tab:\n" +msgstr "Tabulation:\n" + +#: src/help.c:159 +msgid "" +"Pressing 'Tab' allows you to switch between panels.\n" +"The panel currently in use has its border colorized.\n" +"\n" +"Some actions are possible only if the right panel is selected.\n" +"For example, if you want to add a task in the TODO list, you need first\n" +"to press the 'Tab' key to get the TODO panel selected. Then you can\n" +"press 'A' to add your item.\n" +"\n" +"Notice that at the bottom of the screen the list of possible actions\n" +"change while pressing 'Tab', so you always know what action can be\n" +"performed on the selected panel." +msgstr "" +"Appuyer sur 'Tab' permet de séléctionner circulairement un des\n" +"panneaux de l'affichage principal de Calcurse. Le panneau actuellement\n" +"séléctionné est reconnaissable par sa bordure en couleur.\n" +"\n" +"Certaines actions ne sont possibles que si le panneau approprié est\n" +"séléctionné.\n" +"Par exemple, si vous voulez ajouter un élément à la liste des tâches,\n" +"vous devez tout d'abord presser 'Tab' autant de fois que nécessaire\n" +"pour séléctionner le panneau des tâches. Ensuite vous pouvez appuyer\n" +"sur 'A' pour ajouter un élément à cette liste.\n" +"\n" +"Notez qu'au bas de l'écran, la liste des actions possibles change\n" +"lorsque vous appyuez sur 'Tab'. De cette manière, vous pouvez\n" +"toujours savoir quelles actions sont accessibles à partir du\n" +"panneau actuellement séléctionné." + +#: src/help.c:169 +msgid "Goto:\n" +msgstr "Aller à:\n" + +#: src/help.c:171 +msgid "" +"Pressing 'G' allows you to jump to a specific day in the calendar.\n" +"\n" +"Using this command, you do not need to travel to that day using\n" +"the displacement keys inside the calendar panel.\n" +"If you hit [ENTER] without specifying any date, Calcurse checks the\n" +"system current date and you will be taken to that date." +msgstr "" +"Appuyer sur 'G' permet de se rendre rapidement à un jour donné dans\n" +"le calendrier.\n" +"\n" +"En utilisant cette commande, il n'est pas nécessaire d'utiliser les\n" +"touches de déplacement dans le panneau du calendrier pour se rendre\n" +"au jour voulu.\n" +"Si vous appuyez sur [ENTREE] sans spécifier de date, vous serez\n" +"directement placé à la date du jour." + +#: src/help.c:177 +msgid "Delete:\n" +msgstr "Effacer:\n" + +#: src/help.c:179 +msgid "" +"Pressing 'D' deletes an element in the ToDo or Appointment list.\n" +"\n" +"Depending on which panel is selected when you press the delete key,\n" +"the hilighted item of either the ToDo or Appointment list will be \n" +"removed from this list.\n" +"\n" +"If the general option 'confirm_delete' is set to 'YES', then you will\n" +"be asked for confirmation before deleting the selected event.\n" +"Do not forget to save the calendar data to retrieve the modifications\n" +"next time you launch Calcurse." +msgstr "" +"Appuyer sur 'D' efface un élement dans les listes de tâches ou de\n" +"rendez-vous.\n" +"\n" +"En fonction du panneau qui est séléctionné lorsque vous appuyez\n" +"sur la touche d'effacement, l'élement qui est en surbrillance\n" +"dans la liste correspondante au panneau sera supprimé de\n" +"celle-ci.\n" +"\n" +"Si l'option générale 'confirmer_pour_effacer' est fixée à 'OUI',\n" +"alors il sera nécessaire de confirmer avant que l'élement soit\n" +"effectivement effacé.\n" +"N'oubliez pas de sauvegarder les données du calendrier pour\n" +"retrouver vos modifications au prochain lancement de Calcurse." + +#: src/help.c:188 +msgid "Add:\n" +msgstr "Ajouter:\n" + +#: src/help.c:190 +msgid "" +"Pressing 'A' allows you to add an item in either the ToDo or Appointment\n" +"list, depending on which panel is selected when you press 'A'.\n" +"\n" +"To enter a new item in the TODO list, you only need to enter the\n" +"description of this new item.\n" +"\n" +"If the APPOINTMENT panel is selected while pressing 'A', you will be\n" +"able to enter either a new appointment or a new all-day long event.\n" +"To enter a new event, press [ENTER] instead of the item start time, and\n" +"just fill in the event description.\n" +"To enter a new appointment to be added in the APPOINTMENT list, you\n" +"will need to enter successively the time at which the appointment\n" +"begins, the appointment length (either by specifying the duration in\n" +"minutes, or the end time in [hh:mm] or [h:mm] format), and the\n" +"description of the event.\n" +"\n" +"The day at which occurs the event or appointment is the day currently\n" +"selected in the calendar, so you need to move to the desired day before\n" +"pressing 'A'.\n" +"\n" +"Notes:\n" +" o if an appointment lasts for such a long time that it continues\n" +" on the next days, this event will be indicated on all the\n" +" corresponding days, and the beginning or ending hour will be\n" +" replaced by '..' if the event does not begin or end on the day.\n" +" o if you only press [ENTER] at the APPOINTMENT or TODO event\n" +" description prompt, without any description, no item will be\n" +" added.\n" +" o do not forget to save the calendar data to retrieve the new\n" +" event next time you launch Calcurse." +msgstr "" +"Appuyer sur 'A' permet d'ajouter un élément soit à la liste des tâches,\n" +"soit à la liste des rendez-vous, en fonction du panneau qui est \n" +"séléctionné.\n" +"\n" +"Pour ajouter un nouvel élément à la liste des tâches, il est uniquement\n" +"nécessaire de renseigner la description de la nouvelle tâche.\n" +"\n" +"Par contre, si le panneau des rendez-vous est séléctionné au moment où\n" +"vous appuyez sur 'A', vous pourrez ajouter soit un nouveau rendez-vous,\n" +"soit un nouvel événement qui dure toute la journée.\n" +"Pour ajouter un nouvel événement, il faut appuyer sur [ENTREE] sans\n" +"mentionner d'heure de début, et ensuite renseigner la description de\n" +"ce nouvel événement.\n" +"Pour ajouter un nouveau rendez-vous, il faut renseigner successivement:\n" +"l'heure à laquelle débute ce rendez-vous, la durée (soit en spécifiant\n" +"un nombre de minutes, ou une heure de fin au format [hh:mm] ou [h:mm]),\n" +"ainsi que la description du rendez-vous.\n" +"\n" +"La date de ce rendez-vous sera celle du jour actuellement séléctionné\n" +"dans le calendrier. Il est donc nécessaire de se déplacer jusqu'au jour\n" +"du rendez-vous avant d'appuyer sur 'A' pour l'ajouter dans la liste.\n" +"\n" +"Remarques:\n" +" o Si la durée d'un rendez-vous s'étale sur plusieurs jours,\n" +" ce rendez-vous sera indiqué sur tous les jours concernés.\n" +" De plus, si le rendez-vous ne commence ou ne se termine pas \n" +" au jour séléctionné dans le calendrier, respectivement \n" +" l'horaire de début ou de fin sera remplacé par '..'.\n" +" o Si vous n'entrez aucun texte au moment de renseigner la\n" +" description d'un nouvel élément à ajouter, mais que vous\n" +" appuyez juste sur [ENTREE], l'ajout de ce nouvel élément\n" +" sera annulé.\n" +" o N'oubliez pas de sauvegarder les données en appuyant sur 'S'\n" +" pour retrouver les nouveaux éléments que vous ajoutez." + +#: src/help.c:217 +msgid "Config:\n" +msgstr "Configuration:\n" + +#: src/help.c:219 +msgid "" +"Pressing 'C' leads to the configuration submenu, from which you can\n" +"select between color, layout, and general options.\n" +"\n" +"The color submenu lets you choose the color theme.\n" +"\n" +"The layout submenu lets you choose the Calcurse screen layout, in other\n" +"words where to place the three different panels on the screen.\n" +"\n" +"The general options submenu brings a screen with the different options\n" +"which modifies the way Calcurse interacts with the user.\n" +"\n" +"Do not forget to save the calendar data to retrieve your configuration\n" +"next time you launch Calcurse." +msgstr "" +"Appuyer sur 'C' fait apparaître le menu de configuration, depuis lequel\n" +"il est possible de modifier les options concernant les couleurs, la\n" +"disposition des panneaux, ainsi que les options générales.\n" +"\n" +"Le sous-menu 'Couleur' permet de séléctionner parmis plusieurs thèmes\n" +"graphiques différents. Le sous-menu 'Ecran' permet de séléctionner la \n" +"disposition voulue pour les trois panneaux de l'affichage principal.\n" +"Le sous-menu 'Général' amène à un écran qui permet de modifier les\n" +"options qui gèrent la manière dont Calcurse intéragit avec\n" +"l'utilisateur.\n" +"\n" +"N'oubliez pas de sauvegarder les données pour retrouver votre\n" +"configuration au prochain lancement de Calcurse." + +#: src/help.c:229 +msgid "Calcurse - text-based organizer" +msgstr "Calcurse - organiseur personnel en mode texte" + +#: src/help.c:231 +msgid "" +"Copyright (c) 2004-2006 Frederic Culot\n" +"\n" +"This program is free software; you can redistribute it and/or modify\n" +"it under the terms of the GNU General Public License as published by\n" +"the Free Software Foundation; either version 2 of the License, or\n" +"(at your option) any later version.\n" +"\n" +"This program is distributed in the hope that it will be useful,\n" +"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +"GNU General Public License for more details.\n" +"\n" +"\n" +"Send your feedback or comments to : calcurse@culot.org\n" +"Calcurse home page : http://culot.org/calcurse" +msgstr "" +"Copyright (c) 2004-2006 Frédéric Culot\n" +"\n" +"Ce programme est un logiciel libre; vous pouvez le redistribuer et/ou\n" +"le modifier en respéctant les clauses de la Licence Publique Générale\n" +"GNU publiée par la 'Free Software Foundation'; soit la version 2 de\n" +"la Licence, soit (à votre discrétion) une version plus récente.\n" +"\n" +"Ce programme est distribué dans l'espoir qu'il sera utile, mais SANS\n" +"AUCUNE GARANTIE; sans même une garantie implicite de COMMERCIABILITE\n" +"ou de CONFORMITE A UNE UTILISATION PARTICULIERE.\n" +"Pour plus de détails, voir la Licence Publique Générale GNU.\n" +"\n" +"\n" +"Envoyez vos remarques ou commentaires à : calcurse@culot.org\n" +"Page web de Calcurse : http://culot.org/calcurse" + +#: src/help.c:252 +#, c-format +msgid "CalCurse %s | help" +msgstr "Calcurse %s | aide" + +#: src/io.c:74 +#, c-format +msgid "%s does not exist, create it now [y or n] ? " +msgstr "%s n'existe pas, le créer maintenant [y ou n] ? " + +#: src/io.c:79 src/io.c:96 +#, c-format +msgid "aborting...\n" +msgstr "annulation...\n" + +#: src/io.c:90 +#, c-format +msgid "%s successfully created\n" +msgstr "%s correctement créé\n" + +#: src/io.c:91 +#, c-format +msgid "starting interactive mode...\n" +msgstr "lancement du mode intéractif...\n" + +#: src/io.c:127 +msgid "Problems accessing data file ..." +msgstr "Problème d'accession aux fichiers de données ..." + +#: src/io.c:130 +msgid "The data files were successfully saved" +msgstr "Les données ont été correctement enregistrées" + +#: src/io.c:259 +msgid "FATAL ERROR in load_app: syntax error in the item date\n" +msgstr "ERREUR FATALE dans load_app: mauvais format de date\n" + +#: src/io.c:274 +msgid "FATAL ERROR in load_app: no event nor appointment found\n" +msgstr "ERREUR FATALE dans load_app: aucun évenement ou rendez-vous trouvé\n" + +#: src/io.c:291 +msgid "FATAL ERROR in load_app: wrong format in the appointment or event\n" +msgstr "" +"ERREUR FATALE dans load_app: mauvais format dans le rendez-vous ou " +"l'évenement\n" + +#: src/io.c:304 +msgid "Failed to open todo file" +msgstr "Problème d'ouverture du fichier des tâches" + +#: src/io.c:375 +msgid "Welcome to Calcurse. Missing data files were created." +msgstr "Bienvenue dans Calcurse. Les fichiers manquants ont été créés." + +#: src/io.c:376 +msgid "Data files found. Data will be loaded now." +msgstr "Fichiers de données trouvés. Les données seront chargées." + +#: src/io.c:392 +msgid "Saving..." +msgstr "Enregistrement..." + +#: src/io.c:393 +msgid "Loading..." +msgstr "Chargement..." + +#: src/todo.c:76 +msgid "FATAL ERROR in todo_delete_bynum: no such todo\n" +msgstr "ERREUR FATALE dans todo_delete_by_num: aucune tâche correspondante\n" + +#: src/utils.c:74 +msgid "Press any key to continue..." +msgstr "Appuyez sur une touche pour continuer..." + +#: src/utils.c:232 +msgid "-- Press 'N' for next page --" +msgstr "-- Appuyez sur 'N' pour la page suivante --" + +#: src/utils.c:233 +msgid "-- Press 'P' for previous page --" +msgstr "-- Appuyez sur 'P' pour la page précédente --" + +#: src/utils.c:368 src/utils.c:399 +msgid "Help" +msgstr "Aide" + +#: src/utils.c:369 src/utils.c:400 +msgid "Quit" +msgstr "Quitter" + +#: src/utils.c:371 src/utils.c:402 +msgid "Redraw" +msgstr "Retracer" + +#: src/utils.c:372 src/utils.c:403 +msgid "Save" +msgstr "Sauver" + +#: src/utils.c:374 +msgid "-/+1 Day" +msgstr "-+1 Jour" + +#: src/utils.c:376 +msgid "-/+1 Week" +msgstr "-+1 Sem." + +#: src/utils.c:378 src/utils.c:413 +msgid "GoTo" +msgstr "Aller à" + +#: src/utils.c:380 src/utils.c:407 +msgid "Chg View" +msgstr "Chg Vue" + +#: src/utils.c:382 src/utils.c:417 +msgid "Config" +msgstr "Config" + +#: src/utils.c:405 +msgid "Up/Down" +msgstr "Haut/Bas" + +#: src/utils.c:409 +msgid "Add Item" +msgstr "Ajouter" + +#: src/utils.c:411 +msgid "Del Item" +msgstr "Effacer" + +#: src/utils.c:415 +msgid "View" +msgstr "Voir" + +#: src/utils.c:443 +msgid "FATAL ERROR in date2sec: failure in mktime\n" +msgstr "ERREUR FATALE dans date2sec: dysfonctionnement dans mktime\n" + +#: src/utils.c:567 +msgid "Appointment" +msgstr "Rendez-vous" + +#: src/vars.c:41 +msgid "January" +msgstr "Janvier" + +#: src/vars.c:42 +msgid "February" +msgstr "Février" + +#: src/vars.c:43 +msgid "March" +msgstr "Mars" + +#: src/vars.c:44 +msgid "April" +msgstr "Avril" + +#: src/vars.c:45 +msgid "May" +msgstr "Mai" + +#: src/vars.c:46 +msgid "June" +msgstr "Juin" + +#: src/vars.c:47 +msgid "July" +msgstr "Juillet" + +#: src/vars.c:48 +msgid "August" +msgstr "Août" + +#: src/vars.c:49 +msgid "September" +msgstr "Septembre" + +#: src/vars.c:50 +msgid "October" +msgstr "Octobre" + +#: src/vars.c:51 +msgid "November" +msgstr "Novembre" + +#: src/vars.c:52 +msgid "December" +msgstr "Décembre" + +#: src/vars.c:55 src/vars.c:62 +msgid "Sun" +msgstr "Dim" + +#: src/vars.c:56 +msgid "Mon" +msgstr "Lun" + +#: src/vars.c:57 +msgid "Tue" +msgstr "Mar" + +#: src/vars.c:58 +msgid "Wed" +msgstr "Mer" + +#: src/vars.c:59 +msgid "Thu" +msgstr "Jeu" + +#: src/vars.c:60 +msgid "Fri" +msgstr "Ven" + +#: src/vars.c:61 +msgid "Sat" +msgstr "Sam" diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100755 index 0000000..1614db1 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,14 @@ +# $calcurse: Makefile.am,v 1.1 2006/07/31 21:00:02 culot Exp $ + +AUTOMAKE_OPTIONS= gnu +bin_PROGRAMS= calcurse +calcurse_SOURCES= calcurse.c apoint.c event.c todo.c utils.c\ + calendar.c vars.c io.c help.c custom.c args.c\ + day.c recur.c\ + apoint.h event.h todo.h utils.h calendar.h\ + vars.h io.h help.h custom.h args.h i18n.h\ + day.h recur.h +LIBS= -lncurses -lm +LDADD= @LTLIBINTL@ +man_MANS= calcurse.1 +EXTRA_DIST= calcurse.1 diff --git a/src/apoint.c b/src/apoint.c new file mode 100755 index 0000000..5cbc62e --- /dev/null +++ b/src/apoint.c @@ -0,0 +1,235 @@ +/* $calcurse: apoint.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#include <ncurses.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <time.h> + +#include "i18n.h" +#include "vars.h" +#include "event.h" +#include "apoint.h" +#include "day.h" +#include "custom.h" +#include "utils.h" + +struct apoint_s *apointlist; + +struct apoint_s *apoint_new(char *mesg, long start, long dur) +{ + struct apoint_s *o, **i; + o = (struct apoint_s *) malloc(sizeof(struct apoint_s)); + o->mesg = (char *) malloc(strlen(mesg) + 1); + strcpy(o->mesg, mesg); + o->start = start; + o->dur = dur; + i = &apointlist; + for (;;) { + if (*i == 0 || (*i)->start > start) { + o->next = *i; + *i = o; + break; + } + i = &(*i)->next; + } + return o; +} + +unsigned apoint_inday(struct apoint_s *i, long start) +{ + if (i->start <= start + 3600 * 24 && i->start + i->dur > start) { + return 1; + } + return 0; +} + +void apoint_sec2str(struct apoint_s *o, int type, long day, char *start, char *end) +{ + struct tm *lt; + time_t t; + + if (o->start < day && type == APPT) { + strcpy(start, "..:.."); + } else { + t = o->start; + lt = localtime(&t); + snprintf(start, HRMIN_SIZE, "%02u:%02u", lt->tm_hour, + lt->tm_min); + } + if (o->start + o->dur > day + 24 * 3600 && type == APPT) { + strcpy(end, "..:.."); + } else { + t = o->start + o->dur; + lt = localtime(&t); + snprintf(end, HRMIN_SIZE, "%02u:%02u", lt->tm_hour, + lt->tm_min); + } +} + +void apoint_write(struct apoint_s *o, FILE * f) +{ + struct tm *lt; + time_t t; + + t = o->start; + lt = localtime(&t); + fprintf(f, "%02u/%02u/%04u @ %02u:%02u", + lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year, + lt->tm_hour, lt->tm_min); + + t = o->start + o->dur; + lt = localtime(&t); + fprintf(f, " -> %02u/%02u/%04u @ %02u:%02u |%s\n", + lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year, + lt->tm_hour, lt->tm_min, o->mesg); +} + +struct apoint_s *apoint_scan(FILE * f, struct tm start, struct tm end) +{ + struct tm *lt; + char buf[MESG_MAXSIZE], *nl; + time_t tstart, tend, t; + + t = time(NULL); + lt = localtime(&t); + + /* Read the appointment description */ + fgets(buf, MESG_MAXSIZE, f); + nl = strchr(buf, '\n'); + if (nl) { + *nl = '\0'; + } + + start.tm_sec = end.tm_sec = 0; + start.tm_isdst = end.tm_isdst = -1; + start.tm_year -= 1900; + start.tm_mon--; + end.tm_year -= 1900; + end.tm_mon--; + + tstart = mktime(&start); + tend = mktime(&end); + if (tstart == -1 || tend == -1 || tstart > tend) { + fputs(_("FATAL ERROR in apoint_scan: date error in the appointment\n"), stderr); + exit(EXIT_FAILURE); + } + return apoint_new(buf, tstart, tend - tstart); +} + +void apoint_delete_bynum(long start, unsigned num) +{ + unsigned n; + struct apoint_s *i, **iptr; + + n = 0; + iptr = &apointlist; + for (i = apointlist; i != 0; i = i->next) { + if (apoint_inday(i, start)) { + if (n == num) { + *iptr = i->next; + free(i->mesg); + free(i); + return; + } + n++; + } + iptr = &i->next; + } + /* NOTREACHED */ + fputs(_("FATAL ERROR in apoint_delete_bynum: no such appointment\n"), stderr); + exit(EXIT_FAILURE); +} + +/* + * Print an item date in the appointment panel. + */ +void display_item_date(WINDOW *win, int incolor, struct apoint_s *i, + int type, long date, int y, int x) +{ + char a_st[100], a_end[100]; + + apoint_sec2str(i, type, date, a_st, a_end); + + if (incolor == 0) + custom_apply_attr(win, ATTR_HIGHEST); + mvwprintw(win, y, x, " - %s -> %s", a_st, a_end); + if (incolor == 0) + custom_remove_attr(awin, ATTR_HIGHEST); +} + +/* + * Return the line number of an item (either an appointment or an event) in + * the appointment panel. This is to help the appointment scroll function + * to place beggining of the pad correctly. + */ +int get_item_line(int item_nb, int nb_events_inday) +{ + int separator = 2; + int line = 0; + + if (item_nb <= nb_events_inday) + line = item_nb - 1; + else + line = nb_events_inday + separator + + (item_nb - (nb_events_inday + 1))*3 - 1; + return line; +} + +/* + * Update (if necessary) the first displayed pad line to make the + * appointment panel scroll down next time pnoutrefresh is called. + */ +void scroll_pad_down(int item_nb, int nb_events_inday, int win_length) +{ + int pad_last_line = 0; + int item_first_line = 0, item_last_line = 0; + int borders = 6; + int awin_length = win_length - borders; + + item_first_line = get_item_line(item_nb, nb_events_inday); + if (item_nb < nb_events_inday) + item_last_line = item_first_line; + else + item_last_line = item_first_line + 1; + pad_last_line = apad->first_onscreen + awin_length; + if (item_last_line >= pad_last_line) + apad->first_onscreen = item_last_line - awin_length; +} + +/* + * Update (if necessary) the first displayed pad line to make the + * appointment panel scroll up next time pnoutrefresh is called. + */ +void scroll_pad_up(int item_nb, int nb_events_inday) +{ + int item_first_line = 0; + + item_first_line = get_item_line(item_nb, nb_events_inday); + if (item_first_line < apad->first_onscreen) + apad->first_onscreen = item_first_line; +} diff --git a/src/apoint.h b/src/apoint.h new file mode 100755 index 0000000..e9dbe82 --- /dev/null +++ b/src/apoint.h @@ -0,0 +1,56 @@ +/* $calcurse: apoint.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#ifndef CALCURSE_APOINT_H +#define CALCURSE_APOINT_H + +#include <ncurses.h> + +#define HRMIN_SIZE 6 +#define MESG_MAXSIZE 256 + +struct apoint_s { + struct apoint_s *next; + long start; /* seconds since 1 jan 1970 */ + long dur; /* duration of the appointment in seconds */ + char *mesg; +}; + +extern struct apoint_s *apointlist; + +struct apoint_s *apoint_new(char *, long, long); +unsigned apoint_inday(struct apoint_s *o, long start); +void apoint_sec2str(struct apoint_s *o, int type, long day, char *start, char *end); +void apoint_write(struct apoint_s *o, FILE * f); +struct apoint_s *apoint_scan(FILE * f, struct tm start, struct tm end); +void apoint_delete_bynum(long start, unsigned num); +void display_item_date(WINDOW *win, int color, struct apoint_s *i, + int type, long date, int y, int x); +int get_item_line(int item_nb, int nb_events_inday); +void scroll_pad_down(int item_nb, int nb_events_inday, int win_length); +void scroll_pad_up(int item_nb, int nb_events_inday); + +#endif /* CALCURSE_APOINT_H */ diff --git a/src/args.c b/src/args.c new file mode 100755 index 0000000..2261640 --- /dev/null +++ b/src/args.c @@ -0,0 +1,431 @@ +/* $calcurse: args.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#include <ncurses.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <stdbool.h> +#include <sys/types.h> +#include <unistd.h> +#include <time.h> + +#include "i18n.h" +#include "utils.h" +#include "args.h" +#include "vars.h" +#include "event.h" +#include "apoint.h" +#include "recur.h" +#include "day.h" +#include "todo.h" +#include "io.h" + +/* + * Parse the command-line arguments and call the appropriate + * routines to handle those arguments. Also initialize the data paths. + */ +int parse_args(int argc, char **argv, int colr) +{ + int ch, add_line = 0; + int unknown_flag = 0, app_found = 0; + int aflag = 0, cflag = 0, dflag = 0, vflag = 0, hflag = 0, tflag = 0; + int non_interactive = 0, multiple_flag = 0, load_data = 0; + int no_file = 1; + char *ddate = "", *cfile = NULL; + + while ((ch = getopt(argc, argv, "hvtad:c:")) != -1) { + switch (ch) { + case 'a': + aflag = 1; + multiple_flag++; + load_data++; + break; + case 'd': + dflag = 1; + multiple_flag++; + load_data++; + ddate = optarg; + break; + case 'c': + cflag = 1; + multiple_flag++; + load_data++; + cfile = optarg; + break; + case 'h': + hflag = 1; + break; + case 't': + tflag = 1; + multiple_flag++; + load_data++; + add_line = 1; + break; + case 'v': + vflag = 1; + break; + default: + usage(); + usage_try(); + unknown_flag = 1; + non_interactive = 1; + } + } + argc -= optind; + argv += optind; + if (argc >= 1) { /* incorrect arguments */ + usage(); + usage_try(); + return 1; + } else { + if (unknown_flag) { + non_interactive = 1; + } else if (hflag) { + help_arg(); + non_interactive = 1; + } else if (vflag) { + version_arg(); + non_interactive = 1; + } else if (multiple_flag) { + if (load_data) { + io_init(cfile); + no_file = check_data_files(); + if (dflag || aflag) + load_app(colr); + } + if (tflag) { + todo_arg(colr); + non_interactive = 1; + } + if (dflag) { + date_arg(ddate, add_line); + non_interactive = 1; + } else if (aflag) { + app_found = app_arg(add_line,0,0,0,0); + non_interactive = 1; + } + } else { + non_interactive = 0; + io_init(cfile); + no_file = check_data_files(); + } + return non_interactive; + } +} + +/* + * Print Calcurse version with a short copyright text and exit. + */ +void version_arg() +{ + char vtitle[50]; + char *vtext = + _("\nCopyright (c) 2004-2006 Frederic Culot.\n" + "This is free software; see the source for copying conditions.\n"); + + sprintf(vtitle, _("Calcurse %s - text-based organizer\n"), VERSION); + fputs(vtitle, stdout); + fputs(vtext, stdout); +} + +/* + * Print the command line options and exit. + */ +void help_arg() +{ + char htitle[50]; + char *htext = + _("\nMiscellaneous:\n" + " -h print this help and exit.\n" + " -v print calcurse version and exit.\n" + "\nOptions:\n" + " -c <file> specify the calendar <file> to use.\n" + "\nNon-interactive:\n" + " -a print events and appointments for current day and exit.\n" + " -d <date|num> print events and appointments for <date> " + "or <num> upcoming\n\t\tdays and exit. Possible formats are: " + "'mm/dd/yyyy' or 'n'.\n" + " -t print todo list and exit.\n" + "\nFor more information, type '?' from within Calcurse, " + "or read the manpage.\n" + "Mail bug reports and suggestions to <calcurse@culot.org>.\n"); + + sprintf(htitle, _("Calcurse %s - text-based organizer\n"), VERSION); + fputs(htitle, stdout); + usage(); + fputs(htext, stdout); +} + +/* + * Print todo list and exit. + */ +void todo_arg(int colr) +{ + struct todo_s *i; + int nb_tod; + + nb_tod = load_todo(colr); + fputs(_("to do:\n"),stdout); + for (i = todolist; i != 0; i = i->next) { + fputs(" - ",stdout); + fputs(i->mesg,stdout); + fputs("\n",stdout); + } +} + +/* + * Print appointments for given day and exit. + * If no year, month, and day is given, the given date is used. + * If there is also no date given, current date is considered. + */ +int app_arg(int add_line, int year, int month, int day, long date) +{ + struct recur_event_s *re; + struct event_s *j; + struct recur_apoint_s *ra; + struct apoint_s *i; + long today; + bool print_date = true; + int app_found = 0; + char apoint_start_time[100]; + char apoint_end_time[100]; + + if (date == 0) { + today = get_sec_date(year, month, day); + } else today = date; + + /* + * Calculate and print the selected date if there is an event for + * that date and it is the first one, and then print all the events for + * that date. + */ + for (re = recur_elist; re != 0; re = re->next) { + if (recur_item_inday(re->day, re->rpt->type, re->rpt->freq, + re->rpt->until, today)) { + app_found = 1; + if (add_line) { + fputs("\n", stdout); + add_line = 0; + } + if (print_date) { + arg_print_date(today); + print_date = false; + } + fputs(" o ", stdout); + fputs(re->mesg, stdout); fputs("\n", stdout); + } + } + + for (j = eventlist; j != 0; j = j->next) { + if (event_inday(j, today)) { + app_found = 1; + if (add_line) { + fputs("\n",stdout); + add_line = 0; + } + if (print_date) { + arg_print_date(today); + print_date = false; + } + fputs(" o ",stdout); + fputs(j->mesg,stdout); fputs("\n",stdout); + } + } + + /* Same process is performed but this time on the appointments. */ + for (ra = recur_alist; ra != 0; ra = ra->next) { + if (recur_item_inday(ra->start, ra->rpt->type, ra->rpt->freq, + ra->rpt->until, today)) { + app_found = 1; + if (add_line) { + fputs("\n",stdout); + add_line = 0; + } + if (print_date) { + arg_print_date(today); + print_date = false; + } + apoint_sec2str(recur_apoint_s2apoint_s(ra), + RECUR_APPT, today, apoint_start_time, + apoint_end_time); + fputs(" - ",stdout); + fputs(apoint_start_time,stdout); + fputs(" -> ",stdout); + fputs(apoint_end_time,stdout); fputs("\n\t",stdout); + fputs(ra->mesg,stdout); fputs("\n",stdout); + } + } + + for (i = apointlist; i != 0; i = i->next) { + if (apoint_inday(i, today)) { + app_found = 1; + if (add_line) { + fputs("\n",stdout); + add_line = 0; + } + if (print_date) { + arg_print_date(today); + print_date = false; + } + apoint_sec2str(i, APPT, today, apoint_start_time, + apoint_end_time); + fputs(" - ",stdout); + fputs(apoint_start_time,stdout); + fputs(" -> ",stdout); + fputs(apoint_end_time,stdout); fputs("\n\t",stdout); + fputs(i->mesg,stdout); fputs("\n",stdout); + } + } + return app_found; +} + +/* + * Print appointment for the given date or for the given n upcoming + * days. + */ +void date_arg(char *ddate, int add_line) +{ + int i; + int year = 0, month = 0, day = 0; + int numdays = 0, num_digit = 0; + int arg_len = 0, app_found = 0; + int date_valid = 0; + long today, ind; + int sec_in_day = 86400; + + /* + * Check (with the argument length) if a date or a number of days + * was entered, and then call app_arg() to print appointments + */ + arg_len = strlen(ddate); + if (arg_len <= 4) { /* a number of days was entered */ + for (i = 0; i <= arg_len-1; i++) { + if (isdigit(ddate[i])) num_digit++; + } + if (num_digit == arg_len) numdays = atoi(ddate); + + /* + * Get current date, and print appointments for each day + * in the chosen interval. app_found and add_line are used + * to format the output correctly. + */ + today = get_sec_date(year, month, day); + ind = today; + for (i = 0; i < numdays; i++) { + app_found = app_arg(add_line, 0, 0, 0, ind); + add_line = app_found; + ind = ind + sec_in_day; + } + } else { /* a date was entered */ + date_valid = check_date(ddate); + if (date_valid) { + sscanf(ddate, "%d / %d / %d", &month, &day, &year); + app_found = app_arg(add_line, year, month, day, 0); + } else { + fputs(_("Argument to the '-d' flag is not valid\n"),stdout); + fputs(_("Possible argument formats are : 'mm/dd/yyyy' or 'n'\n"),stdout); + fputs(_("\nFor more information, type '?' from within Calcurse, or read the manpage.\n"),stdout); + fputs + (_("Mail bug reports and suggestions to <calcurse@culot.org>.\n"), + stdout); + } + } +} + +/* + * Check if the entered date is of a valid format. + * First check the format by itself, and then check the + * numbers correctness. + */ +int +check_date(char *date) +{ + int ok = 0; + char month[] = " "; + char day[] = " "; + char year[] = " "; + if ( + (strlen(date) == 10) & + (isdigit(date[0]) != 0) & + (isdigit(date[1]) != 0) & + (date[2] == '/') & + (isdigit(date[3]) != 0) & + (isdigit(date[4]) != 0) & + (date[5] == '/') & + (isdigit(date[6])!=0) & (isdigit(date[7])!=0) & + (isdigit(date[8])!=0) & (isdigit(date[9])!=0) + ) { + strncpy(month, date, 2); + strncpy(day, date + 3, 2); + strncpy(year, date + 6, 4); + if ( (atoi(month) <= 12) & + (atoi(month) >= 1) & + (atoi(day) <= 31) & + (atoi(day) >= 1) & + (atoi(year) <= 9999) & + (atoi(year) > 1)) + ok = 1; + } + return ok; +} + +/* + * Print the date on stdout. + */ +void arg_print_date(long date) +{ + char date_str[30]; + time_t t; + struct tm *lt; + + t = date; + lt = localtime(&t); + sprintf(date_str,"%02u/%02u/%04u",lt->tm_mon+1, + lt->tm_mday, 1900+lt->tm_year); + fputs(date_str,stdout); + fputs(":\n",stdout); +} + +/* + * Print Calcurse usage and exit. + */ +void usage() +{ + char *arg_usage = + _("Usage: calcurse [-h | -v] [-at] [-d date|num] [-c file]\n"); + + fputs(arg_usage, stdout); +} + +void usage_try() +{ + char *arg_usage_try = + _("Try 'calcurse -h' for more information.\n"); + + fputs(arg_usage_try, stdout); +} diff --git a/src/args.h b/src/args.h new file mode 100755 index 0000000..995cc20 --- /dev/null +++ b/src/args.h @@ -0,0 +1,41 @@ +/* $calcurse: args.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#ifndef CALCURSE_ARGS_H +#define CALCURSE_ARGS_H + +void usage(); +void usage_try(); +int parse_args(int argc, char **argv, int colr); +void version_arg(); +void help_arg(); +void todo_arg(int colr); +int app_arg(int add_line, int year, int month, int day, long date); +void date_arg(char *ddate, int add_line); +int check_date(char *date); +void arg_print_date(long date); + +#endif /* CALCURSE_ARGS_H */ diff --git a/src/calcurse.1 b/src/calcurse.1 new file mode 100755 index 0000000..5ae929c --- /dev/null +++ b/src/calcurse.1 @@ -0,0 +1,158 @@ +.\" $calcurse: calcurse.1,v 1.1 2006/07/31 21:00:03 culot Exp $ +.\" +.\" Copyright (c) 2004-2006 Frederic Culot +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place - Suite 330, +.\" Boston, MA 02111-1307, USA. +.\" +.TH CALCURSE 1 "May 07, 2006" "Version 1.4" "Calcurse Manual" +.SH NAME +Calcurse \- text-based organizer +.PP +.SH SYNOPSIS +.B "calcurse " +[ +.B "-h " +| +.B "-v " +] [ +.B "-at " +] [ +.B "-d " +\fIdate\fP|\fInum\fP ] [ +.B "-c " +\fIfile\fP ] +.PP +.SH DESCRIPTION +Calcurse is a text-based personal organizer which helps keeping track of +events and everyday tasks. It contains a calendar, a 'todo' list, and +puts your appointments in order. The user interface is configurable, +and one can choose between different color schemes and layouts. +All of the commands are documented within an online help system. +.PP +.SH OPTIONS +The following options are supported: +.TP +.B \-a +Print the appointments and events for the current day and exit. +.br +\fINote:\fP the calendar from which to read the appointments can be specified using +the '\-c' flag. +.TP +.B \-c +Specify the calendar file to use. The default calendar is +.B "'~/.calcurse/apts'" +(see section \fIFILES\fP below). +.TP +.B \-d +Print the appointments and events for the given date or for +the given number of upcoming days, depending on the argument format. +Two possible formats are supported: +.RS 9 +.TP 2 +\(bu a date of the form 'mm/dd/yyyy'. +.TP 2 +\(bu a number 'n'. +.RE +.RS 7 +.LP +In the first case, the appointments and events list for the specified +date will be returned, while in the second case the appointments and events +list for the 'n' upcoming days will be returned. +.br +As an example, typing 'calcurse -d 3' will display your appointments +and events for today, tomorrow, and the day after tomorrow. +.br +\fINote:\fP as for the '-a' flag, the calendar from which to read the +appointments can be specified using the '\-c' flag. +.RE +.TP +.B \-h +Print a short help text describing the supported command-line options, +and then exit. +.TP +.B \-t +Print the 'todo' list and exit. +.TP +.B \-v +Display calcurse version and exit. +.SH NOTES +Calcurse interface contains three different panels (calendar, +appointment list, and todo list) on which you can perform different +actions. All the possible actions, together with their associated +keystrokes, are listed on the status bar. This status bar +takes place at the bottom of the screen. +.PP +At any time, the built-in help system can be invoked by pressing the '?' +key. Once viewing the help screens, informations on a specific command +can be accessed by pressing the keystroke corresponding to that command. +.PP +.SH CONFIGURATION +The calcurse options can be changed from the configuration menu (shown +when 'C' is hit). Three possible categories are to be chosen from : the +color scheme, the layout (the location of the three panels on the +screen), and more general options (such as automatic save before +quitting). All of these options are detailed in the configuration menu. +.PP +.SH FILES +The following structure is created in your $HOME directory the first +time calcurse is run : +.PP +.HP 10 +$HOME/.calcurse/ +.br +|___conf +.br +|___apts +.br +|___todo +.PP +The \fIconf\fP file contains the user configuration. The \fIapts\fP +file contains all of the user's appointments, and the \fItodo\fP +file contains the todo list. +.PP +.SH LICENCE +Copyright (c) 2004-2006 by Frederic Culot. +.br +This software is released under the GNU General Public License. Please +read the COPYING file for more information. +.PP +.SH BUGS +Incorrect highlighting of items appear when using calcurse black and +white theme together with a \fB$TERM\fP variable set to +\fIxterm-color\fP. +To fix this bug, and as advised by Thomas E. Dickey (xterm maintainer), +\fIxterm-xfree86\fP should be used instead of \fIxterm-color\fP to set +the \fB$TERM\fP variable: + "The xterm-color value for $TERM is a bad choice for XFree86 + xterm because it is commonly used for a terminfo entry which + happens to not support bce. Use the xterm-xfree86 entry + which is distributed with XFree86 xterm (or the similar one + distributed with ncurses)." +.PP +If you find other bugs, please send a report to calcurse@culot.org or to the +author, below. +.PP +.SH AUTHOR +\fBFrederic Culot\fP <frederic@culot.org>. +.PP +.SH SEE ALSO +ncurses(3), gettext(3) +.br +Calcurse home page : http://culot.org/calcurse/ +.br +Calcurse manual found in the doc/ directory of the source package, or +at: +http://culot.org/calcurse/manual.html diff --git a/src/calcurse.c b/src/calcurse.c new file mode 100755 index 0000000..7432daf --- /dev/null +++ b/src/calcurse.c @@ -0,0 +1,1156 @@ +/* $calcurse: calcurse.c,v 1.1 2006/07/31 21:00:02 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif /* HAVE_CONFIG_H */ + +#include <ncurses.h> +#include <time.h> +#include <string.h> +#include <stdlib.h> +#include <stdbool.h> +#include <math.h> +#include <locale.h> + +#include "i18n.h" +#include "io.h" +#include "help.h" +#include "calendar.h" +#include "custom.h" +#include "utils.h" +#include "vars.h" +#include "day.h" +#include "apoint.h" +#include "event.h" +#include "todo.h" +#include "args.h" + + +/* Variables for calendar */ +struct tm *ptrtime; +time_t timer; +char current_day[3]; +char current_month[3]; +char current_year[5]; +char current_time[15]; +char cal_date[30]; +int year, month, day; +int sel_year, sel_month, sel_day; + +/* Variables for appointments */ +int number_apoints_inday; +int number_events_inday; +int first_app_onscreen = 0; +int hilt_app = 0, sav_hilt_app; + +/* Variables for todo list */ +int nb_tod = 0, hilt_tod = 0, sav_hilt_tod; +int first_todo_onscreen = 1; +char *saved_t_mesg; + +/* Variables for user configuration */ +int colr = 1, layout = 1; +int no_data_file = 1; +int really_quit = 0; +bool confirm_quit; +bool confirm_delete; +bool auto_save; +bool skip_system_dialogs; +bool skip_progress_bar; +bool week_begins_on_monday; + +/* + * Variables to handle calcurse windows + */ +int x_cal, y_cal, x_app, y_app, x_tod, y_tod, x_bar, y_bar; +int nl_cal, nc_cal, nl_app, nc_app, nl_tod, nc_tod, nl_bar, nc_bar; +int which_pan = 0; +enum window_number {CALENDAR, APPOINTMENT, TODO}; + +/* External functions */ +void get_date(void); +void init_vars(int colr); +void init_wins(void), reinit_wins(void); +void add_item(void); +void add_todo(void); +void load_conf(void); +bool fill_config_var(char *string); +void update_todo_panel(void); +void update_app_panel(int yeat, int month, int day); +void store_day(int year, int month, int day, bool day_changed); +void get_screen_config(void); +void update_windows(int surrounded_window); +void general_config(void); +void print_general_options(WINDOW *win); +void print_option_incolor(WINDOW *win, bool option, int pos_x, int pos_y); +void del_apoint(void); + +/* + * Calcurse is a text-based personal organizer which helps keeping track + * of events and everyday tasks. It contains a calendar, a 'todo' list, + * and puts your appointments in order. The user interface is configurable, + * and one can choose between different color schemes and layouts. + * All of the commands are documented within an online help system. + */ +int main(int argc, char **argv) +{ + int ch; + int non_interactive; + bool do_storage = false; + bool day_changed = false; + char *no_color_support = + _("Sorry, colors are not supported by your terminal\n" + "(Press [ENTER] to continue)"); + char *quit_message = _("Do you really want to quit ?"); + char choices[] = "[y/n] "; + +#if ENABLE_NLS + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); +#endif /* ENABLE_NLS */ + + /* + * Begin by parsing and handling command line arguments. + * The data path is also initialized here. + */ + non_interactive = parse_args(argc, argv, colr); + if (non_interactive) return EXIT_SUCCESS; + + /* Begin of interactive mode with ncurses interface. */ + initscr(); /* start the curses mode */ + cbreak(); /* control chars generate a signal */ + noecho(); /* controls echoing of typed chars */ + curs_set(0); /* make cursor invisible */ + get_date(); + get_screen_config(); + + /* Check if terminal supports color. */ + if (has_colors()) { + colorize = true; + start_color(); + + /* Color assignment */ + init_pair(1, COLOR_RED, COLOR_BLACK); + init_pair(2, COLOR_GREEN, COLOR_BLACK); + init_pair(3, COLOR_BLUE, COLOR_BLACK); + init_pair(4, COLOR_CYAN, COLOR_BLACK); + init_pair(5, COLOR_YELLOW, COLOR_BLACK); + init_pair(6, COLOR_BLACK, COLOR_GREEN); + init_pair(7, COLOR_BLACK, COLOR_YELLOW); + init_pair(8, COLOR_RED, COLOR_BLUE); + init_pair(9, COLOR_WHITE, COLOR_BLACK); + } else { + colorize = false; + use_default_colors(); + } + + init_vars(colr); + init_wins(); + update_windows(which_pan); + + /* + * Read the data from files : first the user + * configuration (the display is then updated), and then + * the todo list, appointments and events. + */ + no_data_file = check_data_files(); + load_conf(); + custom_init_attr(colr); + nb_tod = load_todo(colr); + load_app(); + get_screen_config(); + reinit_wins(); + startup_screen(skip_system_dialogs, no_data_file, colr); + store_day(year, month, day, day_changed); + update_windows(CALENDAR); + + /* User input */ + for (;;) { + + /* Check terminal size. */ + getmaxyx(stdscr, row, col); + if ((col < 80) | (row < 24)) { + endwin(); + fputs(_("Please resize your terminal screen\n" + "(to at least 80x24),\n" + "and restart calcurse.\n"), stderr); + return EXIT_FAILURE; + } + + /* Get user input. */ + ch = wgetch(swin); + switch (ch) { + + case 9: /* The TAB key was hit. */ + /* Save previously highlighted event. */ + if (which_pan == TODO) { + sav_hilt_tod = hilt_tod; + hilt_tod = 0; + } + if (which_pan == APPOINTMENT) { + sav_hilt_app = hilt_app; + hilt_app = 0; + } + /* Switch to the selected panel. */ + if (which_pan == TODO) which_pan = CALENDAR; + else ++which_pan; + + /* Select the event to highlight. */ + if (which_pan == APPOINTMENT) { + if ((sav_hilt_app == 0) + & ( (number_events_inday + + number_apoints_inday) != 0)) + hilt_app = 1; + else + hilt_app = sav_hilt_app; + } else if (which_pan == TODO) { + if ((sav_hilt_tod == 0) & (nb_tod != 0)) + hilt_tod = 1; + else + hilt_tod = sav_hilt_tod; + } + break; + + case 'R': + case 'r': + reinit_wins(); + break; + + case 'G': + case 'g': /* Goto function */ + erase_window_part(swin, 0, 0, nc_bar, nl_bar); + get_date(); + goto_day(colr, day, month, year, + &sel_day, &sel_month, &sel_year); + do_storage = true; + day_changed = true; + break; + + case 'V': + case 'v': /* View function */ + if ((which_pan == APPOINTMENT) & (hilt_app != 0)) + day_popup_item(); + else if ((which_pan == TODO) & (hilt_tod != 0)) + item_in_popup(NULL, NULL, saved_t_mesg, + _("To do :")); + break; + + case 'C': + case 'c': /* Configuration menu */ + erase_window_part(swin, 0, 0, nc_bar, nl_bar); + config_bar(); + while ((ch = wgetch(swin)) != 'q') { + switch (ch) { + case 'C': + case 'c': + if (has_colors()) { + colorize = true; + colr = color_config(colr); + custom_init_attr(colr); + } else { + colorize = false; + erase_window_part(swin, 0, 0, + nc_bar, + nl_bar); + mvwprintw(swin, 0, 0, + _(no_color_support)); + wgetch(swin); + } + break; + case 'L': + case 'l': + layout = layout_config(layout, colr); + break; + case 'G': + case 'g': + general_config(); + break; + } + reinit_wins(); + erase_window_part(swin, 0, 0, nc_bar, nl_bar); + config_bar(); + } + update_windows(which_pan); + break; + + case 'A': + case 'a': /* Add an item */ + if (which_pan == APPOINTMENT) { + add_item(); + do_storage = true; + } + if (which_pan == TODO) add_todo(); + break; + + case 'D': + case 'd': /* Delete an item */ + del_apoint(); + do_storage = true; + break; + + case '?': /* Online help system */ + status_bar(which_pan, colr, nc_bar, nl_bar); + help_screen(which_pan, colr); + break; + + case 'S': + case 's': /* Save function */ + save_cal(auto_save, confirm_quit, + confirm_delete, skip_system_dialogs, + skip_progress_bar, week_begins_on_monday, + colr, layout); + break; + + case (261): /* right arrow */ + case ('L'): + case ('l'): + if (which_pan == CALENDAR) { + do_storage = true; + day_changed = true; + if ((sel_day == 31) & (sel_month == 12)) + { /* goto next year */ + sel_day = 0; + sel_month = 1; + sel_year++; + } + if (sel_day == days[sel_month - 1]) + { /* goto next month */ + sel_month = sel_month + 1; + sel_day = 1; + } else + sel_day = sel_day + 1; + } + break; + + case (260): /* left arrow */ + case ('H'): + case ('h'): + if (which_pan == CALENDAR) { + do_storage = true; + day_changed = true; + if ((sel_day == 1) & (sel_month == 1)) + { /* goto previous year */ + sel_day = 32; + sel_month = 12; + sel_year--; + } + if (sel_day == 1) + { /* goto previous month */ + sel_day = days[sel_month - 2]; + sel_month = sel_month - 1; + } else + sel_day = sel_day - 1; + } + break; + + case (259): /* up arrow */ + case ('K'): + case ('k'): + if (which_pan == CALENDAR) { + do_storage = true; + day_changed = true; + if ((sel_day <= 7) & (sel_month == 1)) + { /* goto previous year */ + sel_day = 31 - (7 - sel_day); + sel_month = 12; + sel_year--; + break; + } + if (sel_day <= 7) + { /* goto previous month */ + sel_day = days[sel_month - 2] - + (7 - sel_day); + sel_month = sel_month - 1; + } else /* previous week */ + sel_day = sel_day - 7; + } else { + if ((which_pan == APPOINTMENT) & (hilt_app > 1)) { + hilt_app--; + scroll_pad_up(hilt_app, + number_events_inday); + } + if ((which_pan == TODO) & (hilt_tod > 1)) { + hilt_tod--; + if (hilt_tod < first_todo_onscreen) + first_todo_onscreen--; + } + } + break; + + case (258): /* down arrow */ + case ('J'): + case ('j'): + if (which_pan == CALENDAR) { + do_storage = true; + day_changed = true; + if ((sel_day > days[sel_month - 1] - 7) & + (sel_month == 12)) + { /* next year */ + sel_day = (7 - (31 - sel_day)); + sel_month = 1; + sel_year++; + break; + } + if (sel_day > days[sel_month - 1] - 7) + { /* next month */ + sel_day = (7 - (days[sel_month - 1] - + sel_day)); + sel_month = sel_month + 1; + } else /* next week */ + sel_day = sel_day + 7; + } else { + if ((which_pan == APPOINTMENT) & (hilt_app < number_events_inday + number_apoints_inday)) + { + hilt_app++; + scroll_pad_down(hilt_app, + number_events_inday, + nl_app); + } + if ((which_pan == TODO) & (hilt_tod < nb_tod)) { + ++hilt_tod; + if (hilt_tod - first_todo_onscreen == + nl_tod - 4) + ++first_todo_onscreen; + } + } + break; + + case ('Q'): /* Quit calcurse :-( */ + case ('q'): + if (auto_save) + save_cal(auto_save,confirm_quit, + confirm_delete, skip_system_dialogs, + skip_progress_bar, + week_begins_on_monday, + colr, layout); + if (confirm_quit) { + status_mesg(_(quit_message), choices); + ch = wgetch(swin); + if ( ch == 'y' ) { + endwin(); + erase(); + return EXIT_SUCCESS; + } else { + erase_window_part(swin, 0, 0, nc_bar, nl_bar); + break; + } + } else { + endwin(); + erase(); + return EXIT_SUCCESS; + } + break; + + } /* end case statement */ + if (do_storage) { + store_day(sel_year, sel_month, sel_day, day_changed); + do_storage = !do_storage; + if (day_changed) { + sav_hilt_app = 0; + day_changed = !day_changed; + } + } + update_windows(which_pan); + } +} /* end of interactive mode */ + +/* + * EXTERNAL FUNCTIONS + */ + +/* + * Variables init + */ +void init_vars(int colr) +{ + // Variables for user configuration + confirm_quit = true; + confirm_delete = true; + auto_save = true; + skip_system_dialogs = false; + skip_progress_bar = false; + week_begins_on_monday = true; + + // Pad structure for scrolling text inside the appointment panel + apad = (struct pad_s *) malloc(sizeof(struct pad_s)); + apad->width = nc_app - 3; + apad->length = 1; + apad->first_onscreen = 0; + apad->ptrwin = newpad(apad->length, apad->width); + + // Attribute definitions for color and non-color terminals + custom_init_attr(colr); +} + +/* + * Update all of the three windows and put a border around the + * selected window. + */ +void update_windows(int surrounded_window) +{ + if (surrounded_window == CALENDAR) { + border_color(cwin, colr); + border_nocolor(awin); + border_nocolor(twin); + } else if (surrounded_window == APPOINTMENT) { + border_color(awin, colr); + border_nocolor(cwin); + border_nocolor(twin); + } else if (surrounded_window == TODO) { + border_color(twin, colr); + border_nocolor(awin); + border_nocolor(cwin); + } else { + /* NOTREACHED */ + fputs(_("FATAL ERROR in update_windows: no window selected\n"),stderr); + exit(EXIT_FAILURE); + } + update_app_panel(sel_year, sel_month, sel_day); + update_todo_panel(); + update_cal_panel(cwin, nl_cal, nc_cal, sel_month, + sel_year, sel_day, day, month, year, + week_begins_on_monday); + status_bar(surrounded_window, colr, nc_bar, nl_bar); + wmove(swin, 0, 0); + doupdate(); +} + +/* + * Get the screen size and recalculate the windows configurations. + */ +void get_screen_config(void) +{ + /* Get the screen configuration */ + getmaxyx(stdscr, row, col); + + /* window size definition */ + nl_cal = 12; + nc_cal = 30; + nc_app = col - nc_cal; + nl_app = row - 2; + nc_tod = nc_cal; + nl_tod = row - (nl_cal + 2); + nl_app = row - 2; + nl_bar = 2; y_bar = row - 2; + nc_bar = col; x_bar = 0; + + /* defining the layout */ + switch (layout) { + case 1: + y_app = 0; x_app = 0; y_cal = 0; + x_tod = nc_app; y_tod = nl_cal; x_cal = nc_app; + break; + case 2: + y_app = 0; x_app = 0; y_tod = 0; + x_tod = nc_app; x_cal = nc_app; y_cal = nl_tod; + break; + case 3: + y_app = 0; x_tod = 0; x_cal = 0; y_cal = 0; + x_app = nc_cal; y_tod = nl_cal; + break; + case 4: + y_app = 0; x_tod = 0; y_tod = 0; x_cal = 0; + x_app = nc_cal; y_cal = nl_tod; + break; + } +} + + + +/* Get current date */ +void get_date(void) +{ + timer = time(NULL); + ptrtime = localtime(&timer); + strftime(current_time, 15, "%H:%M%p", ptrtime); + strftime(cal_date, 30, "%a %B %Y", ptrtime); + strftime(current_day, 3, "%d", ptrtime); + strftime(current_month, 3, "%m", ptrtime); + strftime(current_year, 5, "%Y", ptrtime); + month = atoi(current_month); + day = atoi(current_day); + year = atoi(current_year); + sel_year = year; + sel_month = month; + sel_day = day; +} + +/* Create all the windows */ +void init_wins(void) +{ + char label[80]; + + /* Create the three main windows plus the status bar. */ + cwin = newwin(nl_cal, nc_cal, y_cal, x_cal); + sprintf(label, _("Calendar")); + win_show(cwin, label); + awin = newwin(nl_app, nc_app, y_app, x_app); + sprintf(label, _("Appointments")); + win_show(awin, label); + twin = newwin(nl_tod, nc_tod, y_tod, x_tod); + sprintf(label, _("ToDo")); + win_show(twin, label); + swin = newwin(nl_bar, nc_bar, y_bar, x_bar); + + /* Enable function keys (i.e. arrow keys) in those windows */ + keypad(swin, TRUE); + keypad(twin, TRUE); + keypad(awin, TRUE); + keypad(cwin, TRUE); +} + +/* + * Delete the existing windows and recreate them with their new + * size and placement. + */ +void reinit_wins(void) +{ + clear(); + delwin(swin); + delwin(cwin); + delwin(awin); + delwin(twin); + get_screen_config(); + init_wins(); + update_windows(which_pan); +} + +/* General configuration */ +void general_config(void) +{ + WINDOW *conf_win; + char label[80]; + char *number_str = _("Enter an option number to change its value [Q to quit] "); + int ch; + + clear(); + conf_win = newwin(row - 2, col, 0, 0); + box(conf_win, 0, 0); + sprintf(label, _("CalCurse %s | general options"), VERSION); + win_show(conf_win, label); + status_mesg(number_str, ""); + print_general_options(conf_win); + while ((ch = wgetch(swin)) != 'q') { + switch (ch) { + case '1': + auto_save = !auto_save; + break; + case '2': + confirm_quit = !confirm_quit; + break; + case '3': + confirm_delete = !confirm_delete; + break; + case '4': + skip_system_dialogs = + !skip_system_dialogs; + break; + case '5': + skip_progress_bar = + !skip_progress_bar; + break; + case '6': + week_begins_on_monday = + !week_begins_on_monday; + break; + } + print_general_options(conf_win); + } + delwin(conf_win); +} + +/* prints the general options */ +void print_general_options(WINDOW *win) +{ + int x_pos, y_pos; + char *option1 = _("auto_save = "); + char *option2 = _("confirm_quit = "); + char *option3 = _("confirm_delete = "); + char *option4 = _("skip_system_dialogs = "); + char *option5 = _("skip_progress_bar = "); + char *option6 = _("week_begins_on_monday = "); + + x_pos = 3; + y_pos = 4; + + mvwprintw(win, y_pos, x_pos, "[1] %s ", option1); + print_option_incolor(win, auto_save, y_pos, + x_pos + 4 + strlen(option1)); + mvwprintw(win, y_pos + 1, x_pos, + _("(if set to YES, automatic save is done when quitting)")); + + mvwprintw(win, y_pos + 3, x_pos, "[2] %s ", option2); + print_option_incolor(win, confirm_quit, y_pos + 3, + x_pos + 4 + strlen(option2)); + mvwprintw(win, y_pos + 4, x_pos, + _("(if set to YES, confirmation is required before quitting)")); + + mvwprintw(win, y_pos + 6, x_pos, "[3] %s ", option3); + print_option_incolor(win, confirm_delete, y_pos + 6, + x_pos + 4 + strlen(option3)); + mvwprintw(win, y_pos + 7, x_pos, + _("(if set to YES, confirmation is required before deleting an event)")); + + mvwprintw(win, y_pos + 9, x_pos, "[4] %s ", option4); + print_option_incolor(win, skip_system_dialogs, y_pos + 9, + x_pos + 4 + strlen(option4)); + mvwprintw(win, y_pos + 10, x_pos, + _("(if set to YES, messages about loaded and saved data will not be displayed)")); + + mvwprintw(win, y_pos + 12, x_pos, "[5] %s ", option5); + print_option_incolor(win, skip_progress_bar , y_pos + 12, + x_pos + 4 + strlen(option5)); + mvwprintw(win, y_pos + 13, x_pos, + _("(if set to YES, progress bar will not be displayed when saving data)")); + + mvwprintw(win, y_pos + 15, x_pos, "[6] %s ", option6); + print_option_incolor(win, week_begins_on_monday , y_pos + 15, + x_pos + 4 + strlen(option6)); + mvwprintw(win, y_pos + 16, x_pos, + _("(if set to YES, monday is the first day of the week, else it is sunday)")); + + wmove(swin, 1, 0); + wnoutrefresh(win); + doupdate(); +} + +/* print the option value with appropriate color */ +void print_option_incolor(WINDOW *win, bool option, int pos_y, int pos_x) +{ + int color; + char *option_value; + + if (option == true) { + color = ATTR_TRUE; + option_value = _("yes"); + } else if (option == false) { + color = ATTR_FALSE; + option_value = _("no"); + } else { + erase_window_part(win, 0, 0, col, row - 2); + mvwprintw(win, 1, 1, + _("option not defined - Problem in print_option_incolor()")); + wnoutrefresh(win); + doupdate(); + wgetch(win); + exit(EXIT_FAILURE); + } + custom_apply_attr(win, color); + mvwprintw(win, pos_y, pos_x, "%s", option_value); + custom_remove_attr(win, color); + wnoutrefresh(win); + doupdate(); +} + + /* Delete an event from the ToDo or Appointment lists */ +void del_apoint(void) +{ + char *choices = "[y/n] "; + char *del_app_str = _("Do you really want to delete this item ?"); + char *del_todo_str = _("Do you really want to delete this task ?"); + long date; + int nb_items = number_apoints_inday + number_events_inday; + bool go_for_deletion = false; + bool go_for_todo_del = false; + int to_be_removed = 0; + int answer = 0; + + /* delete an appointment */ + if (which_pan == APPOINTMENT && hilt_app != 0) { + date = date2sec(sel_year, sel_month, sel_day, 0, 0); + + if (confirm_delete) { + status_mesg(del_app_str, choices); + answer = wgetch(swin); + if ( (answer == 'y') && (nb_items != 0) ) + go_for_deletion = true; + else { + erase_window_part(swin, 0, 0, nc_bar, nl_bar); + return; + } + } else + if (nb_items != 0) + go_for_deletion = true; + + if (go_for_deletion) { + if (nb_items != 0) { + if (hilt_app <= number_events_inday) { + event_delete_bynum(date, hilt_app - 1); + number_events_inday--; + to_be_removed = 1; + } else { + apoint_delete_bynum(date, + hilt_app - + number_events_inday - 1); + number_apoints_inday--; + to_be_removed = 3; + } + if (hilt_app > 1) --hilt_app; + if (apad->first_onscreen >= to_be_removed) + apad->first_onscreen = + apad->first_onscreen - + to_be_removed; + } + } + + /* delete a todo */ + } else if (which_pan == TODO && hilt_tod != 0) { + if (confirm_delete) { + status_mesg(del_todo_str, choices); + answer = wgetch(swin); + if ( (answer == 'y') && (nb_tod > 0) ) { + go_for_todo_del = true; + } else { + erase_window_part(swin, 0, 0, nc_bar, nl_bar); + return; + } + } else + if (nb_tod > 0) + go_for_todo_del = true; + + if (go_for_todo_del) { + todo_delete_bynum(hilt_tod - 1); + nb_tod--; + if (hilt_tod > 1) hilt_tod--; + } + } +} + + /* Add an item in the ToDo list */ +void add_todo(void) +{ + char *mesg = _("Enter the new ToDo item : "); + char todo_input[500]; + + status_mesg(mesg, ""); + getstring(swin, colr, todo_input, 0, 1); + if (strlen(todo_input) != 0) { + todo_insert(todo_input); + ++nb_tod; + update_todo_panel(); + } + erase_window_part(swin, 0, 0, nc_bar, nl_bar); + status_bar(which_pan, colr, nc_bar, nl_bar); + doupdate(); +} + +/* + * Add an item in either the appointment or the event list, + * depending if the start time is entered or not. + */ +void add_item(void) +{ + char *mesg_1 = _("Enter start time ([hh:mm] or [h:mm]), leave blank for an all-day event : "); + char *mesg_2 = _("Enter end time ([hh:mm] or [h:mm]) or duration (in minutes) : "); + char *mesg_3 = _("Enter description :"); + char *format_message_1 = _("You entered an invalid start time, should be [h:mm] or [hh:mm]"); + char *format_message_2 = _("You entered an invalid end time, should be [h:mm] or [hh:mm] or [mm]"); + char *enter_str = _("Press [Enter] to continue"); + int Id; + char item_time[500]; + char item_mesg[500]; + long apoint_duration; + struct apoint_s *apoint_pointeur; + struct event_s *event_pointeur; + unsigned heures, minutes; + unsigned end_h, end_m; + int is_appointment = 1; + + /* Get the starting time */ + strcpy(item_time, " "); + while (check_time(item_time) == 0) { + status_mesg(mesg_1, ""); + getstring(swin, colr, item_time, 0, 1); + if (strlen(item_time) == 0){ + is_appointment = 0; + break; + } else if (check_time(item_time) != 1) { + status_mesg(format_message_1, enter_str); + wgetch(swin); + } else + sscanf(item_time, "%u:%u", &heures, &minutes); + } + /* + * Check if an event or appointment is entered, + * depending on the starting time, and record the + * corresponding item. + */ + if (is_appointment){ /* Get the appointment duration */ + strcpy(item_time, " "); + while (check_time(item_time) == 0) { + status_mesg(mesg_2, ""); + getstring(swin, colr, item_time, 0, 1); + if (strlen(item_time) == 0) + return; //nothing entered, cancel adding of event + else if (check_time(item_time) == 0) { + status_mesg(format_message_2, enter_str); + wgetch(swin); + } else { + if (check_time(item_time) == 2) + apoint_duration = atoi(item_time); + else if (check_time(item_time) == 1) { + sscanf(item_time, "%u:%u", + &end_h, &end_m); + if (end_h < heures){ + apoint_duration = + (60 - minutes + end_m) + + (24 + end_h - (heures + 1))*60; + } else { + apoint_duration = + (60 - minutes + end_m) + + (end_h - (heures + 1))*60; + } + } + } + } + } else { /* Insert the event Id */ + Id = 1; + } + // get the item description + status_mesg(mesg_3, ""); + getstring(swin, colr, item_mesg, 0, 1); + if (strlen(item_mesg) != 0) { + if (is_appointment){ + // insert the appointment in list + apoint_pointeur = + apoint_new(item_mesg, + date2sec(sel_year, sel_month, sel_day, + heures, minutes), + min2sec(apoint_duration)); + // insert the event in list + } else { + event_pointeur = event_new(item_mesg, date2sec( + sel_year, + sel_month, + sel_day, + 12, 0), + Id); + } + update_app_panel(sel_year, sel_month, sel_day); + } + erase_window_part(swin, 0, 0, nc_bar, nl_bar); + status_bar(which_pan, colr, nc_bar, nl_bar); + doupdate(); +} + +/* Updates the ToDo panel */ +void update_todo_panel(void) +{ + struct todo_s *i; + int len = nc_tod - 5; + int num_todo = 0; + int y_offset = 3, x_offset = 1; + int t_realpos = -1; + int title_lines = 3; + int todo_lines = 1; + int max_items = nl_tod - 4; + int incolor = -1; + + /* Print todo item in the panel. */ + erase_window_part(twin, 1, title_lines, nc_tod - 2, nl_tod - 2); + for (i = todolist; i != 0; i = i->next) { + num_todo++; + t_realpos = num_todo - first_todo_onscreen; + incolor = num_todo - hilt_tod; + if (incolor == 0) saved_t_mesg = i->mesg; + if (t_realpos >= 0 && t_realpos < max_items) { + display_item(twin, incolor, i->mesg, + len, y_offset, x_offset); + y_offset = y_offset + todo_lines; + } + } + + /* Draw the scrollbar if necessary. */ + if (nb_tod > max_items){ + float ratio = ((float) max_items) / ((float) nb_tod); + int sbar_length = (int) (ratio * (max_items + 1)); + int highend = (int) (ratio * first_todo_onscreen); + bool hilt_bar = (which_pan == TODO) ? true : false; + int sbar_top = highend + title_lines; + + if ((sbar_top + sbar_length) > nl_tod - 1) + sbar_length = nl_tod - 1 - sbar_top; + draw_scrollbar(twin, sbar_top, nc_tod - 2, + sbar_length, title_lines, nl_tod - 1, hilt_bar); + } + + wnoutrefresh(twin); +} + +/* Updates the Appointment panel */ +void update_app_panel(int year, int month, int day) +{ + int title_xpos; + int bordr = 1; + int title_lines = 3; + int app_width = nc_app - bordr; + int app_length = nl_app - bordr - title_lines; + long date; + + /* variable inits */ + title_xpos = nc_app - (strlen(_(monthnames[sel_month - 1])) + 11); + if (sel_day < 10) title_xpos++; + date = date2sec(year, month, day, 0, 0); + day_write_pad(date, app_width, app_length, hilt_app, colr); + + /* Print current date in the top right window corner. */ + erase_window_part(awin, 1, title_lines, nc_app - 2, nl_app - 2); + custom_apply_attr(awin, ATTR_HIGHEST); + mvwprintw(awin, title_lines, title_xpos, "%s %d, %d", + _(monthnames[sel_month - 1]), sel_day, sel_year); + custom_remove_attr(awin, ATTR_HIGHEST); + + /* Draw the scrollbar if necessary. */ + if ((apad->length >= app_length)||(apad->first_onscreen > 0)) { + float ratio = ((float) app_length) / ((float) apad->length); + int sbar_length = (int) (ratio * app_length); + int highend = (int) (ratio * apad->first_onscreen); + bool hilt_bar = (which_pan == APPOINTMENT) ? true : false; + int sbar_top = highend + title_lines + 1; + + if ((sbar_top + sbar_length) > nl_app - 1) + sbar_length = nl_app - 1 - sbar_top; + draw_scrollbar(awin, sbar_top, nc_app - 2, sbar_length, + title_lines + 1, nl_app - 1, hilt_bar); + } + + wnoutrefresh(awin); + pnoutrefresh(apad->ptrwin, apad->first_onscreen, 0, + y_app + title_lines + 1, x_app + bordr, + y_app + nl_app - 2*bordr, x_app + nc_app - 2*bordr); +} + +/* + * Store the events and appointments for the selected day, and write + * those items in a pad. + * This is useful to speed up the appointment panel update. + */ +void store_day(int year, int month, int day, bool day_changed) +{ + long date; + date = date2sec(year, month, day, 0, 0); + + /* Inits */ + if (apad->length != 0) + delwin(apad->ptrwin); + + /* Store the events and appointments (recursive and normal items). */ + apad->length = day_store_items(date, + &number_events_inday, &number_apoints_inday); + + /* Create the new pad with its new length. */ + if (day_changed) apad->first_onscreen = 0; + apad->ptrwin = newpad(apad->length, apad->width); +} + +/* Load the user configuration */ +void load_conf(void) +{ + FILE *data_file; + char *mesg_line1 = _("Failed to open config file"); + char *mesg_line2 = _("Press [ENTER] to continue"); + char buf[100], e_conf[100]; + int var; + + data_file = fopen(path_conf, "r"); + if (data_file == NULL) { + status_mesg(mesg_line1, mesg_line2); + wnoutrefresh(swin); + doupdate(); + wgetch(swin); + } + var = 0; + for (;;) { + if (fgets(buf, 99, data_file) == NULL) { + break; + } + extract_data(e_conf, buf, strlen(buf)); + if (var == 1) { + auto_save = + fill_config_var(e_conf); + var = 0; + } else if (var == 2) { + confirm_quit = + fill_config_var(e_conf); + var = 0; + } else if (var == 3) { + confirm_delete = + fill_config_var(e_conf); + var = 0; + } else if (var == 4) { + skip_system_dialogs = + fill_config_var(e_conf); + var = 0; + } else if (var == 5) { + skip_progress_bar = + fill_config_var(e_conf); + var = 0; + } else if (var == 6) { + week_begins_on_monday = + fill_config_var(e_conf); + var = 0; + } else if (var == 7) { + colr = atoi(e_conf); + if (colr == 0) colorize = false; + var = 0; + } else if (var == 8) { + layout = atoi(e_conf); + var = 0; + } + if (strncmp(e_conf, "auto_save=", 10) == 0) + var = 1; + else if (strncmp(e_conf, "confirm_quit=", 13) == 0) + var = 2; + else if (strncmp(e_conf, "confirm_delete=", 15) == 0) + var = 3; + else if (strncmp(e_conf, "skip_system_dialogs=", 20) == 0) + var = 4; + else if (strncmp(e_conf, "skip_progress_bar=", 18) == 0) + var = 5; + else if (strncmp(e_conf, "week_begins_on_monday=", 23) == 0) + var = 6; + else if (strncmp(e_conf, "color-theme=", 12) == 0) + var = 7; + else if (strncmp(e_conf, "layout=", 7) == 0) + var = 8; + } + fclose(data_file); + erase_window_part(swin, 0, 0, nc_bar, nl_bar); +} + +bool fill_config_var (char *string) { + if (strncmp(string, "yes", 3) == 0) + return true; + else if (strncmp(string, "no", 2) == 0) + return false; + else { + fputs(_("FATAL ERROR in fill_config_var: " + "wrong configuration variable format.\n"), stderr); + return EXIT_FAILURE; + } +} diff --git a/src/calendar.c b/src/calendar.c new file mode 100755 index 0000000..c147e47 --- /dev/null +++ b/src/calendar.c @@ -0,0 +1,227 @@ +/* $calcurse: calendar.c,v 1.1 2006/07/31 21:00:02 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#include <ncurses.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <time.h> + +#include "i18n.h" +#include "day.h" +#include "apoint.h" +#include "event.h" +#include "calendar.h" +#include "custom.h" +#include "vars.h" +#include "utils.h" + +static unsigned months_to_days(unsigned); +static long years_to_days(unsigned); + + /* Load the calendar */ +void +update_cal_panel(WINDOW *cwin, int nl_cal, + int nc_cal, int sel_month, int sel_year, int sel_day, + int day, int month, int year, + bool monday_first) +{ + int c_day, c_day_1, day_1_sav, numdays, j; + unsigned yr, mo; + int ofs_x, ofs_y; + int item_this_day = 0; + int title_lines = 3; + int sunday_first = 0; + + // Inits + erase_window_part(cwin, 1, title_lines, nc_cal - 2, nl_cal - 2); + mo = sel_month; + yr = sel_year; + if (!monday_first) sunday_first = 1; + + // Offset for centering calendar in window + ofs_y = 2 + (nl_cal - 9) / 2; + ofs_x = (nc_cal - 27) / 2; + + + //checking the number of days in february + numdays = days[mo - 1]; + if (2 == mo && isBissextile(yr)) + ++numdays; + + //the first calendar day will be monday or sunday, depending on the + //value of week_begins_on_monday + 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 + custom_apply_attr(cwin, ATTR_HIGH); + mvwprintw(cwin, ofs_y, + (nc_cal - (strlen(_(monthnames[mo - 1])) + 5)) / 2, + "%s %d", _(monthnames[mo - 1]), sel_year); + custom_remove_attr(cwin, ATTR_HIGH); + ++ofs_y; + + //prints the days, with regards to the first day of the week + custom_apply_attr(cwin, ATTR_HIGH); + for (j = 0; j < 7; j++) { + mvwprintw(cwin, ofs_y, ofs_x + 4 * j, "%s", + _(daynames[1 + j - sunday_first])); + } + custom_remove_attr(cwin, ATTR_HIGH); + + day_1_sav = (c_day_1 + 1) * 3 + c_day_1 - 7; + + for (c_day = 1; c_day <= numdays; ++c_day, ++c_day_1, c_day_1 %= 7) { + //check if the day contains an event or an appointment + item_this_day = day_check_if_item(sel_year, sel_month, c_day); + + /* Go to next line, the week is over. */ + if (!c_day_1 && 1 != c_day) { + ++ofs_y; + ofs_x = 2 - day_1_sav - 4 * c_day - 1; + } + /* This is today, so print it in yellow. */ + if (c_day == day && month == sel_month + && year == sel_year && day != sel_day) + { + custom_apply_attr(cwin, ATTR_LOWEST); + mvwprintw(cwin, ofs_y + 1, + ofs_x + day_1_sav + 4 * c_day + 1, "%2d", + c_day); + custom_remove_attr(cwin, ATTR_LOWEST); + } else if (c_day == sel_day && ( (day != sel_day) | + (month != sel_month) | (year != sel_year) )) + /* This is the selected day, print it in red. */ + { + custom_apply_attr(cwin, ATTR_MIDDLE); + mvwprintw(cwin, ofs_y + 1, + ofs_x + day_1_sav + 4 * c_day + 1, "%2d", + c_day); + custom_remove_attr(cwin, ATTR_MIDDLE); + } else if (c_day == sel_day && day == sel_day && month == sel_month && year == sel_year) //today is the selected day + { + custom_apply_attr(cwin, ATTR_MIDDLE); + mvwprintw(cwin, ofs_y + 1, + ofs_x + day_1_sav + 4 * c_day + 1, "%2d", + c_day); + custom_remove_attr(cwin, ATTR_MIDDLE); + } else if (item_this_day) { + custom_apply_attr(cwin, ATTR_LOW); + mvwprintw(cwin, ofs_y + 1, + ofs_x + day_1_sav + 4 * c_day + 1, "%2d", + c_day); + custom_remove_attr(cwin, ATTR_LOW); + } + + else // otherwise, print normal days in black + mvwprintw(cwin, ofs_y + 1, + ofs_x + day_1_sav + 4 * c_day + 1, "%2d", + c_day); + + } + wnoutrefresh(cwin); +} + +int isBissextile(unsigned annee) +{ + return annee % 400 == 0 || (annee % 4 == 0 && annee % 100 != 0); +} + +// convertion functions +unsigned months_to_days(unsigned mois) +{ + return (mois * 3057 - 3007) / 100; +} + + +long years_to_days(unsigned annee) +{ + return annee * 365L + annee / 4 - annee / 100 + annee / 400; +} + +long ymd_to_scalar(unsigned annee, unsigned mois, unsigned jour) +{ + long scalaire; + scalaire = jour + months_to_days(mois); + if (mois > 2) + scalaire -= isBissextile(annee) ? 1 : 2; + annee--; + scalaire += years_to_days(annee); + return scalaire; +} + +/* + * 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. + * day, month, year are the current day given to that routine, and + * sel_day, sel_month and sel_year represent the day given back. + */ +void +goto_day(int colr, int day, int month, int year, + int *sel_day, int *sel_month, int *sel_year) +{ + char selected_day[50] = ""; + int dday, dmonth, dyear; + int wrong_day = 0; + char *mesg_line1 = _("The day you entered is not valid"); + char *mesg_line2 = _("Press [ENTER] to continue"); + char *request_date = _("Enter the day to go to [ENTER for today] : dd/mm/yyyy"); + + while (wrong_day != 1) { + status_mesg(request_date, ""); + getstring(swin, colr, selected_day, 0, 1); + if (strlen(selected_day) == 0) // go to today + { + *sel_day = day; + *sel_month = month; + *sel_year = year; + break; + } else { + sscanf(selected_day, "%u/%u/%u", &dday, &dmonth, + &dyear); + //check if the entered day is correct + if ((dday <= 0) | (dday >= 32)) + wrong_day = 1; + if ((dmonth <= 0) | (dmonth >= 13)) + wrong_day = 1; + if ((dyear <= 0) | (dyear >= 3000)) + wrong_day = 1; + //go to chosen day + if (wrong_day != 1) { + *sel_day = dday; + *sel_month = dmonth; + *sel_year = dyear; + } else { + status_mesg(mesg_line1, mesg_line2); + wgetch(swin); + } + break; + } + } + return; +} diff --git a/src/calendar.h b/src/calendar.h new file mode 100755 index 0000000..a8cb3ea --- /dev/null +++ b/src/calendar.h @@ -0,0 +1,41 @@ +/* $calcurse: calendar.h,v 1.1 2006/07/31 21:00:02 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#ifndef CALCURSE_CALENDAR_H +#define CALCURSE_CALENDAR_H + +#include <stdbool.h> + +void update_cal_panel(WINDOW *cwin, int nl_cal, + int nc_cal, int sel_month, int sel_year, int sel_day, + int day, int month, int year, + bool monday_first); +int isBissextile(unsigned); +long ymd_to_scalar(unsigned, unsigned, unsigned); +void goto_day(int colr, int day, int month, int year, + int *sel_day, int *sel_month, int *sel_year); + +#endif /* CALCURSE_CALENDAR_H */ diff --git a/src/custom.c b/src/custom.c new file mode 100755 index 0000000..4a2ea72 --- /dev/null +++ b/src/custom.c @@ -0,0 +1,178 @@ +/* $calcurse: custom.c,v 1.1 2006/07/31 21:00:02 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#include <ncurses.h> + +#include "i18n.h" +#include "utils.h" +#include "custom.h" +#include "vars.h" + +static struct attribute_s attr; + +/* + * Define window attributes (for both color and non-color terminals): + * ATTR_HIGHEST are for window titles + * ATTR_HIGH are for month and days names + * ATTR_MIDDLE are for the selected day inside calendar panel + * ATTR_LOW are for days inside calendar panel which contains an event + * ATTR_LOWEST are for current day inside calendar panel + */ +void custom_init_attr(int colr) +{ + attr.color[ATTR_HIGHEST] = COLOR_PAIR(colr); + attr.color[ATTR_HIGH] = COLOR_PAIR(6); + attr.color[ATTR_MIDDLE] = COLOR_PAIR(1); + attr.color[ATTR_LOW] = COLOR_PAIR(4); + attr.color[ATTR_LOWEST] = COLOR_PAIR(5); + attr.color[ATTR_TRUE] = COLOR_PAIR(2); + attr.color[ATTR_FALSE] = COLOR_PAIR(1); + + attr.nocolor[ATTR_HIGHEST] = A_BOLD; + attr.nocolor[ATTR_HIGH] = A_REVERSE; + attr.nocolor[ATTR_MIDDLE] = A_REVERSE; + attr.nocolor[ATTR_LOW] = A_UNDERLINE; + attr.nocolor[ATTR_LOWEST] = A_BOLD; + attr.nocolor[ATTR_TRUE] = A_BOLD; + attr.nocolor[ATTR_FALSE] = A_DIM; +} + +/* Apply window attribute */ +void custom_apply_attr(WINDOW *win, int attr_num) +{ + if (colorize) + wattron(win, attr.color[attr_num]); + else + wattron(win, attr.nocolor[attr_num]); +} + +/* Remove window attribute */ +void custom_remove_attr(WINDOW *win, int attr_num) +{ + if (colorize) + wattroff(win, attr.color[attr_num]); + else + wattroff(win, attr.nocolor[attr_num]); +} + +/* Draws the configuration bar */ +void config_bar() +{ + int smlspc, spc; + + smlspc = 2; + spc = 15; + + custom_apply_attr(swin, ATTR_HIGHEST); + mvwprintw(swin, 0, 2, "Q"); + mvwprintw(swin, 1, 2, "G"); + mvwprintw(swin, 0, 2 + spc, "L"); + mvwprintw(swin, 1, 2 + spc, "C"); + custom_remove_attr(swin, ATTR_HIGHEST); + + mvwprintw(swin, 0, 2 + smlspc, _("Exit")); + mvwprintw(swin, 1, 2 + smlspc, _("General")); + mvwprintw(swin, 0, 2 + spc + smlspc, _("Layout")); + mvwprintw(swin, 1, 2 + spc + smlspc, _("Color")); + + wnoutrefresh(swin); + wmove(swin, 0, 0); + doupdate(); +} + +/* Choose the layout */ +int layout_config(int layout, int colr) +{ + int ch, old_layout; + char *layout_mesg = _("Pick the desired layout on next screen [press ENTER]"); + char *choice_mesg = _("('A'= Appointment panel, 'c'= calendar panel, 't'= todo panel)"); + char *layout_up_mesg = _(" |Ac| |At| |cA| |tA|"); + char *layout_down_mesg = _("[1]|At| [2]|Ac| [3]|tA| [4]|cA|"); + + old_layout = layout; + status_mesg(layout_mesg, choice_mesg); + wgetch(swin); + status_mesg(layout_up_mesg, layout_down_mesg); + wnoutrefresh(swin); + doupdate(); + while ((ch = wgetch(swin)) != 'q') { + switch (ch) { + case '1': + layout = 1; + return layout; + case '2': + layout = 2; + return layout; + case '3': + layout = 3; + return layout; + case '4': + layout = 4; + return layout; + } + } + layout = old_layout; + return layout; +} + +/* Choose the color theme */ +int color_config(int colr) +{ + int ascii2dec = 48; + int i, ch, old_colr; + int max_colors = 9; + int spc = 6; + char *choose_color = _("Pick the number corresponding to the color scheme " + "(Q to exit) :"); + + old_colr = colr; + erase_window_part(swin, 0, 0, col, 2); + for (i = 1; i < max_colors; i++) { + wattron(swin, COLOR_PAIR(i)); + mvwprintw(swin, 1, (i - 1) * spc, "[>%d<]", i); + wattroff(swin, COLOR_PAIR(i)); + } + mvwprintw(swin, 1, 50, _("([>0<] for black & white)")); + custom_apply_attr(swin, ATTR_HIGHEST); + mvwprintw(swin, 0, 0, choose_color); + custom_remove_attr(swin, ATTR_HIGHEST); + wnoutrefresh(swin); + doupdate(); + while ((ch = wgetch(swin)) != 'q') { + ch = ch - ascii2dec; + if ( (ch > 0) && (ch <= max_colors) ) { + colorize = true; + return ch; + } else if (ch == 0) { + colorize = false; + return 0; + } else { + colr = old_colr; + } + } + if (colr == 0) colorize = false; + return colr; +} diff --git a/src/custom.h b/src/custom.h new file mode 100755 index 0000000..a7f133b --- /dev/null +++ b/src/custom.h @@ -0,0 +1,42 @@ +/* $calcurse: custom.h,v 1.1 2006/07/31 21:00:02 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#ifndef CALCURSE_CUSTOM_H +#define CALCURSE_CUSTOM_H + +struct attribute_s { + int color[7]; + int nocolor[7]; +}; + +void custom_init_attr(int colr); +void custom_apply_attr(WINDOW *win, int attr_num); +void custom_remove_attr(WINDOW *win, int attr_num); +void config_bar(); +int layout_config(int layout, int colr); +int color_config(int colr); + +#endif /* CALCURSE_CUSTOM_H */ diff --git a/src/day.c b/src/day.c new file mode 100755 index 0000000..8fd7981 --- /dev/null +++ b/src/day.c @@ -0,0 +1,362 @@ +/* $calcurse: day.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#include <ncurses.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <stdbool.h> +#include <time.h> + +#include "i18n.h" +#include "utils.h" +#include "apoint.h" +#include "event.h" +#include "recur.h" +#include "day.h" +#include "vars.h" + +static struct day_item_s *day_items_ptr; +static struct day_saved_item_s *day_saved_item = NULL; + +/* + * Store all of the items to be displayed for the selected day. + * Items are of four types: recursive events, normal events, + * recursive appointments and normal appointments. + * The items are stored in the linked list pointed by *day_items_ptr + * and the length of the new pad to write is returned. + * The number of events and appointments in the current day are also updated. + */ +int day_store_items(long date, int *pnb_events, int *pnb_apoints) +{ + int pad_length; + int nb_events, nb_recur_events; + int nb_apoints, nb_recur_apoints; + + pad_length = nb_events = nb_apoints = 0; + nb_recur_events = nb_recur_apoints = 0; + + if (day_items_ptr != 0) + day_free_list(); + nb_recur_events = day_store_recur_events(date); + nb_events = day_store_events(date); + *pnb_events = nb_events; + nb_recur_apoints = day_store_recur_apoints(date); + nb_apoints = day_store_apoints(date); + *pnb_apoints = nb_apoints; + pad_length = nb_recur_events + nb_events + 1 + + 3*(nb_recur_apoints + nb_apoints); + *pnb_apoints += nb_recur_apoints; + *pnb_events += nb_recur_events; + + return pad_length; +} + +/* Free the current day linked list containing the events and appointments. */ +void day_free_list(void) +{ + struct day_item_s *p, *q; + + for (p = day_items_ptr; p != 0; p = q) { + q = p->next; + free(p->mesg); + free(p); + } + day_items_ptr = NULL; +} + +/* + * Store the recurrent events for the selected day in structure pointed + * by day_items_ptr. This is done by copying the recurrent events + * from the general structure pointed by recur_elist to the structure + * dedicated to the selected day. + * Returns the number of recurrent events for the selected day. + */ +int day_store_recur_events(long date) +{ + struct recur_event_s *j; + struct day_item_s *ptr; + int e_nb = 0; + + for (j = recur_elist; j != 0; j = j->next) { + if (recur_item_inday(j->day, j->rpt->type, j->rpt->freq, + j->rpt->until, date)) { + e_nb++; + ptr = day_add_event(RECUR_EVNT, j->mesg, j->day, j->id); + } + } + + return e_nb; +} + +/* + * Store the events for the selected day in structure pointed + * by day_items_ptr. This is done by copying the events + * from the general structure pointed by eventlist to the structure + * dedicated to the selected day. + * Returns the number of events for the selected day. + */ +int day_store_events(long date) +{ + struct event_s *j; + struct day_item_s *ptr; + int e_nb = 0; + + for (j = eventlist; j != 0; j = j->next) { + if (event_inday(j, date)) { + e_nb++; + ptr = day_add_event(EVNT, j->mesg, j->day, j->id); + } + } + + return e_nb; +} + +/* + * Store the recurrent apoints for the selected day in structure pointed + * by day_items_ptr. This is done by copying the appointments + * from the general structure pointed by recur_alist to the structure + * dedicated to the selected day. + * Returns the number of recurrent appointments for the selected day. + */ +int day_store_recur_apoints(long date) +{ + struct recur_apoint_s *j; + struct day_item_s *ptr; + int a_nb = 0; + + for (j = recur_alist; j != 0; j = j->next) { + if (recur_item_inday(j->start, j->rpt->type, j->rpt->freq, + j->rpt->until, date)) { + a_nb++; + ptr = day_add_apoint(RECUR_APPT, j->mesg, j->start, j->dur); + } + } + + return a_nb; +} + +/* + * Store the apoints for the selected day in structure pointed + * by day_items_ptr. This is done by copying the appointments + * from the general structure pointed by apointlist to the structure + * dedicated to the selected day. + * Returns the number of appointments for the selected day. + */ +int day_store_apoints(long date) +{ + struct apoint_s *j; + struct day_item_s *ptr; + int a_nb = 0; + + for (j = apointlist; j != 0; j = j->next) { + if (apoint_inday(j, date)) { + a_nb++; + ptr = day_add_apoint(APPT, j->mesg, j->start, j->dur); + } + } + + return a_nb; +} + +/* Add an event in the current day list */ +struct day_item_s *day_add_event(int type, char *mesg, long day, int id) +{ + struct day_item_s *o, **i; + o = (struct day_item_s *) malloc(sizeof(struct day_item_s)); + o->mesg = (char *) malloc(strlen(mesg) + 1); + strcpy(o->mesg, mesg); + o->type = type; + o->appt_dur = 0; + o->start = day; + o->evnt_id = id; + i = &day_items_ptr; + for (;;) { + if (*i == 0 || (*i)->start > day) { + o->next = *i; + *i = o; + break; + } + i = &(*i)->next; + } + return o; +} + +/* Add an appointment in the current day list. */ +struct day_item_s *day_add_apoint(int type, char *mesg, long start, long dur) +{ + struct day_item_s *o, **i; + o = (struct day_item_s *) malloc(sizeof(struct day_item_s)); + o->mesg = (char *) malloc(strlen(mesg) + 1); + strcpy(o->mesg, mesg); + o->start = start; + o->appt_dur = dur; + o->type = type; + o->evnt_id = 0; + i = &day_items_ptr; + for (;;) { + if (*i == 0 || (*i)->start > start) { + o->next = *i; + *i = o; + break; + } + i = &(*i)->next; + } + return o; +} + +/* + * Write the appointments and events for the selected day in a pad. + * An horizontal line is drawn between events and appointments, and the + * item selected by user is highlighted. This item is also saved inside + * structure (pointed by day_saved_item), to be later displayed in a + * popup window if requested. + */ +void day_write_pad(long date, int width, int length, int incolor, int colr) +{ + struct day_item_s *p; + int line, item_number, max_pos; + const int x_pos = 0; + bool draw_line = true; + + line = item_number = 0; + max_pos = length; + + /* Initialize the structure used to store highlited item. */ + if (day_saved_item == NULL) { + day_saved_item = (struct day_saved_item_s *) + malloc(sizeof(struct day_saved_item_s)); + day_saved_item->mesg = (char *) malloc(1); + } + + for (p = day_items_ptr; p != 0; p = p->next) { + + /* First print the events for current day. */ + if (p->type < RECUR_APPT) { + item_number++; + if (item_number - incolor == 0) { + day_saved_item->type = p->type; + day_saved_item->mesg = (char *) + realloc(day_saved_item->mesg, + strlen(p->mesg) + 1); + day_saved_item->mesg = p->mesg; + } + display_item(apad->ptrwin, item_number - incolor, p->mesg, + width - 4, line, x_pos); + line++; + } else { + /* Draw a line between events and appointments. */ + if (line > 0 && draw_line){ + wmove(apad->ptrwin, line, x_pos); + whline(apad->ptrwin, 0, width); + draw_line = false; + } + + /* Last print the appointments for current day. */ + item_number++; + if (item_number - incolor == 0) { + day_saved_item->type = p->type; + day_saved_item->mesg = (char *) + realloc(day_saved_item->mesg, + strlen(p->mesg) + 1); + day_saved_item->mesg = p->mesg; + apoint_sec2str(day_item_s2apoint_s(p), + p->type, date, + day_saved_item->start, + day_saved_item->end); + } + display_item_date(apad->ptrwin, item_number - incolor, + day_item_s2apoint_s(p), p->type, date, + line + 1, x_pos); + display_item(apad->ptrwin, item_number - incolor, p->mesg, + width - 6, line + 2, x_pos + 2); + line = line + 3; + } + } +} + +/* Returns a structure of type apoint_s given a structure of type day_item_s */ +struct apoint_s *day_item_s2apoint_s(struct day_item_s *p) +{ + struct apoint_s *a; + + a = (struct apoint_s *) malloc(sizeof(struct apoint_s)); + a->mesg = (char *) malloc(strlen(p->mesg) + 1); + a->start = p->start; + a->dur = p->appt_dur; + a->mesg = p->mesg; + return a; +} + +/* Display an item inside a popup window. */ +void day_popup_item(void) +{ + char *error = + _("FATAL ERROR in day_popup_item: unknown item type\n"); + + if (day_saved_item->type == EVNT || day_saved_item->type == RECUR_EVNT) + item_in_popup(NULL, NULL, day_saved_item->mesg, _("Event :")); + else if (day_saved_item->type == APPT || + day_saved_item->type == RECUR_APPT) + item_in_popup(day_saved_item->start, day_saved_item->end, + day_saved_item->mesg, _("Appointment :")); + else { /* NOT REACHED */ + fputs(error, stderr); + exit(EXIT_FAILURE); + } +} + +/* + * Need to know if there is an item for the current selected day inside + * calendar. This is used to put the correct colors inside calendar panel. + */ + int day_check_if_item(int year, int month, int day) { + struct recur_event_s *re; + struct recur_apoint_s *ra; + struct event_s *e; + struct apoint_s *a; + const long date = date2sec(year, month, day, 0, 0); + + for (re = recur_elist; re != 0; re = re->next) + if (recur_item_inday(re->day, re->rpt->type, re->rpt->freq, + re->rpt->until, date)) + return 1; + + for (ra = recur_alist; ra != 0; ra = ra->next) + if (recur_item_inday(ra->start, ra->rpt->type, ra->rpt->freq, + ra->rpt->until, date)) + return 1; + + for (e = eventlist; e != 0; e = e->next) + if (event_inday(e, date)) + return 1; + + for (a = apointlist; a != 0; a = a->next) + if (apoint_inday(a, date)) + return 1; + + return 0; +} diff --git a/src/day.h b/src/day.h new file mode 100755 index 0000000..8426704 --- /dev/null +++ b/src/day.h @@ -0,0 +1,66 @@ +/* $calcurse: day.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#ifndef CALCURSE_DAY_H +#define CALCURSE_DAY_H + +#include "apoint.h" + +#define RECUR_EVNT 1 +#define EVNT 2 +#define RECUR_APPT 3 +#define APPT 4 + +struct day_item_s { + struct day_item_s *next; + int type; /* (recursive or normal) event or appointment */ + long start; /* seconds since 1 jan 1970 */ + char *mesg; /* item description */ + int evnt_id; /* event identifier */ + long appt_dur; /* appointment duration in seconds */ +}; + +struct day_saved_item_s { + int type ; + char *mesg; + char start[100]; + char end[100]; +}; + +int day_store_items(long date, int *pnb_events, int *pnb_apoints); +void day_free_list(void); +int day_store_recur_events(long date); +int day_store_events(long date); +int day_store_recur_apoints(long date); +int day_store_apoints(long date); +struct day_item_s *day_add_event(int type, char *mesg, long day, int id); +struct day_item_s *day_add_apoint(int type, char *mesg, long start, long dur); +void day_write_pad(long date, int width, int length, int incolor, int colr); +struct apoint_s *day_item_s2apoint_s(struct day_item_s *p); +void day_popup_item(void); +int day_check_if_item(int year, int month, int day); + +#endif /* CALCURSE_DAY_H */ diff --git a/src/event.c b/src/event.c new file mode 100755 index 0000000..4cf3953 --- /dev/null +++ b/src/event.c @@ -0,0 +1,135 @@ +/* $calcurse: event.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#include <ncurses.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <time.h> + +#include "i18n.h" +#include "event.h" +#include "utils.h" + +struct event_s *eventlist; + +/* Create a new event */ +struct event_s *event_new(char *mesg, long day, int id) +{ + struct event_s *o, **i; + o = (struct event_s *) malloc(sizeof(struct event_s)); + o->mesg = (char *) malloc(strlen(mesg) + 1); + strcpy(o->mesg, mesg); + o->day = day; + o->id = id; + i = &eventlist; + for (;;) { + if (*i == 0 || (*i)->day > day) { + o->next = *i; + *i = o; + break; + } + i = &(*i)->next; + } + return o; +} + +/* Check if the event belongs to the selected day */ +unsigned event_inday(struct event_s *i, long start) +{ + if (i->day <= start + 3600 * 24 && i->day > start) { + return 1; + } + return 0; +} + +/* Write to file the event in user-friendly format */ +void event_write(struct event_s *o, FILE * f) +{ + struct tm *lt; + time_t t; + + t = o->day; + lt = localtime(&t); + fprintf(f, "%02u/%02u/%04u [%d] %s\n", + lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year, o->id, o->mesg); +} + +/* Load the events from file */ +struct event_s *event_scan(FILE * f, struct tm start, int id) +{ + struct tm *lt; + char buf[MESG_MAXSIZE], *nl; + time_t tstart, t; + + t = time(NULL); + lt = localtime(&t); + + /* Read the event description */ + fgets(buf, MESG_MAXSIZE, f); + nl = strchr(buf, '\n'); + if (nl) { + *nl = '\0'; + } + start.tm_hour = 12; + start.tm_min = 0; + start.tm_sec = 0; + start.tm_isdst = -1; + start.tm_year -= 1900; + start.tm_mon--; + + tstart = mktime(&start); + if (tstart == -1) { + fputs(_("FATAL ERROR in event_scan: date error in the event\n"), stderr); + exit(EXIT_FAILURE); + } + return event_new(buf, tstart, id); +} + +/* Delete an event from the list */ +void event_delete_bynum(long start, unsigned num) +{ + unsigned n; + struct event_s *i, **iptr; + + n = 0; + iptr = &eventlist; + for (i = eventlist; i != 0; i = i->next) { + if (event_inday(i, start)) { + if (n == num) { + *iptr = i->next; + free(i->mesg); + free(i); + return; + } + n++; + } + iptr = &i->next; + } + /* NOTREACHED */ + fputs(_("FATAL ERROR in event_delete_bynum: no such event\n"), stderr); + exit(EXIT_FAILURE); +} diff --git a/src/event.h b/src/event.h new file mode 100755 index 0000000..6e06691 --- /dev/null +++ b/src/event.h @@ -0,0 +1,48 @@ +/* $calcurse: event.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#ifndef CALCURSE_EVENT_H +#define CALCURSE_EVENT_H + +#define HRMIN_SIZE 6 +#define MESG_MAXSIZE 256 + +struct event_s { + struct event_s *next; + int id; /* event identifier */ + long day; /* seconds since 1 jan 1970 */ + char *mesg; +}; + +extern struct event_s *eventlist; + +struct event_s *event_new(char *, long, int); +unsigned event_inday(struct event_s *o, long start); +void event_write(struct event_s *o, FILE * f); +struct event_s *event_scan(FILE * f, struct tm start, int id); +void event_delete_bynum(long start, unsigned num); + +#endif /* CALCURSE_EVENT_H */ diff --git a/src/help.c b/src/help.c new file mode 100755 index 0000000..f586e74 --- /dev/null +++ b/src/help.c @@ -0,0 +1,375 @@ +/* $calcurse: help.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#include <ncurses.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <sys/types.h> + +#include "i18n.h" +#include "help.h" +#include "custom.h" +#include "vars.h" +#include "utils.h" + +/* + * Write the desired help text inside the help pad, and return the number + * of lines that were written. + * */ +int write_help_pad(WINDOW *win, char *title, char *text, int pad_width) +{ + int nl_title = 0; + int nl_text = 0; + + nl_text = get_help_lines(text); + nl_title = get_help_lines(title); + erase_window_part(win, 0, 0, MAX_LENGTH, pad_width); + custom_apply_attr(win, ATTR_HIGHEST); + mvwprintw(win, 0, 0, "%s", title); + custom_remove_attr(win, ATTR_HIGHEST); + mvwprintw(win, nl_title, 0, "%s", text); + return nl_text + nl_title; +} + +int get_help_lines(char *text) +{ + int i; + int nl = 0; + + for (i = 0; text[i]; i++) { + if (text[i] == '\n') nl++; + } + return nl + 1; +} + +/* Draws the help screen */ +void help_screen(int which_pan, int colr) +{ + WINDOW *help_win = NULL; + WINDOW *help_pad = NULL; + char label[80]; + int ch = '?'; + int help_row = row - 2; //size of the help window + int help_col = col; + int title_lines = 3; + int pad_offset = 4; + int text_lines = help_row - (pad_offset + 1); + int pad_width = help_col - 2*pad_offset + 1; + int first_line = 0, nl = 0; + + help_page_t help_main; + help_page_t help_redraw; + help_page_t help_save; + help_page_t help_displacement; + help_page_t help_view; + help_page_t help_tab; + help_page_t help_goto; + help_page_t help_delete; + help_page_t help_add; + help_page_t help_config; + help_page_t help_credits; + + help_main.title = + _(" Welcome to Calcurse. This is the main help screen.\n"); + help_main.text = + _(" Moving around: Press CTRL-P or CTRL-N to scroll text upward or\n" + " downward inside help screens, if necessary.\n\n" + " Exit help: When finished, press 'Q' to exit help and go back\n" + " to the main Calcurse screen.\n\n" + " Help topic: At the bottom of this screen you can see a panel\n" + " with different fields, represented by a letter and\n" + " a short title. This panel contains all the available\n" + " actions you can perform when using Calcurse.\n" + " By pressing one of the letters appearing in this\n" + " panel, you will be shown a short description of the\n" + " corresponding action.\n\n" + " Credits: Press '@' for credits."); + + help_redraw.title = _("Redraw:\n"); + help_redraw.text = + _("Pressing 'R' redraws the Calcurse panels.\n\n" + "You might want to use this function when you resize your terminal\n" + "screen for example, and you want Calcurse to take into account the new\n" + "size of the terminal.\n\n" + "This function can also be useful when garbage appears in the display,\n" + "and you want to clean it."); + + help_save.title = _("Save:\n"); + help_save.text = + _("Pressing 'S' saves the Calcurse data.\n\n" + "The data is splitted into three different files which contains :" + "\n\n" + " / ~/.calcurse/conf -> the user configuration\n" + " | (layout, color, general options)\n" + " | ~/.calcurse/apts -> the data related to the appointments\n" + " \\ ~/.calcurse/todo -> the data related to the todo list\n" + "\nIn the config menu, you can choose to save the Calcurse data\n" + "automatically before quitting."); + + help_displacement.title = _("Displacement keys:\n"); + help_displacement.text = + _("You can use either 'H','J','K','L' or the arrow keys '<','v','^','>'\n" + "to move into the calendar.\n\n" + "The following scheme explains how :\n\n" + " move to previous week\n" + " K ^ \n" + " move to previous day H < > L move to next day\n" + " J v \n" + " move to next week\n" + "\nWhen the Appointment or ToDo panel is selected, the up and down keys\n" + "(respectively K or up arrow, and J or down arrow) allows you to select\n" + "an item from those lists."); + + help_view.title = _("View:\n"); + help_view.text = + _("Pressing 'V' allows you to view the item you select in either the ToDo\n" + "or Appointment panel.\n" + "\nThis is usefull when an event description is longer than the available\n" + "space to display it. If that is the case, the description will be\n" + "shortened and its end replaced by '...'. To be able to read the entire\n" + "description, just press 'V' and a popup window will appear, containing\n" + "the whole event.\n" + "\nPress any key to close the popup window and go back to the main\n" + "Calcurse screen."); + + help_tab.title = _("Tab:\n"); + help_tab.text = + _("Pressing 'Tab' allows you to switch between panels.\n" + "The panel currently in use has its border colorized.\n" + "\nSome actions are possible only if the right panel is selected.\n" + "For example, if you want to add a task in the TODO list, you need first\n" + "to press the 'Tab' key to get the TODO panel selected. Then you can\n" + "press 'A' to add your item.\n" + "\nNotice that at the bottom of the screen the list of possible actions\n" + "change while pressing 'Tab', so you always know what action can be\n" + "performed on the selected panel."); + + help_goto.title = _("Goto:\n"); + help_goto.text = + _("Pressing 'G' allows you to jump to a specific day in the calendar.\n" + "\nUsing this command, you do not need to travel to that day using\n" + "the displacement keys inside the calendar panel.\n" + "If you hit [ENTER] without specifying any date, Calcurse checks the\n" + "system current date and you will be taken to that date."); + + help_delete.title = _("Delete:\n"); + help_delete.text = + _("Pressing 'D' deletes an element in the ToDo or Appointment list.\n" + "\nDepending on which panel is selected when you press the delete key,\n" + "the hilighted item of either the ToDo or Appointment list will be \n" + "removed from this list.\n" + "\nIf the general option 'confirm_delete' is set to 'YES', then you will\n" + "be asked for confirmation before deleting the selected event.\n" + "Do not forget to save the calendar data to retrieve the modifications\n" + "next time you launch Calcurse."); + + help_add.title = _("Add:\n"); + help_add.text = + _("Pressing 'A' allows you to add an item in either the ToDo or Appointment\n" + "list, depending on which panel is selected when you press 'A'.\n" + "\nTo enter a new item in the TODO list, you only need to enter the\n" + "description of this new item.\n" + "\nIf the APPOINTMENT panel is selected while pressing 'A', you will be\n" + "able to enter either a new appointment or a new all-day long event.\n" + "To enter a new event, press [ENTER] instead of the item start time, and\n" + "just fill in the event description.\n" + "To enter a new appointment to be added in the APPOINTMENT list, you\n" + "will need to enter successively the time at which the appointment\n" + "begins, the appointment length (either by specifying the duration in\n" + "minutes, or the end time in [hh:mm] or [h:mm] format), and the\n" + "description of the event.\n" + "\nThe day at which occurs the event or appointment is the day currently\n" + "selected in the calendar, so you need to move to the desired day before\n" + "pressing 'A'.\n" + "\nNotes:\n" + " o if an appointment lasts for such a long time that it continues\n" + " on the next days, this event will be indicated on all the\n" + " corresponding days, and the beginning or ending hour will be\n" + " replaced by '..' if the event does not begin or end on the day.\n" + " o if you only press [ENTER] at the APPOINTMENT or TODO event\n" + " description prompt, without any description, no item will be\n" + " added.\n" + " o do not forget to save the calendar data to retrieve the new\n" + " event next time you launch Calcurse."); + + help_config.title = _("Config:\n"); + help_config.text = + _("Pressing 'C' leads to the configuration submenu, from which you can\n" + "select between color, layout, and general options.\n" + "\nThe color submenu lets you choose the color theme.\n" + "\nThe layout submenu lets you choose the Calcurse screen layout, in other\n" + "words where to place the three different panels on the screen.\n" + "\nThe general options submenu brings a screen with the different options\n" + "which modifies the way Calcurse interacts with the user.\n" + "\nDo not forget to save the calendar data to retrieve your configuration\n" + "next time you launch Calcurse."); + + help_credits.title = _("Calcurse - text-based organizer"); + help_credits.text = + _("Copyright (c) 2004-2006 Frederic Culot\n" + "\n" + "This program is free software; you can redistribute it and/or modify\n" + "it under the terms of the GNU General Public License as published by\n" + "the Free Software Foundation; either version 2 of the License, or\n" + "(at your option) any later version.\n" + "\nThis program is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + "GNU General Public License for more details.\n" + "\n\n" + "Send your feedback or comments to : calcurse@culot.org\n" + "Calcurse home page : http://culot.org/calcurse"); + + /* + * Create the help window and panel. The panel is used to make + * the scrolling faster. + */ + help_win = newwin(help_row, help_col, 0, 0); + help_pad = newpad(MAX_LENGTH, pad_width); + box(help_win, 0, 0); + sprintf(label, _("CalCurse %s | help"), VERSION); + win_show(help_win, label); + + /* Display the main help screen. */ +/* nl = write_help_pad(help_pad, help_main.title, help_main.text, pad_width); + status_bar(which_pan, colr, col, 2); + wmove(swin, 0, 0); + wnoutrefresh(help_win); + pnoutrefresh(help_pad, first_line, 0, pad_offset, pad_offset, + help_row - 2, help_col - pad_offset); + doupdate(); +*/ + + /* Display the help screen related to user input. */ + while ( ch != 'q' ) { + erase_window_part(help_win, 1, title_lines, + help_col - 2, help_row - 2); + + switch (ch) { + + case CTRL('N') : + if (nl > first_line + text_lines) first_line++; + break; + + case CTRL('P') : + if (first_line > 0) first_line--; + break; + + case '?': + first_line = 0; + nl = write_help_pad(help_pad, help_main.title, + help_main.text, pad_width); + break; + case 'r': + first_line = 0; + nl = write_help_pad(help_pad, help_redraw.title, + help_redraw.text, pad_width); + break; + case 's': + first_line = 0; + nl = write_help_pad(help_pad, help_save.title, + help_save.text, pad_width); + break; + case 'h': + case 'l': + case 'j': + case 'k': + case 259: + case 258: + case 260: + case 261: + first_line = 0; + nl = write_help_pad(help_pad, help_displacement.title, + help_displacement.text, pad_width); + break; + + case 'a': + first_line = 0; + nl = write_help_pad(help_pad, help_add.title, + help_add.text, pad_width); + break; + + case 'g': + first_line = 0; + nl = write_help_pad(help_pad, help_goto.title, + help_goto.text, pad_width); + break; + + case 'd': + first_line = 0; + nl = write_help_pad(help_pad, help_delete.title, + help_delete.text, pad_width); + break; + + case 'c': + first_line = 0; + nl = write_help_pad(help_pad, help_config.title, + help_config.text, pad_width); + break; + + case 'v': + first_line = 0; + nl = write_help_pad(help_pad, help_view.title, + help_view.text, pad_width); + break; + + case 9: + first_line = 0; + nl = write_help_pad(help_pad, help_tab.title, + help_tab.text, pad_width); + break; + + case '@': + first_line = 0; + nl = write_help_pad(help_pad, help_credits.title, + help_credits.text, pad_width); + break; + } + + /* Draw the scrollbar if necessary. */ + if (nl > text_lines){ + float ratio = ((float) text_lines + 1) / ((float) nl); + int sbar_length = (int) (ratio * text_lines); + int highend = (int) (ratio * first_line); + int sbar_top = highend + title_lines + 1; + + draw_scrollbar(help_win, sbar_top, help_col - 2, + sbar_length, title_lines + 1, + help_row - 1, true); + } + + wmove(swin, 0, 0); + wnoutrefresh(help_win); + pnoutrefresh(help_pad, first_line, 0, + pad_offset, pad_offset, + help_row - 2, help_col - pad_offset); + doupdate(); + ch = wgetch(swin); + } + delwin(help_pad); + delwin(help_win); +} diff --git a/src/help.h b/src/help.h new file mode 100755 index 0000000..5aa830f --- /dev/null +++ b/src/help.h @@ -0,0 +1,41 @@ +/* $calcurse: help.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#ifndef CALCURSE_HELP_H +#define CALCURSE_HELP_H + +#include <ncurses.h> + +typedef struct { + char *title; + char *text; +} help_page_t; + +int write_help_pad(WINDOW *win, char *title, char *text, int pad_width); +int get_help_lines(char *text); +void help_screen(int which_pan, int colr); + +#endif /* CALCURSE_HELP_H */ diff --git a/src/i18n.h b/src/i18n.h new file mode 100755 index 0000000..454a084 --- /dev/null +++ b/src/i18n.h @@ -0,0 +1,54 @@ +/* $calcurse: i18n.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#ifndef CALCURSE_I18N_H +#define CALCURSE_I18N_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif /* HAVE_CONFIG_H */ + +#if ENABLE_NLS + #include <libintl.h> + #undef _ + #define _(String) gettext(String) + #ifdef gettext_noop + #define N_(String) gettext_noop(String) + #else + #define N_(String) (String) + #endif +#else /* NLS disabled */ + #define _(String) (String) + #define N_(String) (String) + #define textdomain(String) (String) + #define gettext(String) (String) + #define dgettext(String) (String) + #define dcgettext(String) (String) + #define bindtextdomain(String) (String) + #define bind_textdomain_codeset(Domain,Codeset) (Codeset) +#endif /* ENABLE_NLS */ + +#endif /* CALCURSE_I18N_H */ diff --git a/src/io.c b/src/io.c new file mode 100755 index 0000000..35c5802 --- /dev/null +++ b/src/io.c @@ -0,0 +1,484 @@ +/* $calcurse: io.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#include <ncurses.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <time.h> +#include <math.h> +#include <unistd.h> + +#include "i18n.h" +#include "utils.h" +#include "custom.h" +#include "todo.h" +#include "event.h" +#include "apoint.h" +#include "recur.h" +#include "io.h" +#include "vars.h" + +/* + * Initialization of data paths. The argument cfile is the variable + * which contains the calendar file. If none is given, then the default + * one (~/.calcurse/apts) is taken. If the one given does not exist, it + * is created. + */ +void +io_init(char *cfile) +{ + FILE *data_file; + char *home; + char apts_file[MAX_LENGTH] = ""; + int ch; + + home = getenv("HOME"); + if (home == NULL) { + home = "."; + } + snprintf(path_dir, MAX_LENGTH, "%s/" DIR_NAME, home); + snprintf(path_todo, MAX_LENGTH, "%s/" TODO_PATH, home); + snprintf(path_conf, MAX_LENGTH, "%s/" CONF_PATH, home); + if (cfile == NULL) { + snprintf(path_apts, MAX_LENGTH, "%s/" APTS_PATH, home); + } else { + snprintf(apts_file, MAX_LENGTH, "%s", cfile); + strncpy(path_apts, apts_file, MAX_LENGTH); + /* check if the file exists, otherwise create it */ + data_file = fopen(path_apts, "r"); + if (data_file == NULL) { + printf(_("%s does not exist, create it now [y or n] ? "), path_apts); + ch = getchar(); + switch (ch) { + case 'N': + case 'n': + printf(_("aborting...\n")); + exit(EXIT_FAILURE); + break; + + case 'Y': + case 'y': + data_file = fopen(path_apts, "w"); + if (data_file == NULL) { + perror(path_apts); + exit(EXIT_FAILURE); + } else { + printf(_("%s successfully created\n"),path_apts); + printf(_("starting interactive mode...\n")); + } + break; + + default: + printf(_("aborting...\n")); + exit(EXIT_FAILURE); + break; + } + } + fclose(data_file); + } +} + + /* get data from file */ +void extract_data(char *dst_data, const char *org, int len) +{ + for (;;) { + if (*org == '\n' || *org == '\0') + break; + *dst_data++ = *org++; + } + *dst_data = '\0'; +} + +/* Save the calendar data */ +void +save_cal(bool auto_save, bool confirm_quit, + bool confirm_delete, bool skip_system_dialogs, + bool skip_progress_bar, bool week_begins_on_monday, + int colr, int layout) +{ + FILE *data_file; + struct event_s *k; + struct apoint_s *j; + struct todo_s *i; + char *access_pb = _("Problems accessing data file ..."); + char *config_txt = + "#\n# Calcurse configuration file\n#\n# This file sets the configuration options used by Calcurse. These\n# options are usually set from within Calcurse. A line beginning with \n# a space or tab is considered to be a continuation of the previous line.\n# For a variable to be unset its value must be blank.\n# To set a variable to the empty string its value should be \"\".\n# Lines beginning with \"#\" are comments, and ignored by Calcurse.\n"; + char *save_success = _("The data files were successfully saved"); + char *enter = _("Press [ENTER] to continue"); + bool save = true, show_bar = false; + + if (!skip_progress_bar) show_bar = true; + + /* Save the user configuration. */ + + if (show_bar) progress_bar(save, 1); + data_file = fopen(path_conf, "w"); + if (data_file == (FILE *) 0) + status_mesg(access_pb, ""); + else { + fprintf(data_file, "%s\n", config_txt); + + fprintf(data_file, + "# If this option is set to yes, automatic save is done when quitting\n"); + fprintf(data_file, "auto_save=\n"); + fprintf(data_file, "%s\n", + (auto_save) ? "yes" : "no"); + + fprintf(data_file, + "\n# If this option is set to yes, confirmation is required before quitting\n"); + fprintf(data_file, "confirm_quit=\n"); + fprintf(data_file, "%s\n", + (confirm_quit) ? "yes" : "no"); + + fprintf(data_file, + "\n# If this option is set to yes, confirmation is required before deleting an event\n"); + fprintf(data_file, "confirm_delete=\n"); + fprintf(data_file, "%s\n", + (confirm_delete) ? "yes" : "no"); + + fprintf(data_file, + "\n# If this option is set to yes, messages about loaded and saved data will not be displayed\n"); + fprintf(data_file, "skip_system_dialogs=\n"); + fprintf(data_file, "%s\n", + (skip_system_dialogs) ? "yes" : "no"); + + fprintf(data_file, + "\n# If this option is set to yes, progress bar appearing when saving data will not be displayed\n"); + fprintf(data_file, "skip_progress_bar=\n"); + fprintf(data_file, "%s\n", + (skip_progress_bar) ? "yes" : "no"); + + fprintf(data_file, + "\n# If this option is set to yes, monday is the first day of the week, else it is sunday\n"); + fprintf(data_file, "week_begins_on_monday=\n"); + fprintf(data_file, "%s\n", + (week_begins_on_monday) ? "yes" : "no"); + + fprintf(data_file, + "\n# This is the color theme used for menus (1 to 8) :\n"); + fprintf(data_file, "color-theme=\n"); + fprintf(data_file, "%d\n", colr); + + fprintf(data_file, + "\n# This is the layout of the calendar (1 to 4) :\n"); + fprintf(data_file, "layout=\n"); + fprintf(data_file, "%d\n", layout); + fclose(data_file); + } + + /* Save the todo data file. */ + if (show_bar) progress_bar(save, 2); + data_file = fopen(path_todo, "w"); + if (data_file == (FILE *) 0) + status_mesg(access_pb, ""); + else { + for (i = todolist; i != 0; i = i->next) + fprintf(data_file, "%s\n", i->mesg); + fclose(data_file); + } + + /* + * Save the apts data file, which contains the + * appointments first, and then the events. + * Recursive items are written first. + */ + if (show_bar) progress_bar(save, 3); + data_file = fopen(path_apts, "w"); + if (data_file == (FILE *) 0) + status_mesg(access_pb, ""); + else { + recur_save_data(data_file); + for (j = apointlist; j != 0; j = j->next) + apoint_write(j, data_file); + for (k = eventlist; k != 0; k = k->next) + event_write(k, data_file); + fclose(data_file); + } + + + /* Print a message telling data were saved */ + if (!skip_system_dialogs){ + status_mesg(save_success, enter); + wgetch(swin); + } +} + +/* + * Check what type of data is written in the appointment file, + * and then load either: a new appointment, a new event, or a new + * recursive item (which can also be either an event or an appointment). + */ +void load_app() +{ + FILE *data_file; + int c, is_appointment, is_event, is_recursive; + struct tm start, end, until, *lt; + time_t t; + int id = 0; + int freq; + char type; + char *error = + _("FATAL ERROR in load_app: wrong format in the appointment or event\n"); + + t = time(NULL); + lt = localtime(&t); + start = end = until = *lt; + + data_file = fopen(path_apts, "r"); + for (;;) { + is_appointment = is_event = is_recursive = 0; + c = getc(data_file); + if (c == EOF) + break; + ungetc(c, data_file); + + /* Read the date first: it is common to both events + * and appointments. + */ + if (fscanf(data_file, "%u / %u / %u ", + &start.tm_mon, &start.tm_mday, &start.tm_year) != 3) { + fputs(_("FATAL ERROR in load_app: " + "syntax error in the item date\n"), stderr); + exit(EXIT_FAILURE); + } + + /* Read the next character : if it is an '@' then we have + * an appointment, else if it is an '[' we have en event. + */ + c = getc(data_file); + + if (c == '@') + is_appointment = 1; + else if (c == '[') + is_event = 1; + else { + fputs(_("FATAL ERROR in load_app: " + "no event nor appointment found\n"), stderr); + exit(EXIT_FAILURE); + } + ungetc(c, data_file); + + /* Read the remaining informations. */ + if (is_appointment) { + fscanf(data_file, "@ %u : %u -> %u / %u / %u @ %u : %u ", + &start.tm_hour, &start.tm_min, + &end.tm_mon, &end.tm_mday, &end.tm_year, + &end.tm_hour, &end.tm_min); + } else if (is_event) { + fscanf(data_file, "[%d] ", &id); + } else { /* NOT REACHED */ + fputs(error, stderr); + exit(EXIT_FAILURE); + } + + /* Check if we have a recursive item. */ + c = getc(data_file); + + if (c == '{') { + ungetc(c, data_file); + is_recursive = 1; + fscanf(data_file, "{ %d%c ", &freq, &type); + /* Check if we have an endless recurrent item. */ + c = getc(data_file); + if (c == '}') { + ungetc(c, data_file); + fscanf(data_file, "} "); + until.tm_year = 0; + if (is_appointment) + c = getc(data_file); // useless '|' + } else if (c == '-') { + ungetc(c, data_file); + fscanf(data_file, " -> %u / %u / %u } ", + &until.tm_mon, &until.tm_mday, + &until.tm_year); + if (is_appointment) + c = getc(data_file); // useless '|' + } else { /* NOT REACHED */ + fputs(error, stderr); + exit(EXIT_FAILURE); + } + } else { + if (is_event) // if appointment we have a useless '|' + ungetc(c, data_file); + } + + /* + * Last: read the item description and load it into its + * corresponding linked list, depending on the item type. + */ + if (is_appointment) { + if (is_recursive) { + recur_apoint_scan(data_file, start, end, + type, freq, until); + } else { + apoint_scan(data_file, start, end); + } + } else if (is_event) { + if (is_recursive) { + recur_event_scan(data_file, start, id, + type, freq, until); + } else { + event_scan(data_file, start, id); + } + } else { /* NOT REACHED */ + fputs(error, stderr); + exit(EXIT_FAILURE); + } + } + fclose(data_file); +} + +/* Load the todo data */ +int +load_todo(int colr) +{ + FILE *data_file; + char *mesg_line1 = _("Failed to open todo file"); + char *mesg_line2 = _("Press [ENTER] to continue"); + int nb_tod = 0; + char buf[100], e_todo[100]; + + data_file = fopen(path_todo, "r"); + if (data_file == NULL) { + status_mesg(mesg_line1, mesg_line2); + wgetch(swin); + } + for (;;) { + if (fgets(buf, 99, data_file) == NULL) { + break; + } + extract_data(e_todo, buf, strlen(buf)); + todo_add(e_todo); + ++nb_tod; + } + fclose(data_file); + return nb_tod; +} + +/* Checks if data files exist. If not, create them */ +int check_data_files() +{ + FILE *data_file; + int no_data_file; + + no_data_file = 0; + /* Create the calcurse repertory if not present. */ + mkdir(path_dir, 0700); + + data_file = fopen(path_todo, "r"); + if (data_file == NULL) { + no_data_file++; + data_file = fopen(path_todo, "w"); + if (data_file == NULL) { + perror(path_todo); + return no_data_file; + } + } + fclose(data_file); + + data_file = fopen(path_apts, "r"); + if (data_file == NULL) { + no_data_file++; + data_file = fopen(path_apts, "w"); + if (data_file == NULL) { + perror(path_apts); + return no_data_file; + } + } + fclose(data_file); + + data_file = fopen(path_conf, "r"); + if (data_file == NULL) { + no_data_file++; + data_file = fopen(path_conf, "w"); + if (data_file == NULL) { + perror(path_conf); + return no_data_file; + } + } + fclose(data_file); + return no_data_file; +} + +/* Draw the startup screen */ +void startup_screen(bool skip_dialogs, int no_data_file, int colr) +{ + char *welcome_mesg = _("Welcome to Calcurse. Missing data files were created."); + char *data_mesg = _("Data files found. Data will be loaded now."); + char *enter = _("Press [ENTER] to continue"); + + if (no_data_file != 0) { + status_mesg(welcome_mesg, enter); + wgetch(swin); + } else if (!skip_dialogs){ + status_mesg(data_mesg, enter); + wgetch(swin); + } +} + +/* Draw a progress bar while saving or loading data. */ +void progress_bar(bool save, int progress) +{ + int i, nbd = 4; + char *mesg_sav = _("Saving..."); + char *mesg_load = _("Loading..."); + char *barchar = "|"; + char *data[4] = { + "[ ]", + "[ conf ]", + "[ todo ]", + "[ apts ]"}; + int ipos = strlen(data[1]) + 2; + int epos[4]; + int sleep_time = 125000; + + /* progress bar length init. */ + epos[0] = floor(col / nbd); + epos[1] = 2*epos[0]; + epos[2] = 3*epos[0]; + epos[3] = col - 2; + + /* Display which data is being saved. */ + if (save) + status_mesg(mesg_sav, data[progress]); + else + status_mesg(mesg_load, data[progress]); + + /* Draw the progress bar. */ + mvwprintw(swin, 1, ipos, barchar); + mvwprintw(swin, 1, epos[nbd - 1], barchar); + custom_apply_attr(swin, ATTR_HIGHEST); + for (i = ipos + 1; i < epos[progress]; i++) + mvwaddch(swin, 1, i, ' ' | A_REVERSE); + custom_remove_attr(swin, ATTR_HIGHEST); + wmove(swin, 0, 0); + wrefresh(swin); + usleep(sleep_time); +} diff --git a/src/io.h b/src/io.h new file mode 100755 index 0000000..8cc7788 --- /dev/null +++ b/src/io.h @@ -0,0 +1,42 @@ +/* $calcurse: io.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#ifndef CALCURSE_IO_H +#define CALCURSE_IO_H + +void io_init(char *cfile); +void extract_data(char *dst_data, const char *org, int len); +void save_cal(bool auto_save, bool confirm_quit, + bool confirm_delete, bool skip_system_dialogs, + bool skip_progress_bar, bool week_begins_on_monday, + int colr, int layout); +void load_app(); +int load_todo(int colr); +int check_data_files(); +void startup_screen(bool skip_dialogs, int no_data_file, int colr); +void progress_bar(bool save, int progress); + +#endif /* CALCURSE_IO_H */ diff --git a/src/recur.c b/src/recur.c new file mode 100755 index 0000000..d0629aa --- /dev/null +++ b/src/recur.c @@ -0,0 +1,355 @@ +/* $calcurse: recur.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#include <ncurses.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <time.h> + +#include "i18n.h" +#include "utils.h" +#include "apoint.h" +#include "event.h" +#include "recur.h" + +struct recur_apoint_s *recur_alist; +struct recur_event_s *recur_elist; + +/* Insert a new recursive appointment in the general linked list */ +struct recur_apoint_s *recur_apoint_new(char *mesg, long start, long dur, + int type, int freq, long until) +{ + struct recur_apoint_s *o, **i; + o = (struct recur_apoint_s *) malloc(sizeof(struct recur_apoint_s)); + o->rpt = (struct rpt_s *) malloc(sizeof(struct rpt_s)); + o->exc = (struct days_s *) malloc(sizeof(struct days_s)); + o->mesg = (char *) malloc(strlen(mesg) + 1); + strcpy(o->mesg, mesg); + o->start = start; + o->dur = dur; + o->rpt->type = type; + o->rpt->freq = freq; + o->rpt->until = until; + i = &recur_alist; + for (;;) { + if (*i == 0 || (*i)->start > start) { + o->next = *i; + *i = o; + break; + } + i = &(*i)->next; + } + return o; +} + +/* Insert a new recursive event in the general linked list */ +struct recur_event_s *recur_event_new(char *mesg, long day, int id, + int type, int freq, long until) +{ + struct recur_event_s *o, **i; + o = (struct recur_event_s *) malloc(sizeof(struct recur_event_s)); + o->rpt = (struct rpt_s *) malloc(sizeof(struct rpt_s)); + o->exc = (struct days_s *) malloc(sizeof(struct days_s)); + o->mesg = (char *) malloc(strlen(mesg) + 1); + strcpy(o->mesg, mesg); + o->day = day; + o->id = id; + o->rpt->type = type; + o->rpt->freq = freq; + o->rpt->until = until; + i = &recur_elist; + for (;;) { + if (*i == 0 || (*i)->day > day) { + o->next = *i; + *i = o; + break; + } + i = &(*i)->next; + } + return o; +} + +/* + * Correspondance between the defines on recursive type, + * and the letter to be written in file. + */ +char recur_def2char(int define){ + char recur_char; + + switch (define) { + case 1: + recur_char = 'D'; + break; + case 2: + recur_char = 'W'; + break; + case 3: + recur_char = 'M'; + break; + case 4: + recur_char = 'Y'; + break; + } + return recur_char; +} + +/* + * Correspondance between the letters written in file and the defines + * concerning the recursive type. + */ +int recur_char2def(char type){ + int recur_def; + + switch (type) { + case 'D': + recur_def = RECUR_DAILY; + break; + case 'W': + recur_def = RECUR_WEEKLY; + break; + case 'M': + recur_def = RECUR_MONTHLY; + break; + case 'Y': + recur_def = RECUR_YEARLY; + break; + } + return recur_def; +} + +/* Writting of a recursive appointment into file. */ +void recur_apoint_write(struct recur_apoint_s *o, FILE *f) +{ + struct tm *lt; + time_t t; + + t = o->start; + lt = localtime(&t); + fprintf(f, "%02u/%02u/%04u @ %02u:%02u", + lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year, + lt->tm_hour, lt->tm_min); + + t = o->start + o->dur; + lt = localtime(&t); + fprintf(f, " -> %02u/%02u/%04u @ %02u:%02u", + lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year, + lt->tm_hour, lt->tm_min); + + t = o->rpt->until; + if (t == 0) { /* We have an endless recurrent appointment. */ + fprintf(f, " {%d%c} |%s\n", o->rpt->freq, + recur_def2char(o->rpt->type), o->mesg); + } else { + lt = localtime(&t); + fprintf(f, " {%d%c -> %02u/%02u/%04u} |%s\n", + o->rpt->freq, recur_def2char(o->rpt->type), + lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year, + o->mesg); + } +} + +/* Writting of a recursive event into file. */ +void recur_event_write(struct recur_event_s *o, FILE *f) +{ + struct tm *lt; + time_t t; + int st_mon, st_day, st_year; + int end_mon, end_day, end_year; + + t = o->day; + lt = localtime(&t); + st_mon = lt->tm_mon + 1; + st_day = lt->tm_mday; + st_year = lt->tm_year + 1900; + t = o->rpt->until; + if (t == 0) { /* We have an endless recurrent event. */ + fprintf(f, "%02u/%02u/%04u [%d] {%d%c} %s\n", + st_mon, st_day, st_year, o->id, o->rpt->freq, + recur_def2char(o->rpt->type), o->mesg); + } else { + lt = localtime(&t); + end_mon = lt->tm_mon + 1; + end_day = lt->tm_mday; + end_year = lt->tm_year + 1900; + fprintf(f, "%02u/%02u/%04u [%d] {%d%c -> %02u/%02u/%04u} %s\n", + st_mon, st_day, st_year, o->id, + o->rpt->freq, recur_def2char(o->rpt->type), + end_mon, end_day, end_year, o->mesg); + } +} + +/* Load the recursive appointment description */ +struct recur_apoint_s *recur_apoint_scan(FILE * f, struct tm start, + struct tm end, char type, int freq, struct tm until) +{ + struct tm *lt; + char buf[MESG_MAXSIZE], *nl; + time_t tstart, tend, t, tuntil; + + t = time(NULL); + lt = localtime(&t); + + /* Read the appointment description */ + fgets(buf, MESG_MAXSIZE, f); + nl = strchr(buf, '\n'); + if (nl) { + *nl = '\0'; + } + + start.tm_sec = end.tm_sec = 0; + start.tm_isdst = end.tm_isdst = -1; + start.tm_year -= 1900; + start.tm_mon--; + end.tm_year -= 1900; + end.tm_mon--; + tstart = mktime(&start); + tend = mktime(&end); + + if (until.tm_year != 0) { + until.tm_hour = 12; + until.tm_min = 0; + until.tm_sec = 0; + until.tm_isdst = -1; + until.tm_year -= 1900; + until.tm_mon--; + tuntil = mktime(&until); + } else { + tuntil = 0; + } + + if (tstart == -1 || tend == -1 || tstart > tend || tuntil == -1) { + fputs(_("FATAL ERROR in apoint_scan: date error in the appointment\n"), stderr); + exit(EXIT_FAILURE); + } + + return recur_apoint_new(buf, tstart, tend - tstart, + recur_char2def(type), freq, tuntil); +} + +/* Load the recursive events from file */ +struct recur_event_s *recur_event_scan(FILE * f, struct tm start, int id, + char type, int freq, struct tm until) +{ + struct tm *lt; + char buf[MESG_MAXSIZE], *nl; + time_t tstart, t, tuntil; + + t = time(NULL); + lt = localtime(&t); + + /* Read the event description */ + fgets(buf, MESG_MAXSIZE, f); + nl = strchr(buf, '\n'); + if (nl) { + *nl = '\0'; + } + + start.tm_hour = until.tm_hour = 12; + start.tm_min = until.tm_min = 0; + start.tm_sec = until.tm_sec = 0; + start.tm_isdst = until.tm_isdst = -1; + start.tm_year -= 1900; + start.tm_mon--; + if (until.tm_year != 0) { + until.tm_year -= 1900; + until.tm_mon--; + tuntil = mktime(&until); + } else { + tuntil = 0; + } + tstart = mktime(&start); + if ( (tstart == -1) || (tuntil == -1) ) { + fputs(_("FATAL ERROR in recur_event_scan: date error in the event\n"), stderr); + exit(EXIT_FAILURE); + } + + return recur_event_new(buf, tstart, id, recur_char2def(type), freq, tuntil); +} + +/* Write recursive items to file. */ +void recur_save_data(FILE *f) +{ + struct recur_event_s *re; + struct recur_apoint_s *ra; + + for (re = recur_elist; re != 0; re = re->next) + recur_event_write(re, f); + for (ra = recur_alist; ra != 0; ra = ra->next) + recur_apoint_write(ra, f); +} + +/* Check if the recurrent item belongs to the selected day. */ +unsigned recur_item_inday(long item_start, int rpt_type, int rpt_freq, + long rpt_until, long day_start) +{ + const int DAYINSEC = 86400; + long day_end = day_start + DAYINSEC; + int inday = 0; + struct tm *lt; + time_t t; + char *error = + _("FATAL ERROR in recur_item_inday: unknown item type\n"); + + if (rpt_until == 0) /* we have an endless recurrent item */ + rpt_until = day_end; + while (item_start <= day_end && item_start <= rpt_until) { + if (item_start < day_end && item_start >= day_start) { + inday = 1; + break; + } + t = item_start; + lt = localtime(&t); + if (rpt_type == RECUR_DAILY) { + lt->tm_mday += rpt_freq; + } else if (rpt_type == RECUR_WEEKLY) { + lt->tm_mday += rpt_freq * 7; + } else if (rpt_type == RECUR_MONTHLY) { + lt->tm_mon += rpt_freq; + } else if (rpt_type == RECUR_YEARLY) { + lt->tm_year += rpt_freq; + } else { /* NOT REACHED */ + fputs(error, stderr); + exit(EXIT_FAILURE); + } + item_start = date2sec(lt->tm_year + 1900, lt->tm_mon + 1, + lt->tm_mday, 0, 0); + } + return inday; +} + +/* Returns a structure of type apoint_s given a structure of type recur_apoint_s */ +struct apoint_s *recur_apoint_s2apoint_s(struct recur_apoint_s *p) +{ + struct apoint_s *a; + + a = (struct apoint_s *) malloc(sizeof(struct apoint_s)); + a->mesg = (char *) malloc(strlen(p->mesg) + 1); + a->start = p->start; + a->dur = p->dur; + a->mesg = p->mesg; + return a; +} diff --git a/src/recur.h b/src/recur.h new file mode 100755 index 0000000..611197c --- /dev/null +++ b/src/recur.h @@ -0,0 +1,87 @@ +/* $calcurse: recur.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#ifndef CALCURSE_RECUR_H +#define CALCURSE_RECUR_H + +#include "apoint.h" + +#define RECUR_NO 0 +#define RECUR_DAILY 1 +#define RECUR_WEEKLY 2 +#define RECUR_MONTHLY 3 +#define RECUR_YEARLY 4 + +struct days_s { + struct days_s *next; + long st; /* beggining of the considered day, in seconds */ +}; + +struct rpt_s { + int type; /* repetition type, see RECUR_* defines */ + int freq; /* repetition frequence */ + long until; /* ending date for repeated event */ +}; + +struct recur_apoint_s { + struct recur_apoint_s *next; + struct rpt_s *rpt; /* information about repetition */ + struct days_s *exc; /* days when the item should not be repeated */ + long start; /* beggining of the appointment */ + long dur; /* duration of the appointment */ + char *mesg; /* appointment description */ +}; + +struct recur_event_s { + struct recur_event_s *next; + struct rpt_s *rpt; /* information about repetition */ + struct days_s *exc; /* days when the item should not be repeated */ + int id; /* event type */ + long day; /* day at which event occurs */ + char *mesg; /* event description */ +}; + +extern struct recur_apoint_s *recur_alist; +extern struct recur_event_s *recur_elist; + +struct recur_apoint_s *recur_apoint_new(char *mesg, long start, long duration, + int type, int freq, long until); +struct recur_event_s *recur_event_new(char *mesg, long day, int id, + int type, int freq, long until); +char recur_def2char(int define); +int recur_char2def(char type); +void recur_apoint_write(struct recur_apoint_s *o, FILE * f); +void recur_event_write(struct recur_event_s *o, FILE * f); +struct recur_apoint_s *recur_apoint_scan(FILE * f, struct tm start, + struct tm end, char type, int freq, struct tm until); +struct recur_event_s *recur_event_scan(FILE * f, struct tm start, int id, + char type, int freq, struct tm until); +void recur_save_data(FILE *f); +unsigned recur_item_inday(long item_start, int rpt_type, int rpt_freq, + long rpt_until, long day_start); +struct apoint_s *recur_apoint_s2apoint_s(struct recur_apoint_s *p); + +#endif /* CALCURSE_RECUR_H */ diff --git a/src/todo.c b/src/todo.c new file mode 100755 index 0000000..b9419ec --- /dev/null +++ b/src/todo.c @@ -0,0 +1,80 @@ +/* $calcurse: todo.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "i18n.h" +#include "todo.h" + +struct todo_s *todolist; + +struct todo_s *todo_insert(char *mesg) +{ + struct todo_s *o; + o = (struct todo_s *) malloc(sizeof(struct todo_s)); + o->mesg = (char *) malloc(strlen(mesg) + 1); + strcpy(o->mesg, mesg); + o->next = todolist; + todolist = o; + return o; +} + +struct todo_s *todo_add(char *mesg) +{ + struct todo_s *o, **i; + o = (struct todo_s *) malloc(sizeof(struct todo_s)); + o->mesg = (char *) malloc(strlen(mesg) + 1); + strcpy(o->mesg, mesg); + for (i = &todolist; *i != 0; i = &(*i)->next) { + } + o->next = *i; + *i = o; + return o; +} + +void todo_delete_bynum(unsigned num) +{ + unsigned n; + struct todo_s *i, **iptr; + + n = 0; + iptr = &todolist; + for (i = todolist; i != 0; i = i->next) { + if (n == num) { + *iptr = i->next; + free(i->mesg); + free(i); + return; + } + iptr = &i->next; + n++; + } + /* not reached */ + fputs(_("FATAL ERROR in todo_delete_bynum: no such todo\n"), stderr); + exit(EXIT_FAILURE); +} diff --git a/src/todo.h b/src/todo.h new file mode 100755 index 0000000..9e2af31 --- /dev/null +++ b/src/todo.h @@ -0,0 +1,41 @@ +/* $calcurse: todo.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#ifndef CALCURSE_TODO_H +#define CALCURSE_TODO_H + +struct todo_s { + struct todo_s *next; + char *mesg; +}; + +extern struct todo_s *todolist; + +struct todo_s *todo_insert(char *mesg); +struct todo_s *todo_add(char *mesg); +void todo_delete_bynum(unsigned num); + +#endif /* CALCURSE_TODO_H */ diff --git a/src/utils.c b/src/utils.c new file mode 100755 index 0000000..ded00fb --- /dev/null +++ b/src/utils.c @@ -0,0 +1,614 @@ +/* $calcurse: utils.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#include <ncurses.h> +#include <time.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <stdbool.h> +#include <sys/types.h> +#include <math.h> + +#include "i18n.h" +#include "utils.h" +#include "custom.h" +#include "vars.h" + + +/* + * Print a message in the status bar. + * Message texts for first line and second line are to be provided. + */ + +void status_mesg(char *mesg_line1, char *mesg_line2) +{ + erase_window_part(swin, 0, 0, col, 2); + custom_apply_attr(swin, ATTR_HIGHEST); + mvwprintw(swin, 0, 0, mesg_line1); + mvwprintw(swin, 1, 0, mesg_line2); + custom_remove_attr(swin, ATTR_HIGHEST); +} + +/* + * Erase part of a window + */ +void erase_window_part(WINDOW *win, int first_col, int first_row, + int last_col, int last_row) +{ + int c, r; + + for (r = first_row; r <= last_row; r++){ + for (c = first_col; c <= last_col; c++){ + mvwprintw(win, r, c, " "); + } + } + wnoutrefresh(win); +} + +/* draws a popup window */ +WINDOW * popup(int pop_row, int pop_col, + int pop_y, int pop_x, char *pop_lab) +{ + char *txt_pop = _("Press any key to continue..."); + char label[80]; + WINDOW *popup_win; + + popup_win = newwin(pop_row, pop_col, pop_y, pop_x); + custom_apply_attr(popup_win, ATTR_HIGHEST); + box(popup_win, 0, 0); + sprintf(label, "%s", pop_lab); + win_show(popup_win, label); + mvwprintw(popup_win, pop_row - 2, pop_col - (strlen(txt_pop) + 1), "%s", + txt_pop); + custom_remove_attr(popup_win, ATTR_HIGHEST); + wnoutrefresh(popup_win); + doupdate(); + return popup_win; +} + +/* prints in middle of a panel */ +void +print_in_middle(WINDOW * win, int starty, int startx, int width, char *string) +{ + int length, x, y; + float temp; + + if (win == NULL) + win = stdscr; + getyx(win, y, x); + if (startx != 0) + x = startx; + if (starty != 0) + y = starty; + if (width == 0) + width = 80; + + length = strlen(string); + temp = (width - length) / 2; + x = startx + (int) temp; + custom_apply_attr(win, ATTR_HIGHEST); + mvwprintw(win, y, x, "%s", string); + custom_remove_attr(win, ATTR_HIGHEST); +} + +/* + * Getstring allows to get user input and to print it on a window, + * even if noecho() is on. + */ +void getstring(win, colr, string, start_x, start_y) +WINDOW *win; +int colr; +char *string; +int start_x, start_y; +{ + int ch; + int charcount = 0; + + custom_apply_attr(win, ATTR_HIGHEST); + if (start_x != -1) + wmove(win, start_y, start_x); + + while ((ch = wgetch(win)) != '\n') { + if ((ch == KEY_BACKSPACE) || + (ch == 330) || + (ch == 263) || + (ch == 127) || + (ch == CTRL('H')) ) { + if (charcount > 0) { + string--; + charcount--; + wmove(win, start_y, start_x + charcount); + waddch(win, ' '); + wmove(win, start_y, start_x + charcount); + } + } else { + *string++ = ch; + charcount++; + waddch(win, ch); + } + doupdate(); + } + *string = 0; + custom_remove_attr(win, ATTR_HIGHEST); + return; +} + +/* checks if a string is only made of digits */ +int is_all_digit(char *string) +{ + int digit, i; + int all_digit; + + digit = 0; + all_digit = 0; + + for (i = 0; i <= strlen(string); i++) + if (isdigit(string[i]) != 0) + digit++; + if (digit == strlen(string)) + all_digit = 1; + return all_digit; +} + +/* draw panel border in color */ +void border_color(WINDOW * window, int bcolr) +{ + int color_attr = A_BOLD; + int no_color_attr = A_BOLD; + + if (colorize) { + wattron(window, color_attr | COLOR_PAIR(bcolr)); + box(window, 0, 0); + } else { + wattron(window, no_color_attr); + box(window, 0, 0); + } + + if (colorize) { + wattroff(window, color_attr | COLOR_PAIR(bcolr)); + } else { + wattroff(window, no_color_attr); + } + + wnoutrefresh(window); +} + +/* draw panel border without any color */ +void border_nocolor(WINDOW * window) +{ + int colr = 9; + int color_attr = A_BOLD; + int no_color_attr = A_DIM; + + if (colorize) { + wattron(window, color_attr | COLOR_PAIR(colr)); + } else { + wattron(window, no_color_attr); + } + + box(window, 0, 0); + + if (colorize) { + wattroff(window, color_attr | COLOR_PAIR(colr)); + } else { + wattroff(window, no_color_attr); + } + + wnoutrefresh(window); +} + + /* prints and scroll text in a window */ +void scroller(WINDOW *win, char *mesg, int x, int y, int nb_row, int nb_col) +{ + int x_offset = 3; + int y_offset = 3; + int text_len = nb_col - 2 * x_offset; + int text_max_row = nb_row - 3; + int nlin, i, j, k; + int last_blank_i, last_blank_j; + char buf[] = " "; + char *next_mesg = _("-- Press 'N' for next page --"); + char *prev_mesg = _("-- Press 'P' for previous page --"); + int ch; + int which_page; //first page : 0, second page : 1 + + i = 0; //position in the message + j = 0; //x position on the current line + nlin = 1; //line number + last_blank_j = 0; + last_blank_i = 0; + which_page = 0; + + while (i <= strlen(mesg)) { + if ((i == strlen(mesg)) & (which_page == 1)) { + // we have finished writing text and we are on second page + custom_apply_attr(win, ATTR_HIGHEST); + mvwprintw(win, nb_row - 2, + nb_col - (strlen(prev_mesg) + 2), "%s", + prev_mesg); + custom_remove_attr(win, ATTR_HIGHEST); + wmove(swin, 0, 0); + wnoutrefresh(win); + wnoutrefresh(swin); + doupdate(); + ch = wgetch(win); + if ( (ch == 'P') | (ch == 'p') ) { + erase_window_part(win, y + 1, x + 3, nb_col - 2, nb_row - 2); + nlin = 1; + j = 0; + i = 0; + which_page = 0; + } else { //erase last line and exit next-prev page mode + for (k = 1; k < nb_col - 2; k++) + mvwprintw(win, nb_row - 2, k, " "); + break; + } + } + if (nlin == text_max_row - 2) { // we reach the last line + custom_apply_attr(win, ATTR_HIGHEST); + mvwprintw(win, nb_row - 2, + nb_col - (strlen(next_mesg) + 2), "%s", + next_mesg); + custom_remove_attr(win, ATTR_HIGHEST); + wmove(swin, 0, 0); + wnoutrefresh(win); + wnoutrefresh(swin); + doupdate(); + ch = wgetch(win); + if ( (ch == 'N') | (ch == 'n') ) { + erase_window_part(win, y + 1, x + 3, nb_col - 2, nb_row - 2); + nlin = 1; + j = 0; + which_page = 1; + } else { + for (k = 1; k < nb_col - 2; k++) + mvwprintw(win, nb_row - 2, k, " "); + break; + } + } + //write text + strncpy(buf, mesg + i, 1); + i++; + j++; + if ((strncmp(buf, "§", 1) == 0)) { //§ is the character for a new line + buf[0] = '\0'; + mvwprintw(win, x + x_offset + nlin, y + y_offset + j, + "%s", buf); + nlin++; + j = 0; + } else { + if (j == text_len - 1) { // if we reach the terminal border + for (k = last_blank_j; k <= text_len - 1; + k++) + mvwprintw(win, x + x_offset + nlin, + y + y_offset + k, " "); + nlin++; + i = last_blank_i; + j = 0; + } else { + if ((strncmp(buf, " ", 1) == 0)) //space between words + { + last_blank_j = j; //save position + last_blank_i = i; + } + mvwprintw(win, x + x_offset + nlin, + y + y_offset + j, "%s", buf); + } + } + } + wmove(swin, 0, 0); + wnoutrefresh(win); + wnoutrefresh(swin); +} + +/* Draws the status bar */ +void status_bar(int which_pan, int colr, int nc_bar, int nl_bar) +{ + int nb_item_cal, nb_item_oth; + int len_let, len_des, spc_lad; + int spc_bet_cal_itm, spc_bet_oth_itm; + int len_cal_itm, len_oth_itm; + + nb_item_cal = 10; /* max item number to display in status bar */ + nb_item_cal = ceil(nb_item_cal / 2); /* two lines to display items */ + nb_item_oth = 12; + nb_item_oth = ceil(nb_item_oth / 2); + len_let = 3; + len_des = 8; + spc_lad = 1; + + spc_bet_cal_itm = + floor((col - + nb_item_cal * (len_let + len_des + + spc_lad)) / nb_item_cal); + spc_bet_oth_itm = + floor((col - + nb_item_oth * (len_let + len_des + + spc_lad)) / nb_item_oth); + len_cal_itm = len_let + spc_lad + len_des + spc_bet_cal_itm; + len_oth_itm = len_let + spc_lad + len_des + spc_bet_oth_itm; + + erase_window_part(swin, 0, 0, nc_bar, nl_bar); + if (which_pan == 0) { + custom_apply_attr(swin, ATTR_HIGHEST); + mvwprintw(swin, 0, 0, " ?"); + mvwprintw(swin, 1, 0, " Q"); + mvwprintw(swin, 0, len_cal_itm, " R"); + mvwprintw(swin, 1, len_cal_itm, " S"); + mvwprintw(swin, 0, 2 * len_cal_itm, "H/L"); + mvwprintw(swin, 1, 2 * len_cal_itm, "J/K"); + mvwprintw(swin, 0, 3 * len_cal_itm, " G"); + mvwprintw(swin, 1, 3 * len_cal_itm, "Tab"); + mvwprintw(swin, 0, 4 * len_cal_itm, " C"); + custom_remove_attr(swin, ATTR_HIGHEST); + wnoutrefresh(swin); + + mvwprintw(swin, 0, len_let + spc_lad, _("Help")); + mvwprintw(swin, 1, len_let + spc_lad, _("Quit")); + mvwprintw(swin, 0, len_cal_itm + len_let + spc_lad, + _("Redraw")); + mvwprintw(swin, 1, len_cal_itm + len_let + spc_lad, _("Save")); + mvwprintw(swin, 0, 2 * len_cal_itm + len_let + spc_lad, + _("-/+1 Day")); + mvwprintw(swin, 1, 2 * len_cal_itm + len_let + spc_lad, + _("-/+1 Week")); + mvwprintw(swin, 0, 3 * len_cal_itm + len_let + spc_lad, + _("GoTo")); + mvwprintw(swin, 1, 3 * len_cal_itm + len_let + spc_lad, + _("Chg View")); + mvwprintw(swin, 0, 4 * len_cal_itm + len_let + spc_lad, + _("Config")); + } else { + custom_apply_attr(swin, ATTR_HIGHEST); + mvwprintw(swin, 0, 0, " ?"); + mvwprintw(swin, 1, 0, " Q"); + mvwprintw(swin, 0, len_oth_itm, " R"); + mvwprintw(swin, 1, len_oth_itm, " S"); + mvwprintw(swin, 0, 2 * len_oth_itm, "J/K"); + mvwprintw(swin, 1, 2 * len_oth_itm, "Tab"); + mvwprintw(swin, 0, 3 * len_oth_itm, " A"); + mvwprintw(swin, 1, 3 * len_oth_itm, " D"); + mvwprintw(swin, 0, 4 * len_oth_itm, " G"); + mvwprintw(swin, 1, 4 * len_oth_itm, " V"); + mvwprintw(swin, 0, 5 * len_oth_itm, " C"); + custom_remove_attr(swin, ATTR_HIGHEST); + wnoutrefresh(swin); + + mvwprintw(swin, 0, len_let + spc_lad, _("Help")); + mvwprintw(swin, 1, len_let + spc_lad, _("Quit")); + mvwprintw(swin, 0, len_oth_itm + len_let + spc_lad, + _("Redraw")); + mvwprintw(swin, 1, len_oth_itm + len_let + spc_lad, _("Save")); + mvwprintw(swin, 0, 2 * len_oth_itm + len_let + spc_lad, + _("Up/Down")); + mvwprintw(swin, 1, 2 * len_oth_itm + len_let + spc_lad, + _("Chg View")); + mvwprintw(swin, 0, 3 * len_oth_itm + len_let + spc_lad, + _("Add Item")); + mvwprintw(swin, 1, 3 * len_oth_itm + len_let + spc_lad, + _("Del Item")); + mvwprintw(swin, 0, 4 * len_oth_itm + len_let + spc_lad, + _( "GoTo")); + mvwprintw(swin, 1, 4 * len_oth_itm + len_let + spc_lad, + _("View")); + mvwprintw(swin, 0, 5 * len_oth_itm + len_let + spc_lad, + _("Config")); + } + wnoutrefresh(swin); +} + +long date2sec(unsigned year, unsigned month, unsigned day, unsigned hour, + unsigned min) +{ + struct tm start, *lt; + time_t tstart, t; + + t = time(NULL); + lt = localtime(&t); + start = *lt; + + start.tm_mon = month; + start.tm_mday = day; + start.tm_year = year; + start.tm_hour = hour; + start.tm_min = min; + start.tm_sec = 0; + start.tm_isdst = -1; + start.tm_year -= 1900; + start.tm_mon--; + tstart = mktime(&start); + if (tstart == -1) { + fputs(_("FATAL ERROR in date2sec: failure in mktime\n"), stderr); + fprintf(stderr, "%u %u %u %u %u\n", year, month, day, hour, min); + exit(EXIT_FAILURE); + } + return tstart; +} + +/* + * Returns the date in seconds from year 1900. + * If no date is entered, current date is chosen. + */ +long +get_sec_date(int year, int month, int day) +{ + struct tm *ptrtime; + time_t timer; + long long_date; + char current_day[3], current_month[3] ,current_year[5]; + + if (year == 0 && month == 0 && day == 0) { + timer = time(NULL); + ptrtime = localtime(&timer); + strftime(current_day, 3, "%d", ptrtime); + strftime(current_month, 3, "%m", ptrtime); + strftime(current_year, 5, "%Y", ptrtime); + month = atoi(current_month); + day = atoi(current_day); + year = atoi(current_year); + + } + long_date = date2sec(year, month, day, 0, 0); + return long_date; +} + +long min2sec(unsigned minutes) +{ + return minutes * 60; +} + +/* + * Checks if a time has a good format. + * The format could be either HH:MM or H:MM or MM, and we should have: + * 0 <= HH <= 24 and 0 <= MM < 999. + * This function returns 1 if the entered time is correct and in + * [h:mm] or [hh:mm] format, and 2 if the entered time is correct and entered + * in [mm] format. + */ +int check_time(char *string) +{ + int ok = 0; + char hour[] = " "; + char minutes[] = " "; + + if ( // format test [MM] + ((strlen(string) == 2) || (strlen(string) == 3)) & + (isdigit(string[0]) != 0) & + (isdigit(string[1]) != 0) + ) { // check if we have a valid time + strncpy(minutes, string, 2); + if ( atoi(minutes) >= 0) + ok = 2; + } + + else if ( // format test [H:MM] + (strlen(string) == 4) & + (isdigit(string[0]) != 0) & + (isdigit(string[2]) != 0) & + (isdigit(string[3]) != 0) & (string[1] == ':') + ) { // check if we have a valid time + strncpy(hour, string, 1); + strncpy(minutes, string + 2, 2); + if ((atoi(hour) <= 24) & (atoi(hour) >= + 0) & (atoi(minutes) < + 60) & (atoi(minutes) >= 0)) + ok = 1; + } + + else if ( //format test [HH:MM] + (strlen(string) == 5) & + (isdigit(string[0]) != 0) & + (isdigit(string[1]) != 0) & + (isdigit(string[3]) != 0) & + (isdigit(string[4]) != 0) & (string[2] == ':') + ) { // check if we have a valid time + strncpy(hour, string, 2); + strncpy(minutes, string + 3, 2); + if ((atoi(hour) <= 24) & (atoi(hour) >= + 0) & (atoi(minutes) < + 60) & (atoi(minutes) >= 0)) + ok = 1; + } + + return ok; +} + +/* + * Display a scroll bar when there are so many items that they + * can not be displayed inside the corresponding panel. + */ +void draw_scrollbar(WINDOW *win, int y, int x, int length, + int bar_top, int bar_bottom, bool hilt) +{ + mvwvline(win, bar_top, x, ACS_VLINE, bar_bottom - bar_top); + if (hilt) + custom_apply_attr(win, ATTR_HIGHEST); + wattron(win, A_REVERSE); + mvwvline(win, y, x, ' ', length); + wattroff(win, A_REVERSE); + if (hilt) + custom_remove_attr(win, ATTR_HIGHEST); +} + +/* + * Print an item (either an appointment, event, or todo) in a + * popup window. This is useful if an item description is too + * long to fit in its corresponding panel window. + */ +void item_in_popup(char *saved_a_start, char *saved_a_end, char *msg, + char *pop_title) +{ + WINDOW *popup_win; + + popup_win = popup(row - 4, col - 2, 1, 1, pop_title); + if (strncmp(pop_title, _("Appointment"), 11) == 0) { + mvwprintw(popup_win, 4, 4, " - %s -> %s", + saved_a_start, saved_a_end); + } + scroller(popup_win, msg, 1, 1, row - 4, col - 2); + wmove(swin, 0, 0); + doupdate(); + wgetch(popup_win); + delwin(popup_win); +} + +/* Show the window with a border and a label */ +void win_show(WINDOW * win, char *label) +{ + int startx, starty, height, width; + + getbegyx(win, starty, startx); + getmaxyx(win, height, width); + + box(win, 0, 0); + mvwaddch(win, 2, 0, ACS_LTEE); + mvwhline(win, 2, 1, ACS_HLINE, width - 2); + mvwaddch(win, 2, width - 1, ACS_RTEE); + + print_in_middle(win, 1, 0, width, label); +} + +/* + * Print an item description in the corresponding panel window. + */ +void display_item(WINDOW *win, int incolor, char *msg, int len, + int y, int x) +{ + char buf[len]; + + if (incolor == 0) + custom_apply_attr(win, ATTR_HIGHEST); + if (strlen(msg) < len) { + mvwprintw(win, y, x, "%s", msg); + } else { + strncpy(buf, msg, len - 1); + buf[len - 1] = '\0'; + mvwprintw(win, y, x, "%s...", buf); + } + if (incolor == 0) + custom_remove_attr(win, ATTR_HIGHEST); +} diff --git a/src/utils.h b/src/utils.h new file mode 100755 index 0000000..e7bdeff --- /dev/null +++ b/src/utils.h @@ -0,0 +1,55 @@ +/* $calcurse: utils.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#ifndef CALCURSE_UTILS_H +#define CALCURSE_UTILS_H + +void status_mesg(char *mesg_line1, char *mesg_line2); +void erase_window_part(WINDOW *win, int first_col, int first_row, + int last_col, int last_row); +WINDOW *popup(int pop_row, int pop_col, + int pop_y, int pop_x, char *pop_lab); +void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string); +void getstring(WINDOW *win, int colr, char *string, int start_x, int start_y); +int is_all_digit(char *string); +void border_color(WINDOW *window, int bcolr); +void border_nocolor(WINDOW *window); +void scroller(WINDOW *win, char *, int x, int y, int nb_row, int nb_col); +void status_bar(int which_pan, int colr, int nc_bar, int nl_bar); +long date2sec(unsigned year, unsigned month, unsigned day, unsigned hour, + unsigned min); +long get_sec_date(int year, int month, int day); +long min2sec(unsigned minutes); +int check_time(char *string); +void draw_scrollbar(WINDOW *win, int y, int x, int length, + int bar_top, int bar_bottom, bool hilt); +void item_in_popup(char *saved_a_start, char *saved_a_end, char *msg, + char *pop_title); +void win_show(WINDOW * win, char *label); +void display_item(WINDOW *win, int incolor, char *msg, + int len, int y, int x); + +#endif /* CALCURSE_UTILS_H */ diff --git a/src/vars.c b/src/vars.c new file mode 100755 index 0000000..524d944 --- /dev/null +++ b/src/vars.c @@ -0,0 +1,85 @@ +/* $calcurse: vars.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#include "i18n.h" +#include "vars.h" + +/* + * variables to store window size + */ +int col = 0, row = 0; + +/* variable to tell if the terminal supports color */ +bool colorize = false; + +/* + * variables to store calendar names + */ +int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; +char *monthnames[12] = + { N_("January"), + N_("February"), + N_("March"), + N_("April"), + N_("May"), + N_("June"), + N_("July"), + N_("August"), + N_("September"), + N_("October"), + N_("November"), + N_("December") }; + +char *daynames[8] = + { N_("Sun"), + N_("Mon"), + N_("Tue"), + N_("Wed"), + N_("Thu"), + N_("Fri"), + N_("Sat"), + N_("Sun") }; + +/* + * variables to store data path names, which are initialized in + * io_init() + */ +char path_dir[] = ""; +char path_todo[] = ""; +char path_apts[] = ""; +char path_conf[] = ""; + +/* + * Variables to handle calcurse windows: + * cwin = calendar window + * awin = appointment window + * twin = todo window + * swin = status bar window + */ +WINDOW *awin = NULL, *cwin = NULL, *twin = NULL, *swin = NULL; + +/* Variable to handle pads. */ +struct pad_s *apad; diff --git a/src/vars.h b/src/vars.h new file mode 100755 index 0000000..d9bb13e --- /dev/null +++ b/src/vars.h @@ -0,0 +1,69 @@ +/* $calcurse: vars.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */ + +/* + * Calcurse - text-based organizer + * Copyright (c) 2004-2006 Frederic Culot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Send your feedback or comments to : calcurse@culot.org + * Calcurse home page : http://culot.org/calcurse + * + */ + +#ifndef CALCURSE_VARS_H +#define CALCURSE_VARS_H + +#include <ncurses.h> +#include <stdbool.h> + +#define DIR_NAME ".calcurse" +#define TODO_PATH ".calcurse/todo" +#define APTS_PATH ".calcurse/apts" +#define CONF_PATH ".calcurse/conf" + +#define MAX_LENGTH 512 + +#define CTRL(x) ((x) & 0x1f) + +#define ATTR_FALSE 0 +#define ATTR_TRUE 1 +#define ATTR_LOWEST 2 +#define ATTR_LOW 3 +#define ATTR_MIDDLE 4 +#define ATTR_HIGH 5 +#define ATTR_HIGHEST 6 + +struct pad_s { + int width; + int length; + int first_onscreen; /* first line to be displayed inside window */ + WINDOW *ptrwin; /* pointer to the pad window */ +}; + +extern int col, row; +extern bool colorize; +extern int days[12]; +extern char *monthnames[12]; +extern char *daynames[8]; +extern char path_dir[MAX_LENGTH]; +extern char path_todo[MAX_LENGTH]; +extern char path_apts[MAX_LENGTH]; +extern char path_conf[MAX_LENGTH]; +extern WINDOW *awin, *cwin, *twin, *swin; +extern struct pad_s *apad; + +#endif /* CALCURSE_VARS_H */ |