aboutsummaryrefslogblamecommitdiffstats
path: root/src/calcurse.c
blob: d004ae817c40f3a72719e4b13953691490c18473 (plain) (tree)
1
2
3
4
5
                                                                          


                                  
                                         
























                                                                       
                   
                   



                 

                   
                 
                

                 
                   

 






                                                                           

                           
 
                    
                             
                                       
                            
                             

                             
                                
                                
                              

                                 

                                                                  








                                                               



                                             



                                                                
                                                        
                             
                                      

                                                               
                                                                  



                                                                             
                                    
                           
                          



                                               

                                         

                              






                                                  
                                      









                                                                   
                
                                 

                                         
 
                         
                    
                          
                          
                            





                                                                
                                             

                                            
                        
                      
                      
                           
                                           
                                        
                
                      
                                                                  
                                                             
                            
                      
                                     


                        

                                 
                                        
 
                             
 









                                          
                                                  
                                            
                                                                
                                               
                                 

                                                           
                                      
                                 

                                                             


                                      
                         
                                          

                                                            
                                               
                                 

                                                                            
                                    
                                                                    
                                      
                                 

                                                                                
                                                           
                                    
                                                                      


                                      


                              

                         
                                                        

                              

                                                   
                                           

                                                    





                                                   
                                                                          
                                                 
                                                                              
                                                                            
                                                  



                                                        
                                           
                                     
                                                                  


                                             


                                                                      
                                                                 
                                                                   


                                                                            



                                              
                                                        


                                              
                                                                     
                                              

                                         
                                                            
                                              
                                 
                                             
                                              
                                                  
                                                   

                                             
                                      

                              
                                                                         
                                     



                                                                         


                                                               

                              

                                                 
                                               
                                 
                                             
                                                  
                                      
                                 


                                                                       


                                      
                         

                              

                                                           
                                                                      
                                                
                                                                         
                                                 
                                          

                              

                                                    
                                                                      
                                                                       
                                                       
                                                                         
                                                   


                                          

                         
                                                                      
                                                    
                                                  
                              

                         
                                                                      
                                                       

                                                  


                         
                                                                      


                                                                    
                                                                           
                                                                     
                                                            
                         
                              
 



                                                                              
                                                           







                                                                         
                                                          



                                                                         
                                                        

                                      



                                                   
                                            

                              

                                                     
                                                                     

                              


                                                 
                               
                                                                     

                                                   
                                                     





                                                
                               
                                                                     

                                                   
                                                    





                                              
                               
                                                                     

                                                   
                                                  
                                
                                                             


                                                                              
                                                                    



                                                                      






                                                
                               
                                                                     

                                                   
                                                    
                                
                                                             
                                                                       
                                                        

                                                                               
                                                        
                                 
                                                             

                                                                
                                                                              
                                                                      



                                 
                                                      
                           
                                           
                                                   

                                                
                                                                      
                                                        
                                                
                                                                    
                                      
                                                           

                                              
                              
                                                            
                              



                                          
                 
 
                                 

                                                                              



                                                           
                                                             
                                                                              
                                                           

                         

                                      
         
 
/*	$calcurse: calcurse.c,v 1.60 2008/01/13 12:40:45 culot Exp $	*/

/*
 * Calcurse - text-based organizer
 * Copyright (c) 2004-2008 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 <stdlib.h>
#include <signal.h>

#include "i18n.h"
#include "io.h"
#include "help.h"
#include "custom.h"
#include "utils.h"
#include "sigs.h"
#include "day.h"
#include "todo.h"
#include "args.h"
#include "notify.h"


/*
 * 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)
{
	conf_t conf;
	day_items_nb_t inday;
	int ch, background, foreground;
	int non_interactive;
	int no_data_file = 1;
	int sav_hilt_app = 0;
	int sav_hilt_tod = 0;
	struct sigaction sigact;
	bool do_storage = false;
	bool do_update = true;
	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 */
		
	/* Thread-safe data structure init */
	apoint_llist_init();
	recur_apoint_llist_init();

	/* 
	 * Begin by parsing and handling command line arguments.
	 * The data path is also initialized here.
	 */
	non_interactive = parse_args(argc, argv, &conf);
	if (non_interactive) 
		return (EXIT_SUCCESS);

	/* Begin of interactive mode with ncurses interface. */
	sigs_init(&sigact);		/* signal handling init */
	initscr();			/* start the curses mode */
	cbreak();			/* control chars generate a signal */
	noecho();			/* controls echoing of typed chars */
	curs_set(0);			/* make cursor invisible */
        calendar_set_current_date();
	notify_init_vars();
	wins_get_config();
	
        /* Check if terminal supports color. */
	if (has_colors()) {
                colorize = true;
		background = COLOR_BLACK;
		foreground = COLOR_WHITE;
		start_color();

#ifdef NCURSES_VERSION
		if (use_default_colors() != ERR) {
			background = -1;
			foreground = -1;
		}
#endif /* NCURSES_VERSION */

		/* Color assignment */
		init_pair(COLR_RED, COLOR_RED, background);
		init_pair(COLR_GREEN, COLOR_GREEN, background);
		init_pair(COLR_YELLOW, COLOR_YELLOW, background);
		init_pair(COLR_BLUE, COLOR_BLUE, background);
		init_pair(COLR_MAGENTA, COLOR_MAGENTA, background);
		init_pair(COLR_CYAN, COLOR_CYAN, background);
		init_pair(COLR_DEFAULT, foreground, background);
		init_pair(COLR_HIGH, COLOR_BLACK, COLOR_GREEN);
		init_pair(COLR_CUSTOM, COLOR_RED, background);

	} else {
                colorize = false;
		background = COLOR_BLACK;
	}

	vars_init(&conf);
	wins_init();
	wins_slctd_init();
	notify_init_bar();
	reset_status_page();

	/* 
	 * 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 = io_check_data_files();
	custom_load_conf(&conf, background);
	erase_status_bar();
	io_load_todo();	
	io_load_app();
        wins_reinit();
	if (notify_bar()) {
		notify_start_main_thread();
		notify_check_next_app();
	}	
	wins_update();
        io_startup_screen(conf.skip_system_dialogs, no_data_file);
	inday = *day_process_storage(0, day_changed, &inday);
	wins_slctd_set(CAL);
	wins_update();
	calendar_start_date_thread();

	/* User input */
	for (;;) {

		do_update = true;
		ch = wgetch(win[STA].p);

		switch (ch) {

		case ERR:
			do_update = false;
			break;

		case CTRL('R'):
		case KEY_RESIZE:
			do_update = false;
			wins_reset();
			break;

		case 9:	/* The TAB key was hit. */
			reset_status_page();
			/* Save previously highlighted event. */
			switch (wins_slctd()) {
			case TOD:
				sav_hilt_tod = todo_hilt();
				todo_hilt_set(0);
				break;
			case APP:
				sav_hilt_app = apoint_hilt();
				apoint_hilt_set(0);
				break;
			default:
				break;
			}
			wins_slctd_next();

			/* Select the event to highlight. */
			switch (wins_slctd()) {
			case TOD:
				if ((sav_hilt_tod == 0) && (todo_nb() != 0))
					todo_hilt_set(1);
				else
					todo_hilt_set(sav_hilt_tod);
				break;
			case APP:
				if ((sav_hilt_app == 0) && 
				    ((inday.nb_events + inday.nb_apoints) != 0))
					apoint_hilt_set(1);
				else
					apoint_hilt_set(sav_hilt_app);
				break;
			default:
				break;
			}
			break;

		case 'O':
		case 'o':
			other_status_page(wins_slctd());
			break;

		case 'G':
		case 'g':	/* Goto function */
			erase_status_bar();
			calendar_set_current_date();
			calendar_change_day();
			do_storage = true;
			day_changed = true;
			break;

		case 'V':
		case 'v':	/* View function */
			if ((wins_slctd() == APP) && (apoint_hilt() != 0))
				day_popup_item();
			else if ((wins_slctd() == TOD) && (todo_hilt() != 0)) 
				item_in_popup(NULL, NULL, todo_saved_mesg(),
				    _("To do :"));
			break;

		case 'C':
		case 'c':	/* Configuration menu */
			erase_status_bar();
			config_bar();
			while ((ch = wgetch(win[STA].p)) != 'q') {
				switch (ch) {
				case 'C':
				case 'c':
                                        if (has_colors())
                                                custom_color_config();
					else {
                                                colorize = false;
						erase_status_bar();
                                                mvwprintw(win[STA].p, 0, 0, 
						    _(no_color_support));
                                                wgetch(win[STA].p);
                                        }
					break;
				case 'L':
				case 'l':
					layout_config();
					break;
				case 'G':
				case 'g':
					custom_general_config(&conf);
					break;
				case 'N':
				case 'n':
					notify_config_bar();
					break;
				}
                                wins_reset();
				wins_update();
				do_storage = true;
				erase_status_bar();
				config_bar();
			}
                        wins_update();
			break;

		case CTRL('A'):	/* Add an app, whatever panel selected */
			apoint_add();
			do_storage = true;
			break;

		case CTRL('T'):	/* Add a todo, whatever panel selected */
			todo_new_item();
			if (todo_hilt() == 0 && todo_nb() == 1)
				todo_hilt_increase();
			break;

		case 'A':
		case 'a':	/* Add an item */
			switch (wins_slctd()) {
			case APP:
				apoint_add();
				do_storage = true;
				break;
			case TOD:
				todo_new_item();
				if (todo_hilt() == 0 && todo_nb() == 1)
					todo_hilt_increase();
				break;
			default:
				break;
			}
			break;

		case 'E':
		case 'e':	/* Edit an existing item */
			if (wins_slctd() == APP && apoint_hilt() != 0)
				day_edit_item();
			else if (wins_slctd() == TOD && todo_hilt() != 0)
				todo_edit_item();
			do_storage = true;
			break;

		case 'D':
		case 'd':	/* Delete an item */
			if (wins_slctd() == APP && apoint_hilt() != 0)
				apoint_delete(&conf, &inday.nb_events, 
				    &inday.nb_apoints);
			else if (wins_slctd() == TOD && todo_hilt() != 0)
				todo_delete(&conf);
			do_storage = true;
			break;

		case 'R':
		case 'r':
			if (wins_slctd() == APP && apoint_hilt() != 0)
				recur_repeat_item();
				do_storage = true;
			break;

		case '!':
			if (wins_slctd() == APP && apoint_hilt() != 0)
				apoint_switch_notify();
				do_storage = true;
			break;
	
		case '+':
		case '-':
			if (wins_slctd() == TOD && todo_hilt() != 0) {
				todo_chg_priority(ch);
				if (todo_hilt_pos() < 0)
					todo_set_first(todo_hilt());
				else if (todo_hilt_pos() >= win[TOD].h - 4)
					todo_set_first(todo_hilt() - 
					    win[TOD].h + 5);
			}
			break;

		case 'N':
		case 'n':	
			/* Attach a note to an item, create it if necessary */
			if (wins_slctd() == APP && apoint_hilt() != 0)
				day_edit_note(conf.editor);
			else if (wins_slctd() == TOD && todo_hilt() != 0)
				todo_edit_note(conf.editor);
			do_storage = true;
			break;

		case '>':	
			/* View a note previously attached to an item */
			if (wins_slctd() == APP && apoint_hilt() != 0)
				day_view_note(conf.pager);
			else if (wins_slctd() == TOD && todo_hilt() != 0)
				todo_view_note(conf.pager);
			break;

		case '?':	/* Online help system */
			status_bar();
			help_screen();
			break;

		case 'S':
		case 's':	/* Save function */
			io_save_cal(&conf); 
			break;

		case 'X':
		case 'x':	/* Export function */
			io_export_data(IO_EXPORT_INTERACTIVE, &conf);
			break;

		case (261):	/* right arrow */
		case ('L'):
		case ('l'):
		case CTRL('L'):
			if (wins_slctd() == CAL || ch == CTRL('L')) {
				do_storage = true;
				day_changed = true;
				calendar_move(RIGHT);
			}
			break;

		case (260):	/* left arrow */
		case ('H'):
		case ('h'):
		case CTRL('H'):
			if (wins_slctd() == CAL || ch == CTRL('H')) {
				do_storage = true;
				day_changed = true;
				calendar_move(LEFT);
			}
			break;

		case (259):	/* up arrow */
		case ('K'):
		case ('k'):
		case CTRL('K'):
			if (wins_slctd() == CAL || ch == CTRL('K')) {
				do_storage = true;
				day_changed = true;
				calendar_move(UP);
			} else {
				if ((wins_slctd() == APP) && 
				    (apoint_hilt() > 1)) {
					apoint_hilt_decrease();
					apoint_scroll_pad_up(inday.nb_events);
				} else if ((wins_slctd() == TOD) && 
				    (todo_hilt() > 1)) {
					todo_hilt_decrease();
					if (todo_hilt_pos() < 0)
						todo_first_decrease();
				}
			}
			break;

		case (258):	/* down arrow */
		case ('J'):
		case ('j'):
		case CTRL('J'):
			if (wins_slctd() == CAL || ch == CTRL('J')) {
				do_storage = true;
				day_changed = true;
				calendar_move(DOWN);
			} else {
				if ((wins_slctd() == APP) && 
				    (apoint_hilt() < inday.nb_events + 
				    inday.nb_apoints)) {
					apoint_hilt_increase();
					apoint_scroll_pad_down(inday.nb_events,
					    win[APP].h);
				}
				if ((wins_slctd() == TOD) && 
				    (todo_hilt() < todo_nb())) {
					todo_hilt_increase();
					if (todo_hilt_pos() == win[TOD].h - 4)
						todo_first_increase();
				}
			}
			break;

		case ('Q'):	/* Quit calcurse :( */
		case ('q'):
			if (conf.auto_save)
				io_save_cal(&conf);

			if (conf.confirm_quit) {
				status_mesg(_(quit_message), choices);
				ch = wgetch(win[STA].p);
				if ( ch == 'y' )
					exit_calcurse(EXIT_SUCCESS);
				else {
					erase_status_bar();
					break;
				}
			} else
				exit_calcurse(EXIT_SUCCESS);
			break;

		default:
			do_update = false;
			break;
		}

		if (do_storage) {
			inday = *day_process_storage(calendar_get_slctd_day(),
			    day_changed, &inday);
			do_storage = !do_storage;
			if (day_changed) {
				sav_hilt_app = 0;
				day_changed = !day_changed;
				if ((wins_slctd() == APP) && 
				    (inday.nb_events + inday.nb_apoints != 0))
					apoint_hilt_set(1);
			}
		}
		if (do_update)
			wins_update();
	}
}