summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Culot <calcurse@culot.org>2006-07-31 21:00:02 +0000
committerFrederic Culot <calcurse@culot.org>2006-07-31 21:00:02 +0000
commitac36e94341ca73d581f0df39f1c7bbf2138b2845 (patch)
tree47de561cd962ff8f47f6d811109907f15b9ff989
downloadcalcurse-ac36e94341ca73d581f0df39f1c7bbf2138b2845.tar.gz
calcurse-ac36e94341ca73d581f0df39f1c7bbf2138b2845.zip
Initial revision
-rwxr-xr-xAUTHORS1
-rwxr-xr-xChangeLog606
-rwxr-xr-xMakefile.am11
-rwxr-xr-xNEWS104
-rwxr-xr-xREADME31
-rwxr-xr-xTODO58
-rwxr-xr-xautogen.sh174
-rwxr-xr-xconfigure.ac44
-rwxr-xr-xdoc/manual_de.html728
-rwxr-xr-xdoc/manual_en.html783
-rwxr-xr-xdoc/manual_fr.html898
-rwxr-xr-xpo/LINGUAS4
-rwxr-xr-xpo/POTFILES.in14
-rwxr-xr-xpo/calcurse.pot760
-rwxr-xr-xpo/fr.po966
-rwxr-xr-xsrc/Makefile.am14
-rwxr-xr-xsrc/apoint.c235
-rwxr-xr-xsrc/apoint.h56
-rwxr-xr-xsrc/args.c431
-rwxr-xr-xsrc/args.h41
-rwxr-xr-xsrc/calcurse.1158
-rwxr-xr-xsrc/calcurse.c1156
-rwxr-xr-xsrc/calendar.c227
-rwxr-xr-xsrc/calendar.h41
-rwxr-xr-xsrc/custom.c178
-rwxr-xr-xsrc/custom.h42
-rwxr-xr-xsrc/day.c362
-rwxr-xr-xsrc/day.h66
-rwxr-xr-xsrc/event.c135
-rwxr-xr-xsrc/event.h48
-rwxr-xr-xsrc/help.c375
-rwxr-xr-xsrc/help.h41
-rwxr-xr-xsrc/i18n.h54
-rwxr-xr-xsrc/io.c484
-rwxr-xr-xsrc/io.h42
-rwxr-xr-xsrc/recur.c355
-rwxr-xr-xsrc/recur.h87
-rwxr-xr-xsrc/todo.c80
-rwxr-xr-xsrc/todo.h41
-rwxr-xr-xsrc/utils.c614
-rwxr-xr-xsrc/utils.h55
-rwxr-xr-xsrc/vars.c85
-rwxr-xr-xsrc/vars.h69
43 files changed, 10754 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100755
index 0000000..d183356
--- /dev/null
+++ b/AUTHORS
@@ -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
+
diff --git a/NEWS b/NEWS
new file mode 100755
index 0000000..ed1e823
--- /dev/null
+++ b/NEWS
@@ -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
diff --git a/README b/README
new file mode 100755
index 0000000..de77bb4
--- /dev/null
+++ b/README
@@ -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.
diff --git a/TODO b/TODO
new file mode 100755
index 0000000..b69e507
--- /dev/null
+++ b/TODO
@@ -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">&Uuml;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&uuml;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">&Uuml;bersetzung der Dokumentation</a>
+<li><a href="#contribute_i18n"><code>calcurse</code> i18n</a>
+<ul>
+<li><a href="#contribute_i18n_overview">&Uuml;berblick</a>
+<li><a href="#contribute_i18n_translator">Aufgaben des &Uuml;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&uuml;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&ouml;nlicher Terminkalender, der
+Ihnen bei der Organisation von Terminen und t&auml;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&ouml;nnen zur Laufzeit jederzeit erfragt werden.
+
+
+<a name="overview"></a><h1>&Uuml;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&ouml;ten. ;)<br>
+Ich mag Programme mit Textinterfaces, weil sie einfach, schnell,
+portabel und effizient sind. Also dachte ich dar&uuml;ber nach ein
+Programm mit textorientiertem Benutzer-Interface zu entwickeln.
+Dar&uuml;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&uuml;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&ouml;rtern 'CALendar' und 'nCurses', dem Namen
+der Bibliothek die f&uuml;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 &auml;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&ouml;nlichen Terminkalenders. Mit dem zweiten Modus ist es m&ouml;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&uuml;ber hinaus ist <code>calcurse</code> f&uuml;r Benutzer erstellt worden,
+mit der Absicht so benutzerfreundlich wie m&ouml;glich zu sein. Das
+bedeutet, dass eine komplette Onlinehilfe im Programm zu Verf&uuml;gung
+steht, sowie alle m&ouml;gliche Aktionen zu jeder Zeit in einer Statuszeile
+ersichtlich sind. Das Benutzer-Interface ist ebenfalls
+einstellbar. Ebenso kann man verschiedene Textfarben und Layouts
+w&auml;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&ouml;tigt einen C-Compiler wie etwa
+<code>cc</code> oder <code>gcc</code>. Ferner wird die
+ncurses-Bibliothek ben&ouml;tigt, dass aber auf den meisten Unix-Systemen
+verf&uuml;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&uuml;tzt die Internationalisierung
+ (k&uuml;nftig <em>i18n</em>) durch <code>gettext</code>.
+ Das bedeutet, dass <code>calcurse</code> mehrsprachige Mitteilungen
+ erzeugen kann, wenn es mit der entsprechenden Sprachunterst&uuml;tzung
+ kompiliert wurde (z.B. <em>NLS</em>).
+ Dennoch, <em>NLS</em> ist optional und wenn keine mehrsprachigen Mitteilungen
+ gew&uuml;nscht sind, kann diese Eigenschaft abgestellt werden. Einfach die Option <code>--disable-nls</code> dem <code>configure</code> Skript &uuml;bergeben
+ (siehe Abschnitt <ahref="#install_process">Installationsprozess</a>). <br>
+ Um zu &uuml;berpr&uuml;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&auml;hrend des <ahref="#install_process"> Installationsprozesses</a> anzugeben. Die entsprechende
+ Option f&uuml;r das <code>configure</code> Skript lautet dann <code>--with-libintl-prefix</code>.
+ Das <code>configure</code> Skript wird nat&uuml;rlich vorzeitig abbrechen, wenn die dazugeh&ouml;rige Bibliothek nicht gefunden wurde.
+
+
+<a name="install_process"></a><h2>Installationsprozess</h2>
+<p>
+Als erstes m&uuml;ssen die Dateien entpackt werden:
+<pre>
+ tar zxvf calcurse-1.4.tar.gz
+</pre>
+Wenn Sie die Voraussetzungen erf&uuml;llen und das Archiv entpackt
+vorliegen, sind nur noch die drei &uuml;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&uuml;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&ouml;gliche
+Formate m&ouml;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&auml;chsten 'n' Tagen zu erledigen sind.<br>
+Beispiel: die Eingabe <code>calcurse -d 3</code> gibt alle Termine von
+heute, morgen und &uuml;bermorgen aus.<br>
+<br>
+<dt><code>-h</code>
+<dd>
+Gibt eine Hilfe zu den Unterst&uuml;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&uuml;r i18n</h3>
+<p>
+
+ <code>calcurse</code> kann mit einer Unterst&uuml;tzung f&uuml;r die Muttersprache
+ kompiliert werden (siehe <a
+ href="#install_requirements_gettext"><code>gettext</code>
+ Bibliothek</a>). Wenn Meldungen in der Muttersprache gew&uuml;nscht sind,
+ sollte zunacht gepr&uuml;ft werden, ob die <code>po/LINGUAS</code> Datei verf&uuml;gbar ist.
+ Diese Datei zeigt alle verf&uuml;gbaren Sprachen durch
+ zweibuchstabige K&uuml;rzel an (z. B., <em>fr</em>
+ steht f&uuml;r franz&ouml;sisch). Wenn Ihre Sprache nicht aufgef&uuml;hrt ist, w&auml;re es
+ nat&uuml;rlich grossartig, wenn Sie sich an der &Uuml;bersetzung von <code>calcurse</code>
+ in andere Sprachen beteiligen k&ouml;nnten (siehe Abschnitt <a href="#contribute">Wie kann
+ ich einen Beitrag leisten?</a>).<br>
+ Wenn Ihre Sprache verf&uuml;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&uuml;nschten Spracheausgabe ist und durch
+ das K&uuml;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&uuml;hrt. Das bedeutet, dass die gew&uuml;nschten Informationen
+ausgegeben werden und das Programm anschlie&szlig;end sofort wieder beendet
+wird. So ist es m&ouml;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&auml;lt
+man ein Interface mit drei unterschiedlichen Panels, die mit der
+'TAB'-Taste angesteuert werden k&ouml;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&uuml;nschten Tag farblich hervor, w&auml;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
+&uuml;ber die m&ouml;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&auml;lt die Informationen zur Benutzerkonfiguration.<br>
+Die <em>apts</em> Datei enth&auml;lt alle Termine.<br>
+Die <em>todo</em> Datei enth&auml;lt die todo-Liste.
+
+
+<a name="basics_help"></a><h2>Online Hilfe</h2>
+<p>
+Das integrierte Hilfe-System kann jederzeit mit '?' aufgerufen
+werden. Informationen &uuml;ber bestimmte Befehle k&ouml;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&uuml;
+einstellbar. Dr&uuml;cke Sie dazu die 'C'-Taste. Ein weiteres Untermen&uuml;
+erscheint mit drei weiteren Auswahlpunkten: Ein erneutes Bet&auml;tigen der
+'C'-Taste f&uuml;hrt zur Farbeinstellung, die 'L'-Taste erlaubt die Auswahl
+eines anderen Layouts, das heisst die Anordnung der drei Panel kann
+hier ge&auml;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&auml;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&ouml;scht werden soll (entweder ein todo-Eintrag oder
+ein Termin). Ist confirm_delete auf <em>no</em>, wird durch Bet&auml;tigung der
+'D'-Taste ohne Nachfrage gel&ouml;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&uuml;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&ouml;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&ouml;nnen nach eigenen Vorlieben eingestellt
+werden. Durch Bet&auml;tigung der entsprechenden Taste kann die gew&uuml;nschte
+Farbkombination ausgew&auml;hlt werden. Die gew&auml;hlte Farbkombination werden
+dem Rahmen, dem Titel und der Status-Zeilen zugeordnet.
+
+ Eine schwarz/weiss Kombination ist ebenfalls verf&uuml;gbar, um Terminals ohne Farben zu unterst&uuml;tzen.<br>
+ <u>Beachte:</u>
+ <ul>
+ <li> In Abh&auml;ngigkeit des verwendeten Terminals und dem zugeordneten Wert der Umgebungsvariable <code>$TERM</code> werden Farben unterst&uuml;tzt oder nicht.
+ Eine Fehlermeldung erscheint, wenn versucht wird die Farben zu &auml;ndern obwohl
+ das Terminal keine Farben unterst&uuml;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&uuml;nschen
+anpassen.
+
+
+<a name="known_bugs"></a><h1>Bekannte Fehler</h1>
+<p>
+
+ Es kommt vor, dass W&ouml;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&auml;ndig f&uuml;r das <code>xterm</code>),
+ <em>xterm-xfree86</em> an Stelle f&uuml;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&uuml;tzen m&ouml;chten, k&ouml;nnen Sie mir
+zuerst eine kurze R&uuml;ckmeldung geben. Was finden Sie gut an diesem
+Programm oder was k&ouml;nnte besser sein. Gibt es vielleicht Programmeigenschaften,
+die Sie vermissen? Teilen Sie es mir mit!<br>
+
+ Von nun an ist es auch m&ouml;glich sich an der &Uuml;bersetzung der Prgrammmitteilungen
+ und der Dokumentation von <code>calcurse</code> zu beteiligen. <br>
+ <br>
+ <u>Beachte:</u> Jegliche Unterst&uuml;tzung <code>calcurse</code>
+ in andere Sprachen zu &uuml;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 &Uuml;bersetzung in Ihrer Sprache schon begonnen hat.
+
+
+
+<a name="contribute_documentation"></a><h2>&Uuml;bersetzung der Dokumentation</h2>
+<p>
+
+ Das <em>doc/</em> Verzeichnis des Source-Packets enth&auml;lt bereits
+ &uuml;besetzte Versionen der <code>calcurse</code> Anleitung.
+ Wenn eine &Uuml;bersetzung in Ihrer Sprache noch nicht vorhanden ist,
+ w&auml;re es grossartig, wenn Sie eine solche erstellen k&ouml;nnten.<br>
+ Kopieren Sie dazu eine der vorhandenen Version mit dem Dateinamen
+ <code>manual_XX.html</code>, wobei <em>XX</em>
+ das entsprechende K&uuml;rzel Ihrer Sprache ist. Anschliessend &uuml;bersetzen Sie diese
+ Datei und senden Sie dann an den Author (siehe <a href="#bugs">Mitteilung von Fehlern und Anregungen</a>), so dass Ihre &Uuml;bersetzung f&uuml;r die n&auml;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&auml;hnt, verwendet <code>calcurse</code> die <code>gettext</code> Utilities um mehrsprachige Programmmitteilungen zu erzeugen.
+ Dieser Abschnitt informiert dar&uuml;ber, wie Programmmitteilungen in Ihrer Muttersprache
+ &uuml;bersetzt werden. Dieses howto zur &Uuml;bersetzung von <code>calcurse</code> mit <code>gettext</code> ist nat&uuml;rlich nur ein Einstieg und wohl zu kurz. Um umfassendere Informationen
+ zu erhalten und sich die weite Welt der Sprach&uuml;bersetzung f&uuml;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 &Uuml;bersetzung beteiligt:
+ Programmierer, Sprachkoordinator und &Uuml;bersetzer.
+ Nach einem kurzen &Uuml;berblick, wie so etwas funktioniert, werden anschliessend die
+ Aufgaben des &Uuml;bersetzers beschrieben.
+
+
+<a name="contribute_i18n_overview"></a><h3>&Uuml;berblick</h3>
+<p>
+Um Text in der Muttersprache des Benutzers erscheinen zu lassen, sind zwei Schritte n&ouml;tig:
+ <em>Internationalisierung</em>
+ (i18n) und <em>Lokalisierung</em> (l10n).
+ Bei der i18n geht es darum ein Buch f&uuml;r mehrere Sprachen vorzubereiten.
+ Das wird vom Programmierer durchgef&uuml;hrt, der die zu &uuml;bersetzenden Texte markiert
+ und es somit erm&ouml;glicht, dass zur Laufzeit des Programms der Text &uuml;bersetzt erscheint.
+ Bei der l10n geht es darum, dem i18n markierten Pragramm <code>calcurse</code> die entsprechende &Uuml;bersetzung des Benutzers zukommen zu lassen. Die zuvor vom Programmierer
+ markierten Texte werden durch das richtige Setzen der Umgebung f&uuml;r <code>calcurse</code> &uuml;bersetzt.<br>
+ <br>
+
+ Also, die zu &uuml;bersetzenden Texte werden zun&auml;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 &Uuml;bersetzungen enthalten
+ (<em>fr.po</em> f&uuml;r franz&ouml;sisch, hier steht <em>po</em> f&uuml;r <em>portable object</em>,
+ dieses Format kann man lesen und ver&auml;ndern),
+ zusammengef&uuml;hrt. Ein &Uuml;bersetzer kann diese Datei dazu &ouml;ffnen, die enthaltenen Texte &uuml;bersetzen
+ und sie dann an den Programmierer zur&uuml;ck senden.
+ Wenn das Programm kompiliert wird, erzeugt der Kompiler (aus Gr&uuml;nden der Effizienz)
+ eine bin&auml;re Version dieser Datei (<em>fr.mo</em> - <em>mo</em> steht f&uuml;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&auml;ngigkeit zur lokalen Einstellung des Benutzers zu &uuml;bersetzen.
+
+
+<a name="contribute_i18n_translator"></a><h3>Aufgaben des &Uuml;bersetzers</h3>
+<p>
+ Wenn Sie mit der &Uuml;bersetzung in eine neue Sprache beginnen m&ouml;chte sind hier die Schritte dazu:
+ <ul>
+ <li>Finden Sie zun&auml;chst heraus, wie die K&uuml;rzel der Sprache definiert sind.
+ Beispielsweise sind die K&uuml;rzel f&uuml;r die franz&ouml;sische 'fr_FR', oder einfacher
+ 'fr'. Das ist der Wert, den der Benutzer als Umgebungsvariable <code>LC_ALL</code> f&uuml;r die Programme setzen muss (siehe <a href="#basics_invocation_variable">Umgebungsvariable f&uuml;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 &auml;nderen Sie den Dateikopf manuel.<br>
+ Wenn die Datei <em>fr.po</em> erstellt ist, kann mit der eigentlichen &Uuml;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&uuml;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 &uuml;bersetzende Text.
+ <li><em>msgstr Zeilen:</em> der &uuml;bersetzte Text.
+ <li><em>Zeilen, die mit '#' beginnen:</em> Kommentare (einige mit spezieller Bedeutung,
+ wie wir weiter unten noch sehen werden).
+ </ol>
+ &Uuml;bersetzen Sie die <em>msgid</em> Zeilen und tragen Sie den &uuml;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 &uuml;bersetzt wurde, aber die Stelle im Programmcode ver&auml;ndert wurde, oder
+ aber es handelt sich um einen neuen Text, f&uuml;r welchen <code>gettext</code> eine sog. 'wild guess' vornimmt, also selbst eine &Uuml;bersetzung versucht.
+ Das beduetet, die &Uuml;bersetzung sollte noch einmal &uuml;berarbeitet werden.
+ Manchmal wurde der Originaltext ver&auml;ndert, weil ein Rechtschreibfehler korrigiert wurde. In einem solchen Fall muss nichts ver&auml;ndert werden.
+ Manchmal ist die &Uuml;bersetzung aber nicht optimal gelungen und muss dann ver&auml;ndert werden.
+ Wenn die &Uuml;bersetzung fertig ist, entferne die <code>"#, fuzzy"</code> Zeilen. Die &Uuml;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&auml;ndert bleiben werden sollte.
+ Beispielsweise die %-Sequenzen, wie <code>"%s"</code>.
+ Diese bedeuten, dass <code>calcurse</code> dort Text einf&uuml;gen wird.
+ Es ist also wichtig, diese nicht zu ver&auml;ndern.
+ Ebenso kommen \-Sequenzen vor, wie <code>\n</code> oder
+ <code>\t</code>. Auch nicht ver&auml;ndern.
+ Das erste stellt das Zeilenende dar, das zweite eine Tabulation.<br>
+ <br>
+ <li><em>&Uuml;bersetzungen k&ouml;nnen in Bl&ouml;cke geschrieben werden</em><br>
+ Wenn Zeilen zu lang werden, k&ouml;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 &auml;hnlich sein
+ <pre>
+ "Content-Type: text/plain; charset=utf-8\n"
+ </pre>
+
+ Auch das &Uuml;bersetzer-Feld sollte ausgef&uuml;llt sein, damit andere potentielle Mitstreiter, die sich an der &Uuml;bersetzung beteiligen wollen, Kontakt mit Ihnen aufnehmen k&ouml;nnen. Ebenso k&ouml;nnen von anderen entdeckte Fehler an den &Uuml;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&uuml;gen von Kommentaren (Zeilen beginnen mit dem '#' Zeichen) ist eine gute M&ouml;glichkeit
+ Probleme und &Uuml;bersetzungsschwierigkeiten besser zu l&ouml;sen. Die &Uuml;bersetzungsarbeit wird besser
+ lesbar.<br>
+ <br>
+ <li><em>L&auml;ngen der Texte</em><br>
+ <code>calcurse</code>
+ ist ein curses/Konsolen Programm und kann somit von der Gr&ouml;sse des Terminals (Anzahl der
+ Zeilen) abh&auml;ngen. Dies sollte bei der &Uuml;bersetzung ber&uuml;cksichtigt werden.
+ H&auml;ufig m&uuml;ssen Texte in eine Zeile passen (Standardl&auml;nge ist 80 Zeichen).
+ &Uuml;bersetzen Sie nicht blind, versuchen Sie herauszufinden, wo der Text erscheint um die &Uuml;bersetzung richtig anzupassen.
+ <br>
+ <br>
+ <li><em>Ein paar n&uuml;tzliche Programme</em><br>
+ Das po-Dateiformat ist sehr einfach und kann mit einem Editor ge&auml;ndert werden.
+ Es gibt aber auch einige spezielle Tools die das Erstellen und &Auml;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&auml;lt Links und Angaben, die Sie interessieren
+k&ouml;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&uuml;ndigungsliste</h2>
+<p>
+Wenn Interesse an Calcurse besteht und Sie gerne &uuml;ber Neuerscheinungen
+informiert werden m&ouml;chten, k&ouml;nnen Sie gerne auf eine Liste gesetzt
+werden, die Sie per Mail &uuml;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&ouml;chte ich gerne f&uuml;r Ihre Unterst&uuml;tzung danken, ohne
+die dieses Projekt nicht m&ouml;glich gewesen w&auml;re. Hier ist die Liste
+derjenigen, denen ich Danke sagen m&ouml;chte:
+<ul>
+<li>Alex f&uuml;r die Patches, Hilfen und Erl&auml;uterungen zur <code>C</code> Programmierung.
+<li>Gwen f&uuml;rs Testen und Anregungen, wie <code>calcurse</code> verbessert werden kann.
+<li>Kevin und Ryan f&uuml;r das Binary-Packet auf Debian.
+<li>Steffen f&uuml;r das Binary-Packet auf Archlinux
+<li>Alexandre f&uuml;r das Binary-Packet auf Mac OsX.
+<li>Joel f&uuml;r sein Kalender-Skript das mich zum Calcurse-Layout inspiriert hat.
+<li>Michael Schulz f&uuml;r die deutsche &uuml;bersetzung der Dokumentation
+<li>Leute die Programme geschrieben haben, die ich mag und mich inspiriert haben, insbesondere :
+<ul>
+<li><code>vim</code> f&uuml;r die Befehlssteuerung
+<li><code>orpheus</code> und <code>abook</code> f&uuml;r die Dokumentation
+<li><code>pine</code> und <code>aptitude</code> f&uuml;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&eacute;d&eacute;ric Culot<br>
+German translation by Michael Schulz <code>&lt;bloodshower.at.web.dot.de&gt;</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&eacute;d&eacute;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&egrave;res</h1>
+<ul>
+<li><a href="#intro">Introduction</a>
+<li><a href="#overview">Aper&ccedil;u du logiciel</a>
+<ul>
+<li><a href="#overview_history">Origine de Calcurse</a>
+<li><a href="#overview_features">Caract&eacute;ristiques importantes</a>
+</ul>
+<li><a href="#install">Installation</a>
+<ul>
+<li><a href="#install_requirements">Pr&eacute;-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&eacute;sentation g&eacute;n&eacute;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&eacute;n&eacute;rales</a>
+<li><a href="#options_colors">Th&egrave;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&ccedil;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&eacute;rer les rendez-vous et les t&acirc;ches
+ &agrave; faire. Il est compos&eacute; d'un calendrier, d'une
+ liste de t&acirc;ches, et classe les rendez-vous.
+ L'interface utilisateur est configurable, et l'on peut
+ choisir entre diff&eacute;rents th&egrave;mes graphiques (couleur et
+ disposition des &eacute;lements de l'interface).
+ Toutes les commandes sont document&eacute;es dans un syst&egrave;me
+ d'aide en ligne.
+
+
+<a name="overview"></a><h1>Aper&ccedil;u du logiciel</h1>
+<a name="overview_history"></a><h2>Origine de Calcurse</h2>
+<p>
+ J'ai commenc&eacute; &agrave; penser &agrave; ce projet &agrave; la fin de mon doctorat
+ en astrophysique... Je commen&ccedil;ais en effet &agrave; avoir de plus
+ en plus de mal &agrave; m'organiser, et j'avais vraiment besoin d'un
+ bon outil pour m'aider dans cette t&acirc;che difficile ;)<br>
+ D'autre part, j'appr&eacute;cie beaucoup les logiciels qui font
+ appel &agrave; des Interfaces en Mode Texte, parce que je les trouve
+ plus simples, plus rapides, plus portables et plus efficaces.
+ J'ai alors commenc&eacute; &agrave; programmer un calendrier rudimentaire
+ qui utilisait une interface de ce type.
+ En plus de cela, je voulais am&eacute;liorer mes connaissances en
+ <code>C</code>, langage de programmation que je n'avais
+ utilis&eacute; jusqu'alors que dans le cadre de petits projets pendant
+ mes &eacute;tudes. J'ai donc pens&eacute; que ce serait une bonne chose de me
+ lancer dans ce projet, puisque cela me permettrait &agrave; la fois de
+ mieux m'organiser, et d'apprendre &agrave; mieux programmer en
+ <code>C</code>!
+ Malheureusement, j'ai obtenu mon doctorat avant de terminer
+ <code>calcurse</code>, mais j'ai tout de m&ecirc;me voulu continuer
+ &agrave; travailler
+ sur ce projet, en esp&eacute;rant que ce programme serait utile &agrave;
+ d'autres personnes. Voil&agrave; comment est n&eacute;
+ <code>calcurse</code>...<br>
+ <br>
+ Mais au fait, pourquoi 'calcurse' ? Et bien ce nom provient
+ simplement de la concat&eacute;nation de 'CALendrier' et de 'nCURSEs',
+ qui est le nom de la librairie utilis&eacute;e pour construire
+ l'interface utilisateur.
+
+
+<a name="overview_features"></a><h2>Caract&eacute;ristiques importantes</h2>
+<p>
+ <code>Calcurse</code> est multi-plateformes et est con&ccedil;u pour
+ &ecirc;tre l&eacute;ger, rapide et fiable. Il doit &ecirc;tre utilis&eacute; 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 &ecirc;tre lanc&eacute; dans deux modes diff&eacute;rents:
+ soit interactif, soit non-interactif. Le premier mode permet
+ de visualiser son organiseur personnel pratiquement sous
+ n'importe quel environnement, gr&acirc;ce &agrave; l'interface en mode texte.
+ Le deuxi&egrave;me mode permet de cr&eacute;er facilement des penses-b&ecirc;te en
+ ajoutant <code>calcurse</code> avec les arguments appropri&eacute;s dans
+ la table cron ou dans le script d'initialisation du shell.<br>
+ De plus, <code>calcurse</code> a &eacute;t&eacute; cr&eacute;&eacute; en prenant en compte
+ l'utilisateur final &agrave; chaque &eacute;tape de sa conception, c'est-&agrave;-dire
+ en essayant d'&ecirc;tre le plus intuitif possible. Cela implique
+ la pr&eacute;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 &eacute;galement configurable, et l'on peut
+ choisir parmis de nombreuses combinaisons possibles de couleurs
+ et de positions des fen&ecirc;tres.
+
+
+<a name="install"></a><h1>Installation</h1>
+<a name="install_requirements"></a><h2>Pr&eacute;-requis</h2>
+<a name="install_requirements_ncurses"></a><h3>Librairie <code>ncurses</code></h3>
+<p>
+ L'installation de <code>Calcurse</code> ne n&eacute;cessite qu'un
+ compilateur <code>C</code>, comme <code>cc</code> ou <code>gcc</code>,
+ et la librairie <code>ncurses</code>.
+ Il serait tr&egrave;s surprenant que vous n'ayez pas d&eacute;j&agrave; la librairie
+ <code>ncurses</code> d'install&eacute;e sur votre machine, mais si
+ c'est le cas, vous pourrez la trouver &agrave; 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&eacute; <em>i18n</em> ci-apr&egrave;s).
+ Cela signifie que <code>calcurse</code> peut fournir des
+ messages multilingues si il est compil&eacute; 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&eacute;s, vous pouvez s&eacute;sactiver cette option.
+ La d&eacute;sactivation du support <em>NLS</em> s'effectue en
+ passant l'option <code>--disable-nls</code> &agrave;
+ <code>configure</code> (voir la section <a
+ href="#install_process">Processus d'Installation</a>). <br>
+ Pour v&eacute;rifier que les utilitaires <code>gettext</code>
+ sont bien install&eacute;s sur votre systs&egrave;me, vous
+ pouvez par exemple v&eacute;rifier la pr&eacute;sence du
+ fichier <code>libintl.h</code> en tapant :
+ <pre>
+ locate libintl.h
+ </pre>
+ Dans l'&eacute;ventualit&eacute; o&ugrave; ce fichier ne
+ serait pas trouv&eacute;, vous pouvez obtenir les sources de
+ <code>gettext</code> &agrave; l'adresse suivante :<br>
+ <pre>
+ http://ftp.gnu.org/pub/gnu/gettext/
+ </pre>
+ <u>Remarque:</u> M&ecirc;me si <code>libintl.h</code> est bien
+ localis&eacute; par la commande pr&eacute;c&eacute;dente, il
+ peut &ecirc;tre utile de sp&eacute;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&eacute; dans un endroit usuel.
+
+
+<a name="install_process"></a><h2>Processus d'installation</h2>
+<p>
+ Vous devez tout d'abord d&eacute;compresser l'archive source de la
+ mani&egrave;re suivante :
+ <pre>
+ tar zxvf calcurse-1.4.tar.gz
+ </pre>
+ Une fois que vous remplissez tous les pr&eacute;-requis n&eacute;cessaires &agrave;
+ l'installation, le processus de compilation est simple et suit
+ les trois &eacute;tapes usuelles :
+ <OL>
+ <li><code>./configure</code>
+ <li><code>make</code>
+ <li><code>make install</code> (peut n&eacute;cessiter les privil&egrave;ges
+ super-utilisateur)
+ </OL>
+ Vous pouvez obtenir la liste des options possibles en tapant
+ <code>./configure --help</code>.
+
+
+<a name="basics"></a><h1>Pr&eacute;sentation g&eacute;n&eacute;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 &agrave; utiliser peut &ecirc;tre
+ sp&eacute;cifi&eacute; en utilisant l'option '-c'.<br>
+ <br>
+ <dt><code>-c</code>
+ <dd>
+ Sp&eacute;cifie le fichier calendrier &agrave; uiliser.<br>
+ Le calendrier par d&eacute;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&eacute;s, suivant le format de l'argument. Deux
+ formats diff&eacute;rents sont accept&eacute;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&eacute;cifi&eacute;e sera affich&eacute;e, alors que dans le
+ deuxi&egrave;me cas, la liste des rendez-vous pour les 'n'
+ jours &agrave; venir sera retourn&eacute;e.<br>
+ Par exemple, taper <code>calcurse -d 3</code> fera
+ s'afficher les rendez-vous pour aujourd'hui, demain
+ et apr&egrave;s-demain.<br>
+ <u>Remarque:</u> comme pour l'option '-a', le fichier
+ contenant le calendrier &agrave; lire peut &ecirc;tre sp&eacute;cifi&eacute; en
+ utilisant l'option '-c'.<br>
+ <br>
+ <dt><code>-h</code>
+ <dd>
+ Affiche l'aide d&eacute;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 &ecirc;tre compil&eacute; 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&eacute;s apparaissent dans votre langue
+ natale, assurez-vous tout d'abord que celle-ci est
+ pr&eacute;sente dans le fichier <code>po/LINGUAS</code>.
+ Ce fichier indique toutes les traductions disponibles par
+ l'interm&eacute;diaire d'un code de deux lettres (par exemple,
+ <em>fr</em> repr&eacute;sente le fran&ccedil;ais). Si vous ne
+ trouvez pas votre langue, il serait tr&egrave;s
+ appr&eacute;ci&eacute; 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&ugrave; <em>fr_FR</em> doit &ecirc;tre remplac&eacute; par
+ la <em>locale</em> (code de la langue suivi du code pays)
+ correspondant &agrave; 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&eacute; 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&eacute; en mode non-interactif.
+ Cela signifie que l'information demand&eacute;e sera affich&eacute;e,
+ puis <code>calcurse</code> quittera et vous serez ramen&eacute;
+ au prompt de l'interpr&eacute;teur de commandes.<br>
+ De ce mani&egrave;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 &agrave; chaque
+ d&eacute;but de session la liste des t&acirc;ches &agrave; faire et des rendez-vous
+ planifi&eacute;s pour la journ&eacute;e.
+
+
+<a name="basics_interface_interactive"></a><h3>Mode interactif</h3>
+<p>
+ Lorsqu'il est appel&eacute; sans aucun argument ou uniquement avec
+ l'option <code>'-c'</code>, <code>calcurse</code> est lanc&eacute;
+ en mode interactif. Dans ce mode s'affiche une interface qui
+ contient trois panneaux diff&eacute;rents, qu'il est possible de
+ s&eacute;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&eacute;sente un calendrier qui permet de
+ s&eacute;lectionner un jour en particulier. Le second panneau contient
+ une liste d'&eacute;v&egrave;nements et les rendez-vous du jour, et le dernier
+ contient une liste des t&acirc;ches &agrave; faire, mais qui ne sont pas
+ assign&eacute;e &agrave; une journ&eacute;e en particulier.
+ En bas de l'&eacute;cran on retrouve une barre de status, qui indique
+ les actions possibles en fonction du contexte, ainsi que la
+ touche qui doit &ecirc;tre press&eacute;e pour effectuer cette action.
+
+
+<a name="basics_files"></a><h2>Fichiers</h2>
+<p>
+ La structure de fichiers suivante est cr&eacute;&eacute;e dans le r&eacute;pertoire
+ <code>$HOME</code> de l'utilisateur la premi&egrave;re fois que
+ <code>calcurse</code> est lanc&eacute; :
+ <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 &eacute;venements ainsi que
+ les rendez-vous de l'utilisateur.<br>
+ Le fichier <em>todo</em> contient la liste des t&acirc;ches &agrave; effectuer.
+
+
+<a name="basics_help"></a><h2>Aide en ligne</h2>
+<p>
+ A n'importe quel moment, le syst&egrave;me d'aide en ligne peut &ecirc;tre
+ appel&eacute; en pressant la touche '?'. Une fois rentr&eacute; dans l'aide,
+ les informations sur une commande sp&eacute;cifique peuvent &ecirc;tre
+ obtenues en appuyant sur la touche correspondant &agrave; cette
+ commande.
+
+
+<a name="options"></a><h1>Options</h1>
+<p>
+ Tous les param&egrave;tres de <code>calcurse</code> sont configurables
+ &agrave; partir du menu <em>Configuration</em>, accessible en appuyant
+ sur 'C'. L'utilisateur se voit alors pr&eacute;sent&eacute; un second menu
+ avec trois choix possibles : appuyer &agrave; nouveau sur 'C' am&egrave;ne
+ au menu de s&eacute;lection des couleurs de l'interface, appuyer sur
+ 'L' permet de choisir parmis diff&eacute;rents emplacements pour les
+ panneaux de la fen&ecirc;tre principale de <code>calcurse</code>,
+ et enfin les options g&eacute;n&eacute;rales peuvent &ecirc;tre fix&eacute;es en pressant
+ 'G'.
+
+
+<a name="options_general"></a><h2>Options g&eacute;n&eacute;rales</h2>
+<p>
+ Ces options contr&ocirc;lent le comportement g&eacute;n&eacute;ral de
+ <code>calcurse</code>, comme d&eacute;crit ci-dessous :
+ <ul>
+ <li><code>sauvegarde_automatique</code> (valeur par d&eacute;faut: <em>oui</em>)<br>
+ Cette option permet de sauvegarder automatiquement les
+ donn&eacute;es de l'utilisateur avant de quitter, si elle est
+ fix&eacute;e &agrave; <em>oui</em>.<br>
+ <em>attention:</em> Aucune donn&eacute;e ne sera automatiquement
+ sauvegard&eacute;e si cette variable est fix&eacute;e &agrave; <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&eacute;faut: <em>oui</em>)<br>
+ Si cette option est fix&eacute;e &agrave; <em>oui</em>, la confirmation
+ de l'utilisateur est n&eacute;cessaire avant de pouvoir quitter.
+ Autrement, appuyer sur 'Q' provoquera l'arr&ecirc;t de
+ <code>calcurse</code> sans demander confirmation.<br>
+ <br>
+ <li><code>confirmer_pour_effacer</code> (valeur par d&eacute;faut: <em>oui</em>)<br>
+ Si cette option est fix&eacute;e &agrave; <em>oui</em>, appuyer sur 'D'
+ pour effacer un &eacute;lement (soit une t&acirc;che, un rendez-vous ou bien
+ un &eacute;venement) provoquera l'apparition d'un message demandant
+ la confirmation de l'utilisateur avant d'effacer cet &eacute;lement.
+ Si cette option est fix&eacute;e &agrave; <em>non</em>, aucune confirmation
+ ne sera demand&eacute;e avant l'effacement d'un &eacute;lement.<br>
+ <br>
+ <li><code>masquer_messages_syst&egrave;me</code> (valeur par d&eacute;faut: <em>non</em>)<br>
+ Fixer cette option &agrave; <em>oui</em> provoque la disparition des
+ messages relatifs aux enregistrements ou lectures des fichiers
+ de donn&eacute;es. Ceci peut &ecirc;tre utile pour acc&eacute;lerer les processus
+ d'entr&eacute;es/sorties.<br>
+ <br>
+ <li><code>masquer_barre_progression</code> (valeur par d&eacute;faut: <em>non</em>)<br>
+ Si elle est fix&eacute;e &agrave; <em>oui</em>, cette option provoque la
+ disparition de la barre de progression qui est normalement charg&eacute;e
+ d'indiquer l'&eacute;t&acirc;t d'avancement de l'enregistrement des fichiers
+ de donn&eacute;es. Si cette option est fix&eacute;e &agrave; <em>non</em>, cette barre
+ sera affich&eacute;e, en m&ecirc;me temps que le nom du fichier de donn&eacute;es
+ actuellement en cours d'&eacute;criture
+ (voir la section <a href="#basics_files">Fichiers</a>).<br>
+ <br>
+ <li><code>semaine_commence_lundi</code> (valeur par d&eacute;faut: <em>oui</em>)<br>
+ Il est possible dans <code>calcurse</code> d'indiquer quel est le premier
+ jour de la semaine, &agrave; savoir soit le lundi, soit le dimanche.
+ Si l'option <em>semaine_commence_lundi</em> est fix&eacute;e &agrave;
+ <em>oui</em>, les semaines du calendrier commenceront le lundi.
+ Par contre si cette option est fix&eacute;e &agrave; <em>non</em>,
+ les semaines d&eacute;buteront le dimanche.
+ </ul>
+
+
+<a name="options_colors"></a><h2>Th&egrave;mes graphiques</h2>
+<p>
+ Le th&egrave;me graphique de <code>calcurse</code> est
+ configurable et doit &ecirc;tre choisi en appuyant sur le
+ num&eacute;ro correspond &agrave; la couleur voulue. Cette
+ couleur est alors appliqu&eacute;e &agrave; la bordure des
+ panneaux, aux titres, aux combinaisons de touches, et aux
+ informations g&eacute;n&eacute;rales affich&eacute;es dans la
+ barre de status. Un th&egrave;me en noir et blanc est
+ &eacute;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 &ecirc;tre support&eacute;e ou non. Un message
+ d'erreur appara&icirc;tra si vous essayez d'appliquer un
+ th&egrave;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 &agrave; l'int&eacute;rieur de la fen&ecirc;tre de
+ <code>calcurse</code> peut &ecirc;tre param&eacute;tr&eacute;e. Par d&eacute;faut, le
+ panneau contenant le calendrier se situe en haut &agrave; droite de
+ la fen&ecirc;tre, le panneau contenant la liste des t&acirc;ches est situ&eacute;
+ en bas &agrave; droite, et le panneau contenant les rendez-vous se
+ trouve sur la partie gauche de l'&eacute;cran (voir la figure dans la
+ section <a href="#basics_interface_interactive">Mode interactif</a>
+ pour un exemple de la disposition par d&eacute;faut).<br>
+ En choisissant une autre disposition pour les &eacute;l&eacute;ments composants
+ la fen&ecirc;tre de <code>calcurse</code>, l'utilisateur peut adapter
+ &agrave; ses besoins l'interface du programme.
+
+
+<a name="known_bugs"></a><h1>Bogues connus</h1>
+<p>
+ Une coloration incorrecte des objets peut r&eacute;sulter
+ d'une utilisation conjointe d'un th&egrave;me graphique en
+ noir et blanc et d'une variable <code>$TERM</code>
+ fix&eacute;e &agrave; <em>xterm-color</em>. Pour supprimer ce
+ bogue, et comme le conseille Thomas E. Dickey (le
+ r&eacute;sponsable du projet <code>xterm</code>),
+ <em>xterm-xfree86</em> devrait &ecirc;tre assign&eacute;
+ &agrave; 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&eacute;e pour les entr&eacute;es terminfo qui ne
+ supportent pas bce. Utilisez plut&ocirc;t l'entr&eacute;e
+ xterm-xfree86 qui est distribu&eacute;e avec le xterm
+ d'XFree86 (ou par celui, similaire, distribu&eacute; 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 &agrave;
+ l'adresse suivante :
+ <pre>
+ calcurse@culot.org
+ </pre>
+ ou directement &agrave; l'auteur :
+ <pre>
+ frederic@culot.org
+ </pre>
+
+<a name="contribute"></a><h1>Comment contribuer?</h1>
+<p>
+ Si vous d&eacute;sirez contribuer au projet, vous pouvez tout d'abord
+ envoyer vos commentaires sur ce qui vous plais ou d&eacute;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 &agrave; la traduction de
+ <code>calcurse</code> serait tr&egrave;s
+ appr&eacute;ci&eacute;e, mais avant tout, envoyez un mail
+ &agrave; <code>calcurse-i18n@culot.org</code> pour savoir si
+ quelqu'un a d&eacute;j&agrave; commenc&eacute; le processus de
+ traduction dans votre langue.
+
+
+<a name="contribute_documentation"></a><h2>Traduction de la documentation</h2>
+<p>
+ Le r&eacute;pertoire <em>doc/</em> du paquet source contient
+ d&eacute;j&agrave; 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&egrave;s
+ appr&eacute;ci&eacute;e.<br>
+ Pour cela, il suffit de copier un des fichiers existant et de
+ renommer cette copie en <code>manual_XX.html</code>, o&ugrave;
+ <em>XX</em> repr&eacute;sente votre langue. Il faut ensuite
+ traduire ce fichier nouvellement cr&eacute;&eacute; et de
+ l'envoyer &agrave; 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&eacute; plus haut, les utilitaires
+ <code>gettext</code> sont utilis&eacute;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&eacute;lib&eacute;r&eacute;ment incompl&egrave;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&eacute;f&eacute;rable de se
+ r&eacute;f&eacute;rer au manuel de <code>GNU gettext</code>
+ que l'on peut trouver &agrave; l'adresse suivante :
+ <pre>
+ http://www.gnu.org/software/gettext/manual/
+ </pre>
+ Pour r&eacute;sumer, trois cat&eacute;gories de personnes sont
+ impliqu&eacute;es dans la cha&icirc;ne de traduction : les
+ programmeurs, les coordinateurs de la traduction, et les
+ traducteurs. Apr&egrave;s un rapide aper&ccedil;u de la
+ mani&egrave;re de proc&eacute;der pour traduire le logiciel,
+ nous d&eacute;crirons plus en d&eacute;tails les t&acirc;ches du
+ traducteur.
+
+
+<a name="contribute_i18n_overview"></a><h3>Aper&ccedil;u</h3>
+<p>
+ Afin de pouvoir afficher du texte dans la langue natale de
+ l'utilisateur, deux &eacute;tapes sont n&eacute;cessaires :
+ l'<em>internationalisation</em> (i18n), et la
+ <em>localisation</em> (l10n).
+ l'i18n permet &agrave; <code>calcurse</code> d'&ecirc;tre
+ multilingues. C'est un processus qui est mis en place par les
+ programmeurs, qui marquent les phrases &agrave; traduire au
+ sein du code source, et qui fournissent les outils pour que
+ ces phrases soient traduites automatiquement pendant le
+ d&eacute;roulement du programme.
+ La l10n correspond quant &agrave; elle au processus qui permet
+ &agrave; <code>calcurse</code> de s'adapter &agrave; la langue
+ de l'utilisateur. C'est-&agrave;-dire qu'il traduit les
+ phrases pr&eacute;c&eacute;demment marqu&eacute;e par les
+ programmeurs, et qu'il fixe correctement les variables
+ d'environnement afin que <code>calcurse</code> puisse utiliser
+ les r&eacute;sultats de cette traduction.<br>
+ <br>
+ Ainsi, les phrases traduisibles sont tout d'abord
+ marqu&eacute;es par les programmeurs dans le code source, puis
+ rassembl&eacute;es dans un fichier r&eacute;f&eacute;rence
+ (<code>calcurse.pot</code> - l'extension <em>pot</em> signifiant
+ <em>portable object template</em>, objet portable de
+ r&eacute;f&eacute;rence). Le contenu de ce fichier est alors
+ associ&eacute; aux fichiers contenant la traduction pour
+ chacune des diff&eacute;rentes langues (fichier <em>fr.po</em>
+ pour le fran&ccedil;ais par exemple - <em>po</em> siginifiant
+ <em>portable object</em>, objet portable - qui peut &ecirc;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&eacute;veloppeurs. Ensuite, au niveau de la
+ compilation du programme, une version binaire de ce fichier
+ sera produite (pour des raisons d'efficacit&eacute;), puis
+ install&eacute;e. Cette version binaire a pour extension
+ <em>.mo</em>, o&ugrave; <em>mo</em> signifie <em>machine
+ object</em> - objet machine, c'est-&agrave;-dire qui peut
+ &ecirc;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 &eacute;tapes &agrave; suivre
+ pour ce faire :
+ <ul>
+ <li>Premi&egrave;rement, trouver quel est le nom de la locale
+ correspondant &agrave; la langue &agrave; traduire. Par
+ exemple, pour le fran&ccedil;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&eacute;pertoire
+ <em>po/</em>, et cr&eacute;er un nouveau fichier <em>.po</em>
+ &agrave; partir du fichier de r&eacute;f&eacute;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&eacute; sur
+ votre syst&egrave;me, vous pouvez plus simplement copier
+ <em>calcurse.pot</em> en <em>fr.po</em> par exemple, et editer
+ l'en-t&ecirc;te du fichier nouvellement cr&eacute;&eacute;
+ manuellement.<br>
+ Maintenant, ayant &agrave; 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 &eacute;l&eacute;ments
+ diff&eacute;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&eacute;ro de ligne), afin de retrouver
+ simplement le contexte d'o&ugrave; est issu la phrase &agrave;
+ traduire.
+ <li><em>ligne msgid:</em> indique la phrase &agrave; traduire.
+ <li><em>ligne msgstr:</em> ligne indiquant la phrase traduite.
+ <li><em>lignes commen&ccedil;ant par '#'</em>: indiquent des
+ commentaires (certains ont une signification sp&eacute;ciale,
+ comme nous le verrons plus tard).
+ </ol>
+ Pour r&eacute;sumer, un traducteur doit simplement remplir les
+ champs <em>msgstr</em> avec la traduction des lignes
+ trouv&eacute;es juste au dessus dans la partie <em>msgid</em>.
+ <p>
+ <u>Remarques:</u>
+ <ul>
+ <li><em>Phrases marqu&eacute;es Fuzzy</em><br>
+ Vous pourrez rencontrer des phrases commen&ccedil;ant par le
+ commentaire <code>"#, fuzzy"</code>.
+ <code>calcurse</code> n'utilisera pas les traductions
+ commen&ccedil;ant par ce commentaire, &agrave; moins que vous
+ ne transformiez ces phrases. En effet, le commentaire
+ <em>fuzzy</em> signifie que la phrase a d&eacute;j&agrave;
+ &eacute;t&eacute; traduite mais qu'elle a depuis
+ &eacute;t&eacute; chang&eacute;e dans le source du programme,
+ ou bien que <em>gettext</em> a effectu&eacute; lui-m&ecirc;me
+ uen traduction, en se basant sur une phrase similaire. Cela
+ implique donc que vous devez v&eacute;rifier la traduction.
+ Parfois, la phrase originale a chang&eacute; suite &agrave;
+ 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 &ecirc;tre valable et
+ n&eacute;cessitera alors une mise &agrave; jour. Une fois
+ cette mise &agrave; jour effectu&eacute;e, vous pouvez
+ supprimer
+ le commentaire <code>"#, fuzzy"</code>, et la traduction sera
+ alors &agrave; nouveau prise en compte par <code>calcurse</code>.<br>
+ <br>
+ <li><em>Lignes au format C et s&eacute;quences sp&eacute;ciales</em><br>
+ Certaines phrases ont le commentaire suivant: <code>"#,
+ c-format"</code>. Cela signifie que des parties du texte
+ &agrave; traduire ont une signification particuli&egrave;re
+ pour le programme, et qu'il ne faut pas les modifier. Par
+ exemple, les s&eacute;quences contenant des <em>%</em>, comme
+ <code>"%s"</code>. Cela signifie que <code>calcurse</code>
+ remplacera ces s&eacute;quences par d'autres expressions. Il
+ est donc important de ne pas les modifier. Il existe
+ &eacute;galement des s&eacute;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&egrave;re
+ s&eacute;quence repr&eacute;sente une fin de ligne, et la
+ deuxi&egrave;me une tabulation.<br>
+ <br>
+ <li><em>D&eacute;coupage des traductions</em><br>
+ Si certaines lignes sont trop longues, il est possible de
+ d&eacute;couper les phrases comme dans l'exemple ci-apr&egrave;s:
+ <pre>
+ msgid ""
+ "une ligne très longue"
+ "une autre ligne"
+ </pre>
+ <li><em>En-t&ecirc;te des fichiers po</em><br>
+ Au tout d&eacute;but du fichier <em>po</em>, la
+ premi&egrave;re phrase forme un en-t&ecirc;te o&ugrave;
+ diff&eacute;rentes informations doivent &ecirc;tre
+ renseign&eacute;es. La plus importante est le jeu de
+ caract&egrave;s utilis&eacute;. Cette information devrait
+ ressembler &agrave;
+ <pre>
+ "Content-Type: text/plain; charset=utf-8\n"
+ </pre>
+ Il est &eacute;galement n&eacute;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&egrave;re personne ayant
+ retouch&eacute; le fichier. De cette mani&egrave;re, il est
+ plus simple de coordonner les efforts de traduction. Il est
+ possible de rajouter son adresse de courrier
+ &eacute;lectronique, par exemple:
+ <pre>
+ "Last-Translator: Frederic Culot <frederic@culot.org>\n"
+ </pre>
+ <li><em>Commentaires</em><br>
+ Ajouter des commentaires (lignes commen&ccedil;ant par '#')
+ peut &ecirc;tre un bon moyen de signaler des probl&egrave;mes ou
+ difficult&eacute;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&eacute;pend donc de la taille
+ du terminal utilis&eacute; (plus particuli&egrave;rement du
+ nombre de colonnes). Il est important de garder ceci en
+ m&eacute;moire au moment de la traduction. Souvent, la phrase
+ &agrave; traduire doit tenir dans une seule ligne (soit en
+ g&eacute;n&eacute;ral 80 caract&egrave;res). Il faut en tenir
+ compte, et essayer de voir o&ugrave; la phrase sera
+ plac&eacute;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 &ecirc;tre modifi&eacute;s avec un &eacute;diteur
+ de texte standard. Mais il est &eacute;galement possible
+ d'utiliser des outils sp&eacute;cialis&eacute;s pour cette
+ t&acirc;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'&eacute;sp&egrave;re que vous prendrez plaisir &agrave;
+ contribuer &agrave; l'internationalisation du monde des
+ logiciels libres. :) Si vous avez d'autres questions
+ concernant ce processus, n'h&eacute;sitez pas &agrave; me
+ contacter &agrave; 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 &ecirc;tre utiles.
+
+
+<a name="links_homepage"></a><h2>Site internet de <code>calcurse</code></h2>
+<p>
+ La page web de <code>calcurse</code> est &agrave; 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 &ecirc;tes interess&eacute; par ce projet et que vous souhaitez
+ &ecirc;tre pr&eacute;venu lorsqu'une nouvelle version est diffus&eacute;e, vous
+ pouvez souscrire &agrave; la liste de diffusion de <code>calcurse</code>.
+ De cette mani&egrave;re, vous recevrez un m&eacute;l d&egrave;s qu'une nouvelle
+ version est disponible.<br>
+ Pour souscrire &agrave; cette liste, envoyez un message &agrave; l'adresse
+ <code>calcurse-announce@culot.org</code> avec "subscribe" dans
+ le sujet du m&eacute;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&egrave;re d'am&eacute;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&eacute; celui de
+ <code>calcurse</code>
+ <li>Michael Schulz pour la traduction allemande du manuel de <code>calcurse</code>
+ <li>les personnes qui &eacute;crivent des logiciels que j'appr&eacute;cie et qui
+ m'ont inspir&eacute; lors de la conception de ce projet, en particulier :
+ <ul>
+ <li><code>vim</code> pour les touches de d&eacute;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&egrave;s grand merci &agrave; tous les utilisateurs de
+ <code>calcurse</code> qui m'ont fait parvenir leur commentaires.
+
+<hr>
+<small><em>
+Copyright (c) 2004-2006 Fr&eacute;d&eacute;ric Culot<br>
+Calcurse version 1.4 - Derni&egrave;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 */