Esempio n. 1
0
void tasklist_check_curs_pos() /* {{{ */
{
	/* check if the cursor is in a valid position */
	const int onscreentasks = getmaxy(tasklist);

	/* log starting cursor position */
	tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "cursor_check(init) - selline:%d offset:%d taskcount:%d perscreen:%d", selline, pageoffset, taskcount, rows-3);

	/* check 0<=selline<taskcount */
	if (selline<0)
		selline = 0;
	else if (selline>=taskcount)
		selline = taskcount-1;

	/* check if page offset is necessary */
	if (taskcount<=onscreentasks)
		pageoffset = 0;
	/* offset up if necessary */
	else if (selline<pageoffset)
		pageoffset = selline;
	/* offset down if necessary */
	else if (taskcount>onscreentasks && pageoffset+onscreentasks-1<selline)
		pageoffset = selline-onscreentasks+1;
	/* dont allow blank lines if there is an offset */
	else if (taskcount>onscreentasks && taskcount-pageoffset<onscreentasks)
		pageoffset = taskcount-onscreentasks;

	/* log cursor position */
	tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "cursor_check - selline:%d offset:%d taskcount:%d perscreen:%d", selline, pageoffset, taskcount, rows-3);
} /* }}} */
Esempio n. 2
0
File: tasknc.c Progetto: skn/tasknc
void ncurses_init() /* {{{ */
{
	/* initialize ncurses */
	int ret;

	/* register signals */
	signal(SIGINT, ncurses_end);
	signal(SIGKILL, ncurses_end);
	signal(SIGSEGV, ncurses_end);

	/* initialize screen */
	tnc_fprintf(stdout, LOG_DEBUG, "starting ncurses...");
	if ((stdscr = initscr()) == NULL )
	{
	    fprintf(stderr, "Error initialising ncurses.\n");
	    exit(EXIT_FAILURE);
	}

	/* start colors */
	ret = init_colors();
	if (ret)
	{
		fprintf(stderr, "Error initializing colors.\n");
		tnc_fprintf(logfp, LOG_ERROR, "error initializing colors (%d)", ret);
	}
} /* }}} */
Esempio n. 3
0
void run_command_source_cmd(const char *cmdstr) /* {{{ */
{
	/* run commands generated by a command */
	FILE *cmd = popen(cmdstr, "r");

	tnc_fprintf(logfp, LOG_DEBUG, "source: command \"%s\"", cmdstr);

	/* check for a valid fd */
	if (cmdstr == NULL)
	{
		tnc_fprintf(logfp, LOG_ERROR, "source: file \"%s\" could not be opened", cmdstr);
		statusbar_message(cfg.statusbar_timeout, "source: command \"%s\" could not be opened", cmdstr);
		return;
	}


	/* exit window */
	def_prog_mode();
	endwin();

	/* read command file */
	source_fp(cmd);

	/* force redraw */
	reset_prog_mode();
	redraw = true;
	
/* close config file */
	pclose(cmd);
	tnc_fprintf(logfp, LOG_DEBUG, "source complete: \"%s\"", cmdstr);
	statusbar_message(cfg.statusbar_timeout, "source complete: \"%s\"", cmdstr);
} /* }}} */
Esempio n. 4
0
File: tasknc.c Progetto: irl/tasknc
void ncurses_end(int sig) /* {{{ */
{
	/* terminate ncurses
	 * sig - the signal which is terminating the program
	 */
	bool print_check_log = true;
	char *logpath;

	delwin(header);
	delwin(tasklist);
	delwin(statusbar);
	delwin(stdscr);
	endwin();

	switch (sig)
	{
		case SIGINT:
			tnc_fprintf(stdout, LOG_DEFAULT, "aborted");
			tnc_fprintf(logfp, LOG_DEBUG, "received SIGINT, exiting");
			break;
		case SIGSEGV:
			tnc_fprintf(logfp, LOG_ERROR, "SEGFAULT");
			tnc_fprintf(logfp, LOG_ERROR, "segmentation fault, exiting");
			break;
		case SIGKILL:
			tnc_fprintf(stdout, LOG_ERROR, "killed");
			tnc_fprintf(logfp, LOG_ERROR, "received SIGKILL, exiting");
			break;
		case -1:
			tnc_fprintf(stdout, LOG_ERROR, "an error has occurred, exiting");
			break;
		default:
			tnc_fprintf(stdout, LOG_DEFAULT, "done");
			tnc_fprintf(logfp, LOG_DEBUG, "exiting with code %d", sig);
			print_check_log = false;
			break;
	}

	/* tell user to check logs */
	if (print_check_log)
	{
		asprintf(&logpath, LOGFILE, getenv("USER"));
		tnc_fprintf(stdout, LOG_ERROR, "tasknc ended abnormally. please check '%s' for details", logpath);
		free(logpath);
		fflush(stdout);
	}

	/* free memory */
	cleanup();

	exit(0);
} /* }}} */
Esempio n. 5
0
void run_command_color(char *args) /* {{{ */
{
	/**
	 * create/modify a color rule
	 * syntax: object foreground background [rule]
	 */
	char *object = NULL, *fg = NULL, *bg = NULL, *rule = NULL;
	color_object obj;
	int ret = 0, fgc, bgc;

	if (args != NULL)
		ret = sscanf(args, "%ms %m[a-z0-9-] %m[a-z0-9-] %m[^\n]", &object, &fg, &bg, &rule);
	if (ret < 3)
	{
		statusbar_message(cfg.statusbar_timeout, "syntax: color <object> <foreground> <background> <rule>");
		tnc_fprintf(logfp, LOG_ERROR, "syntax: color <object> <foreground> <background> <rule>  [%d](%s)", ret, args);
		goto cleanup;
	}

	/* parse object */
	obj = parse_object(object);
	if (obj == OBJECT_NONE)
	{
		statusbar_message(cfg.statusbar_timeout, "color: invalid object \"%s\"", object);
		tnc_fprintf(logfp, LOG_ERROR, "color: invalid object \"%s\"", object);
		goto cleanup;
	}

	/* parse colors */
	fgc = parse_color(fg);
	bgc = parse_color(bg);
	if (bgc < -2 || fgc < -2)
	{
		statusbar_message(cfg.statusbar_timeout, "color: invalid colors \"%s\" \"%s\"", fg, bg);
		tnc_fprintf(logfp, LOG_ERROR, "color: invalid colors %d:\"%s\" %d:\"%s\"", fgc, fg, bgc, bg);
		goto cleanup;
	}

	/* create color rule */
	if (add_color_rule(obj, rule, fgc, bgc)>=0)
		statusbar_message(cfg.statusbar_timeout, "applied color rule");
	else
		statusbar_message(cfg.statusbar_timeout, "applying color rule failed");
	goto cleanup;

cleanup:
	check_free(object);
	check_free(fg);
	check_free(bg);
	check_free(rule);
} /* }}} */
Esempio n. 6
0
File: color.c Progetto: skn/tasknc
short add_color_pair(short askpair, short fg, short bg) /* {{{ */
{
	/* initialize a color pair and return its pair number */
	short pair = 1;

	/* pick a color number if none is specified */
	if (askpair<=0)
	{
		while (pair<COLOR_PAIRS && pairs_used[pair])
			pair++;
		if (pair == COLOR_PAIRS)
			return -1;
	}

	/* check if pair requested is being used */
	else
	{
		if (pairs_used[askpair])
			return -1;
		pair = askpair;
	}

	/* initialize pair */
	if (init_pair(pair, fg, bg) == ERR)
		return -1;

	/* mark pair as used and exit */
	pairs_used[pair] = true;
	tnc_fprintf(logfp, LOG_DEBUG, "assigned color pair %hd to (%hd, %hd)", pair, fg, bg);
	return pair;
} /* }}} */
Esempio n. 7
0
void run_command_source(const char *filepath) /* {{{ */
{
	/* run the commands contained in a config file */
	FILE *config = NULL;

	config = fopen(filepath, "r");
	tnc_fprintf(logfp, LOG_DEBUG, "source: file \"%s\"", filepath);

	/* check for a valid fd */
	if (config == NULL)
	{
		tnc_fprintf(logfp, LOG_ERROR, "source: file \"%s\" could not be opened", filepath);
		statusbar_message(cfg.statusbar_timeout, "source: file \"%s\" could not be opened", filepath);
		return;
	}

	/* read config file */
	source_fp(config);

	/* close config file */
	fclose(config);
	tnc_fprintf(logfp, LOG_DEBUG, "source complete: \"%s\"", filepath);
	statusbar_message(cfg.statusbar_timeout, "source complete: \"%s\"", filepath);
} /* }}} */
Esempio n. 8
0
File: tasknc.c Progetto: irl/tasknc
int umvaddstr(WINDOW *win, const int y, const int x, const char *format, ...) /* {{{ */
{
	/* convert a string to a wchar string and mvaddwstr
	 * win    - the window to print the string in
	 * y      - the y coordinates to print the string at
	 * x      - the x coordinates to print the string at
	 * format - the format string to print
	 * additional args are accepted to use with the format string
	 * (similar to printf)
	 * return is the return of mvwaddnwstr
	 */
	int len, r;
	wchar_t *wstr;
	char *str;
	va_list args;

	/* build str */
	va_start(args, format);
	const int slen = sizeof(wchar_t)*(cols-x+1)/sizeof(char);
	str = calloc(slen, sizeof(char));
	vsnprintf(str, slen-1, format, args);
	va_end(args);

	/* allocate wchar_t string */
	len = strlen(str)+1;
	wstr = calloc(len, sizeof(wchar_t));

	/* check for valid allocation */
	if (wstr==NULL)
	{
		tnc_fprintf(logfp, LOG_ERROR, "critical: umvaddstr failed to malloc");
		return -1;
	}

	/* perform conversion and write to screen */
	mbstowcs(wstr, str, len);
	len = wcslen(wstr);
	if (len>cols-x)
		len = cols-x;
	r = mvwaddnwstr(win, y, x, wstr, len);

	/* free memory allocated */
	free(wstr);
	free(str);

	return r;
} /* }}} */
Esempio n. 9
0
void run_command_show(const char *arg) /* {{{ */
{
	/**
	 * display a variable in the statusbar
	 * syntax: variable
	 */
	var *this_var;
	char *message = NULL;
	int ret = 0;

	/* parse arg */
	if (arg != NULL)
		ret = sscanf(arg, "%m[^\n]", &message);
	if (ret != 1)
	{
		statusbar_message(cfg.statusbar_timeout, "syntax: show <variable>");
		tnc_fprintf(logfp, LOG_ERROR, "syntax: show <variable> [%d](%s)", ret, arg);
		goto cleanup;
	}

	/* check for a variable */
	if (arg == NULL)
	{
		statusbar_message(cfg.statusbar_timeout, "no variable specified!");
		goto cleanup;
	}

	/* find the variable */
	this_var = (var *)find_var(arg);
	if (this_var==NULL)
	{
		statusbar_message(cfg.statusbar_timeout, "variable not found: %s", arg);
		goto cleanup;
	}

	/* acquire the value string and print it */
	message = var_value_message(this_var, 1);
	statusbar_message(cfg.statusbar_timeout, message);

cleanup:
	free(message);
	return;
} /* }}} */
Esempio n. 10
0
void run_command_unbind(char *argstr) /* {{{ */
{
	/**
	 * unbind a key
	 * syntax - mode key
	 */
	char *modestr = NULL, *keystr = NULL, *keyname = NULL;
	prog_mode mode;
	int ret = 0;

	/* parse args */
	if (argstr != NULL)
		ret = sscanf(argstr, "%ms %m[^\n]", &modestr, &keystr);
	if (ret != 2)
	{
		statusbar_message(cfg.statusbar_timeout, "syntax: unbind <mode> <key>");
		tnc_fprintf(logfp, LOG_ERROR, "syntax: unbind <mode> <key> [%d](%s)", ret, argstr);
		goto cleanup;
	}

	/* parse mode */
	if (str_eq(modestr, "pager"))
		mode = MODE_PAGER;
	else if (str_eq(modestr, "tasklist"))
		mode = MODE_TASKLIST;
	else
		mode = MODE_ANY;

	int key = parse_key(keystr);

	remove_keybinds(key, mode);
	keyname = name_key(key);
	statusbar_message(cfg.statusbar_timeout, "key unbound: %s (%d)", keyname, key);
	goto cleanup;

cleanup:
	free(keyname);
	free(modestr);
	free(keystr);
	return;
} /* }}} */
Esempio n. 11
0
void key_tasklist_sort(const char* arg) { /* {{{ */
    /* handle a keyboard direction to sort
     * arg - the mode to sort by (pass NULL to prompt user)
     *       see the manual page for how sort strings are parsed
     */
    char*        uuid = NULL;

    /* store selected task */
    struct task* cur = get_task_by_position(selline);

    if (cur != NULL) {
        uuid = strdup(cur->uuid);
    }

    tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "sort: initial task uuid=%s", uuid);

    check_free(cfg.sortmode);

    if (arg == NULL) {
        /* store sort string  */
        cfg.sortmode = calloc(cols, sizeof(char));
        statusbar_getstr(&(cfg.sortmode), "sort by: ");
        sb_timeout = time(NULL) + 3;
    } else {
        cfg.sortmode = strdup(arg);
    }

    /* run sort */
    sort_wrapper(head);

    /* follow original task */
    if (cfg.follow_task) {
        set_position_by_uuid(uuid);
        tasklist_check_curs_pos();
    }

    check_free(uuid);

    /* force redraw */
    redraw = true;
} /* }}} */
Esempio n. 12
0
File: tasknc.c Progetto: irl/tasknc
void find_next_search_result(task *head, task *pos) /* {{{ */
{
	/* find the next search result in the list of tasks
	 * head - the first task in the task list
	 * pos  - the position in the task list to start searching from
	 */
	task *cur;

	cur = pos;
	while (1)
	{
		/* move to next item */
		cur = cur->next;

		/* move to head if end of list is reached */
		if (cur == NULL)
		{
			cur = head;
			selline = 0;
			tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "search wrapped");
			statusbar_message(cfg.statusbar_timeout, "search wrapped to top");
		}

		else
			selline++;

		/* check for match */
		if (task_match(cur, searchstring))
			return;

		/* stop if full loop was made */
		if (cur==pos)
			break;
	}

	statusbar_message(cfg.statusbar_timeout, "no matches: %s", searchstring);

	return;
} /* }}} */
Esempio n. 13
0
File: tasknc.c Progetto: skn/tasknc
void handle_resize() /* {{{ */
{
	/* handle a change in screen size */
	int pagerheight;

	/* make sure rows and cols are set correctly */
	rows = getmaxy(stdscr);
	cols = getmaxx(stdscr);

	/* resize windows */
	wresize(header, 1, cols);
	wresize(tasklist, rows-2, cols);
	wresize(statusbar, 1, cols);

	/* move to proper positions */
	mvwin(header, 0, 0);
	mvwin(tasklist, 1, 0);
	mvwin(statusbar, rows-1, 0);

	/* handle pager */
	if (pager != NULL)
	{
		pagerheight = getmaxy(pager);
		if (pagerheight > rows-2)
			pagerheight = rows-2;
		wresize(pager, pagerheight, cols);
		mvwin(pager, rows-pagerheight-1, 0);
	}

	/* redraw windows */
	tasklist_print_task_list();
	print_header();

	/* message about resize */
	tnc_fprintf(logfp, LOG_DEBUG, "window resized to y=%d x=%d", rows, cols);
	statusbar_message(cfg.statusbar_timeout, "window resized to y=%d x=%d", rows, cols);
} /* }}} */
Esempio n. 14
0
void key_tasklist_scroll(const int direction) /* {{{ */
{
	/* handle a keyboard direction to scroll
	 * direction - the direction to scroll in
	 *             u = up one
	 *             d = down one
	 *             h = to first element in list
	 *             e = to last element in list
	 */
	const char oldsel = selline;
	const char oldoffset = pageoffset;

	switch (direction)
	{
		case 'u':
			/* scroll one up */
			if (selline>0)
			{
				selline--;
				if (selline<pageoffset)
					pageoffset--;
			}
			else
				statusbar_message(cfg.statusbar_timeout, "already at top");
			break;
		case 'd':
			/* scroll one down */
			if (selline<taskcount-1)
			{
				selline++;
				if (selline>=pageoffset+rows-2)
					pageoffset++;
			}
			else
				statusbar_message(cfg.statusbar_timeout, "already at bottom");
			break;
		case 'h':
			/* go to first entry */
			pageoffset = 0;
			selline = 0;
			break;
		case 'e':
			/* go to last entry */
			if (taskcount>rows-2)
				pageoffset = taskcount-rows+2;
			selline = taskcount-1;
			break;
		default:
			statusbar_message(cfg.statusbar_timeout, "invalid scroll direction");
			break;
	}
	if (pageoffset!=oldoffset)
		redraw = true;
	else
	{
		if (oldsel-selline == 1)
			tasklist_print_task(selline, NULL, 2);
		else if (selline-oldsel == 1)
			tasklist_print_task(oldsel, NULL, 2);
		else
		{
			tasklist_print_task(oldsel, NULL, 1);
			tasklist_print_task(selline, NULL, 1);
		}
	}
	print_header();
	tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "selline:%d offset:%d tasks:%d", selline, pageoffset, taskcount);
} /* }}} */
Esempio n. 15
0
File: tasknc.c Progetto: skn/tasknc
void configure(void) /* {{{ */
{
	/* parse config file to get runtime options */
	FILE *cmd;
	char *filepath, *xdg_config_home, *home;
	int ret = 0;

	/* set default settings */
	cfg.nc_timeout = NCURSES_WAIT;                          /* time getch will wait */
	cfg.statusbar_timeout = STATUSBAR_TIMEOUT_DEFAULT;      /* default time before resetting statusbar */
	cfg.sortmode = strdup("drpu");                          /* determine sort order */
	cfg.follow_task = true;                                 /* follow task after it is moved */
	cfg.history_max = 50;

	/* set default formats */
	cfg.formats.title = strdup(" $program_name ($selected_line/$task_count) $> $date");
	cfg.formats.task = strdup(" $project $description $> ?$due?$due?$-6priority?");
	cfg.formats.view = strdup(" task info");

	/* set initial filter */
	active_filter = strdup("status:pending");

	/* get task version */
	cmd = popen("task --version", "r");
	while (ret != 1)
		ret = fscanf(cmd, "%m[0-9.-] ", &(cfg.version));
	tnc_fprintf(logfp, LOG_DEBUG, "task version: %s", cfg.version);
	pclose(cmd);

	/* default keybinds */
	add_keybind(ERR,           NULL,                     NULL,            MODE_TASKLIST);
	add_keybind(ERR,           NULL,                     NULL,            MODE_PAGER);
	add_keybind(KEY_RESIZE,    handle_resize,            NULL,            MODE_ANY);
	add_keybind('k',           key_tasklist_scroll_up,   NULL,            MODE_TASKLIST);
	add_keybind('k',           key_pager_scroll_up,      NULL,            MODE_PAGER);
	add_keybind(KEY_UP,        key_tasklist_scroll_up,   NULL,            MODE_TASKLIST);
	add_keybind(KEY_UP,        key_pager_scroll_up,      NULL,            MODE_PAGER);
	add_keybind('j',           key_tasklist_scroll_down, NULL,            MODE_TASKLIST);
	add_keybind('j',           key_pager_scroll_down,    NULL,            MODE_PAGER);
	add_keybind(KEY_DOWN,      key_tasklist_scroll_down, NULL,            MODE_TASKLIST);
	add_keybind(KEY_DOWN,      key_pager_scroll_down,    NULL,            MODE_PAGER);
	add_keybind('g',           key_tasklist_scroll_home, NULL,            MODE_TASKLIST);
	add_keybind(KEY_HOME,      key_tasklist_scroll_home, NULL,            MODE_TASKLIST);
	add_keybind('g',           key_pager_scroll_home,    NULL,            MODE_PAGER);
	add_keybind(KEY_HOME,      key_pager_scroll_home,    NULL,            MODE_PAGER);
	add_keybind('G',           key_pager_scroll_end,     NULL,            MODE_PAGER);
	add_keybind(KEY_END,       key_pager_scroll_end,     NULL,            MODE_PAGER);
	add_keybind('G',           key_tasklist_scroll_end,  NULL,            MODE_TASKLIST);
	add_keybind(KEY_END,       key_tasklist_scroll_end,  NULL,            MODE_TASKLIST);
	add_keybind('e',           key_tasklist_edit,        NULL,            MODE_ANY);
	add_keybind('r',           key_tasklist_reload,      NULL,            MODE_TASKLIST);
	add_keybind('u',           key_tasklist_undo,        NULL,            MODE_TASKLIST);
	add_keybind('d',           key_tasklist_delete,      NULL,            MODE_ANY);
	add_keybind('c',           key_tasklist_complete,    NULL,            MODE_ANY);
	add_keybind('a',           key_tasklist_add,         NULL,            MODE_TASKLIST);
	add_keybind('v',           key_tasklist_view,        NULL,            MODE_TASKLIST);
	add_keybind(13,            key_tasklist_view,        NULL,            MODE_TASKLIST);
	add_keybind(KEY_ENTER,     key_tasklist_view,        NULL,            MODE_TASKLIST);
	add_keybind('s',           key_tasklist_sort,        NULL,            MODE_TASKLIST);
	add_keybind('/',           key_tasklist_search,      NULL,            MODE_TASKLIST);
	add_keybind('n',           key_tasklist_search_next, NULL,            MODE_TASKLIST);
	add_keybind('f',           key_tasklist_filter,      NULL,            MODE_TASKLIST);
	add_keybind('y',           key_tasklist_sync,        NULL,            MODE_TASKLIST);
	add_keybind('q',           key_done,                 NULL,            MODE_TASKLIST);
	add_keybind('q',           key_pager_close,          NULL,            MODE_PAGER);
	add_keybind(';',           key_command,              NULL,            MODE_TASKLIST);
	add_keybind(':',           key_command,              NULL,            MODE_ANY);
	add_keybind('h',           help_window,              NULL,            MODE_ANY);
	add_keybind(12,            force_redraw,             NULL,            MODE_TASKLIST);
	add_keybind(12,            force_redraw,             NULL,            MODE_PAGER);

	/* determine config path */
	xdg_config_home = getenv("XDG_CONFIG_HOME");
	if (xdg_config_home == NULL)
	{
		home = getenv("HOME");
		filepath = malloc((strlen(home)+25)*sizeof(char));
		sprintf(filepath, "%s/.config/tasknc/config", home);
	}
	else
	{
		filepath = malloc((strlen(xdg_config_home)+16)*sizeof(char));
		sprintf(filepath, "%s/tasknc/config", xdg_config_home);
	}
	run_command_source(filepath);
	free(filepath);

	/* compile format strings */
	compile_formats();
} /* }}} */
Esempio n. 16
0
File: tasknc.c Progetto: skn/tasknc
int main(int argc, char **argv) /* {{{ */
{
	/* declare variables */
	int c;
	bool debug = false;
	char *debugopts = NULL;

	/* open log */
	logfp = fopen(LOGFILE, "a");
	tnc_fprintf(logfp, LOG_DEBUG, "%s started", PROGNAME);

	/* set defaults */
	cfg.loglvl = LOGLVL_DEFAULT;
	setlocale(LC_ALL, "");

	/* handle arguments */
	static struct option long_options[] =
	{
		{"help",     no_argument,       0, 'h'},
		{"debug",    required_argument, 0, 'd'},
		{"version",  no_argument,       0, 'v'},
		{"loglevel", required_argument, 0, 'l'},
		{"filter",   required_argument, 0, 'f'},
		{0, 0, 0, 0}
	};
	int option_index = 0;
	while ((c = getopt_long(argc, argv, "l:hvd:f:", long_options, &option_index)) != -1)
	{
		switch (c)
		{
			case 'l':
				cfg.loglvl = (char) atoi(optarg);
				printf("loglevel: %d\n", (int)cfg.loglvl);
				break;
			case 'v':
				print_version();
				return 0;
				break;
			case 'd':
				debug = true;
				debugopts = strdup(optarg);
				break;
			case 'f':
				active_filter = strdup(optarg);
				break;
			case 'h':
			case '?':
				help();
				return 0;
				break;
			default:
				return 1;
		}
	}

	/* run ncurses */
	if (!debug)
	{
		tnc_fprintf(logfp, LOG_DEBUG, "running gui");
		ncurses_init();
		mvwprintw(stdscr, 0, 0, "%s %s", PROGNAME, PROGVERSION);
		mvwprintw(stdscr, 1, 0, "configuring...");
		wrefresh(stdscr);
		tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "configuring...");
		configure();
		tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "configuration complete");
		mvwprintw(stdscr, 1, 0, "loading tasks...");
		wrefresh(stdscr);
		tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "loading tasks...");
		head = get_tasks(NULL);
		tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "%d tasks loaded", taskcount);
		mvwhline(stdscr, 0, 0, ' ', COLS);
		mvwhline(stdscr, 1, 0, ' ', COLS);
		tasklist_window();
		ncurses_end(0);
	}

	/* debug mode */
	else
	{
		configure();
		head = get_tasks(NULL);
		test(debugopts);
		free(debugopts);
	}

	/* done */
	tnc_fprintf(logfp, LOG_DEBUG, "exiting");
	return 0;
} /* }}} */
Esempio n. 17
0
void run_command_set(char *args) /* {{{ */
{
	/**
	 * set a variable in the statusbar
	 * syntax: variable value
	 */
	var *this_var;
	char *message = NULL, *varname = NULL, *value = NULL;
	int ret = 0;

	/* parse args */
	if (args != NULL)
		ret = sscanf(args, "%ms %m[^\n]", &varname, &value);
	if (ret != 2)
	{
		statusbar_message(cfg.statusbar_timeout, "syntax: set <variable> <value>");
		tnc_fprintf(logfp, LOG_ERROR, "syntax: set <variable> <value> [%d](%s)", ret, args);
		goto cleanup;
	}

	/* find the variable */
	this_var = (var *)find_var(varname);
	if (this_var==NULL)
	{
		statusbar_message(cfg.statusbar_timeout, "variable not found: %s", varname);
		goto cleanup;
	}

	/* check for permission */
	if (this_var->perms == VAR_RO)
	{
		statusbar_message(cfg.statusbar_timeout, "variable is read only: %s", varname);
		goto cleanup;
	}
	if (this_var->perms == VAR_RC && tasklist != NULL)
	{
		statusbar_message(cfg.statusbar_timeout, "variable must be set in config: %s", varname);
		goto cleanup;
	}

	/* set the value */
	switch (this_var->type)
	{
		case VAR_INT:
			ret = sscanf(value, "%d", (int *)this_var->ptr);
			break;
		case VAR_CHAR:
			ret = sscanf(value, "%c", (char *)this_var->ptr);
			break;
		case VAR_STR:
			if (*(char **)(this_var->ptr)!=NULL)
				free(*(char **)(this_var->ptr));
			*(char **)(this_var->ptr) = calloc(strlen(value)+1, sizeof(char));
			ret = NULL!=strcpy(*(char **)(this_var->ptr), value);
			if (ret)
				strip_quotes((char **)this_var->ptr, 1);
			break;
		default:
			ret = 0;
			break;
	}
	if (ret<=0)
		tnc_fprintf(logfp, LOG_ERROR, "failed to parse value from command: set %s %s", varname, value);

	/* acquire the value string and print it */
	message = var_value_message(this_var, 1);
	statusbar_message(cfg.statusbar_timeout, message);

cleanup:
	free(message);
	free(varname);
	free(value);
	return;
} /* }}} */
Esempio n. 18
0
void handle_command(char *cmdstr) /* {{{ */
{
	/* accept a command string, determine what action to take, and execute */
	char *command, *args, *modestr, *pos;
	funcmap *fmap;
	prog_mode mode;
	int ret = 0;

	/* parse args */
	pos = strchr(cmdstr, '\n');
	if (pos != NULL)
		*pos = 0;
	tnc_fprintf(logfp, LOG_DEBUG, "command received: %s", cmdstr);
	if (cmdstr != NULL)
		ret = sscanf(cmdstr, "%ms %m[^\n]", &command, &args);
	if (ret < 1)
	{
		statusbar_message(cfg.statusbar_timeout, "failed to parse command");
		tnc_fprintf(logfp, LOG_ERROR, "failed to parse command: [%d] (%s)", ret, cmdstr);
		return;
	}

	/* determine mode */
	if (pager != NULL)
	{
		modestr = "pager";
		mode = MODE_PAGER;
	}
	else if (tasklist != NULL)
	{
		modestr = "tasklist";
		mode = MODE_TASKLIST;
	}
	else
	{
		modestr = "none";
		mode = MODE_ANY;
	}

	/* log command */
	tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "command: %s - %s (%s)", modestr, command, args);

	/* handle command & arguments */
	/* try for exposed command */
	fmap = find_function(command, mode);
	if (fmap!=NULL)
	{
		(fmap->function)(str_trim(args));
		goto cleanup;
	}
	/* version: print version string */
	if (str_eq(command, "version"))
		statusbar_message(cfg.statusbar_timeout, "%s %s by %s\n", PROGNAME, PROGVERSION, PROGAUTHOR);
	/* quit/exit: exit tasknc */
	else if (str_eq(command, "quit") || str_eq(command, "exit"))
		done = true;
	/* reload: force reload of task list */
	else if (str_eq(command, "reload"))
	{
		reload = true;
		statusbar_message(cfg.statusbar_timeout, "task list reloaded");
	}
	/* redraw: force redraw of screen */
	else if (str_eq(command, "redraw"))
		redraw = true;
	/* dump: write all displayed tasks to log file */
	else if (str_eq(command, "dump"))
	{
		task *this = head;
		int counter = 0;
		while (this!=NULL)
		{
			tnc_fprintf(logfp, 0, "uuid: %s", this->uuid);
			tnc_fprintf(logfp, 0, "description: %s", this->description);
			tnc_fprintf(logfp, 0, "project: %s", this->project);
			tnc_fprintf(logfp, 0, "tags: %s", this->tags);
			this = this->next;
			counter++;
		}
		tnc_fprintf(logfp, 0, "dumped %d tasks", counter);
	}
	/* scrdump: do an ncurses scr_dump */
	else if (str_eq(command, "scrdump"))
	{
		const char *dumppath = "nc_dump";
		scr_dump(dumppath);
		tnc_fprintf(logfp, LOG_DEBUG, "ncurses dumped to '%s'", dumppath);
	}
	else
	{
		statusbar_message(cfg.statusbar_timeout, "error: command %s not found", command);
		tnc_fprintf(logfp, LOG_ERROR, "error: command %s not found", command);
	}
	goto cleanup;

cleanup:
	/* clean up */
	free(command);
	free(args);
} /* }}} */
Esempio n. 19
0
File: color.c Progetto: skn/tasknc
bool eval_rules(char *rule, const task *tsk, const bool selected) /* {{{ */
{
	/* evaluate a rule set for a task */
	char *regex = NULL, pattern, *tmp;
	int ret, move;
	bool go = false, invert = false;

	/* success if rules are done */
	if (rule == NULL || *rule == 0)
		return true;

	/* skip non-patterns */
	if (*rule != '~')
		return eval_rules(rule+1, tsk, selected);

	/* regex match */
	ret = sscanf(rule, "~%c '%m[^\']'", &pattern, &regex);
	if (ret > 0 && pattern >= 'A' && pattern <= 'Z')
	{
		pattern += 32;
		invert = true;
	}
	if (ret == 1)
	{
		switch (pattern)
		{
			case 's':
				if (!XOR(invert, selected))
					return false;
				else
					return eval_rules(rule+2, tsk, selected);
				break;
			case 't':
				if (!XOR(invert, tsk->start>0))
					return false;
				else
					return eval_rules(rule+2, tsk, selected);
				break;
			default:
				break;
		}
	}
	if (ret == 2)
	{
		move = strlen(regex)+3;
		go = true;
		switch (pattern)
		{
			case 'p':
				if (!XOR(invert, match_string(tsk->project, regex)))
					return false;
				else
					tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "eval_rules: project match - '%s' '%s'", tsk->project, regex);
				break;
			case 'd':
				if (!XOR(invert, match_string(tsk->description, regex)))
					return false;
				else
					tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "eval_rules: description match - '%s' '%s'", tsk->description, regex);
				break;
			case 't':
				if (!XOR(invert, match_string(tsk->tags, regex)))
					return false;
				else
					tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "eval_rules: tag match - '%s' '%s'", tsk->tags, regex);
				break;
			case 'r':
				tmp = calloc(2, sizeof(char));
				*tmp = tsk->priority;
				if (!XOR(invert, match_string(tmp, regex)))
					return false;
				else
					tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "eval_rules: priority match - '%s' '%s'", tmp, regex);
				free(tmp);
				break;
			default:
				go = false;
				break;
		}
		free(regex);
		if (go)
			return eval_rules(rule+move, tsk, selected);
	}

	/* should never get here */
	tnc_fprintf(logfp, LOG_ERROR, "malformed rules - \"%s\"", rule);
	return false;
} /* }}} */
Esempio n. 20
0
void tasklist_window() /* {{{ */
{
	/* ncurses main function */
	int c;
	task *cur;
	char *uuid = NULL;

	/* get field lengths */
	cfg.fieldlengths.project = max_project_length();
	cfg.fieldlengths.date = DATELENGTH;

	/* create windows */
	rows = LINES;
	cols = COLS;
	tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "rows: %d, columns: %d", rows, cols);
	header = newwin(1, cols, 0, 0);
	tasklist = newwin(rows-2, cols, 1, 0);
	statusbar = newwin(1, cols, rows-1, 0);
	tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "ncurses windows: h:%p, t:%p, s:%p (%d,%d)", header, tasklist, statusbar, rows, cols);
	if (statusbar==NULL || tasklist==NULL || header==NULL)
	{
		tnc_fprintf(logfp, LOG_ERROR, "window creation failed (rows:%d, cols:%d)", rows, cols);
		ncurses_end(-1);
	}

	/* set curses settings */
	set_curses_mode(NCURSES_MODE_STD);

	/* print task list */
	check_screen_size();
	cfg.fieldlengths.description = COLS-cfg.fieldlengths.project-1-cfg.fieldlengths.date;
	task_count();
	print_header();
	tasklist_print_task_list();

	/* main loop */
	while (1)
	{
		/* set variables for determining actions */
		done = false;
		redraw = false;
		reload = false;

		/* check for an empty task list */
		if (head == NULL)
		{
			if (strcmp(active_filter,"") == 0){
				tnc_fprintf(logfp, LOG_ERROR, "it appears that your task list is empty. %s does not yet support empty task lists.", PROGNAME);
				ncurses_end(-1);
			}
			active_filter = strdup("");
			reload = true;
		}

		/* get the screen size */
		rows = LINES;
		cols = COLS;

		/* check for a screen thats too small */
		check_screen_size();

		/* check for size changes */
		check_resize();

		/* apply staged window updates */
		doupdate();

		/* get a character */
		c = wgetch(statusbar);

		/* handle the character */
		handle_keypress(c, MODE_TASKLIST);

		/* exit */
		if (done)
			break;
		/* reload task list */
		if (reload)
		{
			cur = get_task_by_position(selline);
			if (cur != NULL)
				uuid = strdup(cur->uuid);
			wipe_tasklist();
			reload_tasks();
			task_count();
			redraw = true;
			if (cfg.follow_task)
				set_position_by_uuid(uuid);
			check_free(uuid);
			uuid = NULL;
			tasklist_check_curs_pos();
		}
		/* redraw all windows */
		if (redraw)
		{
			cfg.fieldlengths.project = max_project_length();
			cfg.fieldlengths.description = cols-cfg.fieldlengths.project-1-cfg.fieldlengths.date;
			print_header();
			tasklist_print_task_list();
			tasklist_check_curs_pos();
			touchwin(tasklist);
			touchwin(header);
			touchwin(statusbar);
			wnoutrefresh(tasklist);
			wnoutrefresh(header);
			wnoutrefresh(statusbar);
			doupdate();
		}

		statusbar_timeout();
	}
} /* }}} */
Esempio n. 21
0
void run_command_bind(char *args) /* {{{ */
{
	/**
	 * create a new keybind
	 * syntax - mode key function [funcarg]
	 */
	int key, ret = 0;
	char *function = NULL, *arg = NULL, *keystr = NULL, *modestr = NULL, *keyname = NULL;
	void (*func)();
	funcmap *fmap;
	prog_mode mode;

	/* parse command */
	if (args != NULL)
		ret = sscanf(args, "%ms %ms %ms %m[^\n]", &modestr, &keystr, &function, &arg);
	if (ret < 3)
	{
		statusbar_message(cfg.statusbar_timeout, "syntax: bind <mode> <key> <function> <args>");
		tnc_fprintf(logfp, LOG_ERROR, "syntax: bind <mode> <key> <function> <args> [%d](%s)", ret, args);
		goto cleanup;
	}

	/* parse mode string */
	if (str_eq(modestr, "tasklist"))
		mode = MODE_TASKLIST;
	else if (str_eq(modestr, "pager"))
		mode = MODE_PAGER;
	else
	{
		tnc_fprintf(logfp, LOG_ERROR, "bind: invalid mode (%s)", modestr);
		goto cleanup;
	}

	/* parse key */
	key = parse_key(keystr);

	/* map function to function call */
	fmap = find_function(function, mode);
	if (fmap==NULL)
	{
		tnc_fprintf(logfp, LOG_ERROR, "bind: invalid function specified (%s)", args);
		goto cleanup;
	}
	func = fmap->function;

	/* error out if there is no argument specified when required */
	if (fmap->argn>0 && arg==NULL)
	{
		statusbar_message(cfg.statusbar_timeout, "bind: argument required for function %s", function);
		goto cleanup;
	}

	/* add keybind */
	add_keybind(key, func, arg, mode);
	keyname = name_key(key);
	statusbar_message(cfg.statusbar_timeout, "key %s (%d) bound to %s - %s", keyname, key, modestr, name_function(func));
	goto cleanup;

cleanup:
	free(function);
	free(arg);
	free(keystr);
	free(modestr);
	free(keyname);
	return;
} /* }}} */