Read key and value of each configuration setting in one loop cycle to facilitate adjustments of the configuration setting format. Also, this allows us to get rid of all the redundant variable resetting. Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
1428 lines
44 KiB
C
1428 lines
44 KiB
C
/*
|
|
* Calcurse - text-based organizer
|
|
*
|
|
* Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* - Redistributions of source code must retain the above
|
|
* copyright notice, this list of conditions and the
|
|
* following disclaimer.
|
|
*
|
|
* - Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the
|
|
* following disclaimer in the documentation and/or other
|
|
* materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* Send your feedback or comments to : misc@calcurse.org
|
|
* Calcurse home page : http://calcurse.org
|
|
*
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
#include "calcurse.h"
|
|
|
|
/* Available configuration variables. */
|
|
enum conf_var {
|
|
CUSTOM_CONF_NOVARIABLE,
|
|
CUSTOM_CONF_AUTOSAVE,
|
|
CUSTOM_CONF_PERIODICSAVE,
|
|
CUSTOM_CONF_CONFIRMQUIT,
|
|
CUSTOM_CONF_CONFIRMDELETE,
|
|
CUSTOM_CONF_SKIPSYSTEMDIALOGS,
|
|
CUSTOM_CONF_SKIPPROGRESSBAR,
|
|
CUSTOM_CONF_CALENDAR_DEFAULTVIEW,
|
|
CUSTOM_CONF_WEEKBEGINSONMONDAY,
|
|
CUSTOM_CONF_COLORTHEME,
|
|
CUSTOM_CONF_LAYOUT,
|
|
CUSTOM_CONF_SBAR_WIDTH,
|
|
CUSTOM_CONF_NOTIFYBARSHOW,
|
|
CUSTOM_CONF_NOTIFYBARDATE,
|
|
CUSTOM_CONF_NOTIFYBARCLOCK,
|
|
CUSTOM_CONF_NOTIFYBARWARNING,
|
|
CUSTOM_CONF_NOTIFYBARCOMMAND,
|
|
CUSTOM_CONF_OUTPUTDATEFMT,
|
|
CUSTOM_CONF_INPUTDATEFMT,
|
|
CUSTOM_CONF_DMON_ENABLE,
|
|
CUSTOM_CONF_DMON_LOG,
|
|
CUSTOM_CONF_VARIABLES
|
|
};
|
|
|
|
struct attribute {
|
|
int color[7];
|
|
int nocolor[7];
|
|
};
|
|
|
|
static struct attribute attr;
|
|
|
|
static unsigned
|
|
fill_config_var (char *string)
|
|
{
|
|
if (strncmp (string, "yes", 3) == 0)
|
|
return 1;
|
|
else if (strncmp (string, "no", 2) == 0)
|
|
return 0;
|
|
else
|
|
{
|
|
EXIT (_("wrong configuration variable format."));
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Load user color theme from file.
|
|
* Need to handle calcurse versions prior to 1.8, where colors where handled
|
|
* differently (number between 1 and 8).
|
|
*/
|
|
static void
|
|
custom_load_color (char *color, int background)
|
|
{
|
|
#define AWAITED_COLORS 2
|
|
|
|
int i, len, color_num;
|
|
char c[AWAITED_COLORS][BUFSIZ];
|
|
int colr[AWAITED_COLORS];
|
|
|
|
len = strlen (color);
|
|
if (len > 1)
|
|
{
|
|
/* New version configuration */
|
|
if (sscanf (color, "%s on %s", c[0], c[1]) != AWAITED_COLORS)
|
|
{
|
|
EXIT (_("missing colors in config file"));
|
|
/* NOTREACHED */
|
|
}
|
|
|
|
for (i = 0; i < AWAITED_COLORS; i++)
|
|
{
|
|
if (!strncmp (c[i], "black", 5))
|
|
colr[i] = COLOR_BLACK;
|
|
else if (!strncmp (c[i], "red", 3))
|
|
colr[i] = COLOR_RED;
|
|
else if (!strncmp (c[i], "green", 5))
|
|
colr[i] = COLOR_GREEN;
|
|
else if (!strncmp (c[i], "yellow", 6))
|
|
colr[i] = COLOR_YELLOW;
|
|
else if (!strncmp (c[i], "blue", 4))
|
|
colr[i] = COLOR_BLUE;
|
|
else if (!strncmp (c[i], "magenta", 7))
|
|
colr[i] = COLOR_MAGENTA;
|
|
else if (!strncmp (c[i], "cyan", 4))
|
|
colr[i] = COLOR_CYAN;
|
|
else if (!strncmp (c[i], "white", 5))
|
|
colr[i] = COLOR_WHITE;
|
|
else if (!strncmp (c[i], "default", 7))
|
|
colr[i] = background;
|
|
else
|
|
{
|
|
EXIT (_("wrong color name"));
|
|
/* NOTREACHED */
|
|
}
|
|
}
|
|
init_pair (COLR_CUSTOM, colr[0], colr[1]);
|
|
}
|
|
else if (len > 0 && len < 2)
|
|
{
|
|
/* Old version configuration */
|
|
color_num = atoi (color);
|
|
|
|
switch (color_num)
|
|
{
|
|
case 0:
|
|
colorize = 0;
|
|
break;
|
|
case 1:
|
|
init_pair (COLR_CUSTOM, COLOR_RED, background);
|
|
break;
|
|
case 2:
|
|
init_pair (COLR_CUSTOM, COLOR_GREEN, background);
|
|
break;
|
|
case 3:
|
|
init_pair (COLR_CUSTOM, COLOR_BLUE, background);
|
|
break;
|
|
case 4:
|
|
init_pair (COLR_CUSTOM, COLOR_CYAN, background);
|
|
break;
|
|
case 5:
|
|
init_pair (COLR_CUSTOM, COLOR_YELLOW, background);
|
|
break;
|
|
case 6:
|
|
init_pair (COLR_CUSTOM, COLOR_BLACK, COLR_GREEN);
|
|
break;
|
|
case 7:
|
|
init_pair (COLR_CUSTOM, COLOR_BLACK, COLR_YELLOW);
|
|
break;
|
|
case 8:
|
|
init_pair (COLR_CUSTOM, COLOR_RED, COLR_BLUE);
|
|
break;
|
|
default:
|
|
EXIT (_("wrong color number"));
|
|
/* NOTREACHED */
|
|
}
|
|
}
|
|
else
|
|
{
|
|
EXIT (_("wrong configuration variable format"));
|
|
/* NOTREACHED */
|
|
}
|
|
}
|
|
|
|
/*
|
|
* 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 (void)
|
|
{
|
|
attr.color[ATTR_HIGHEST] = COLOR_PAIR (COLR_CUSTOM);
|
|
attr.color[ATTR_HIGH] = COLOR_PAIR (COLR_HIGH);
|
|
attr.color[ATTR_MIDDLE] = COLOR_PAIR (COLR_RED);
|
|
attr.color[ATTR_LOW] = COLOR_PAIR (COLR_CYAN);
|
|
attr.color[ATTR_LOWEST] = COLOR_PAIR (COLR_YELLOW);
|
|
attr.color[ATTR_TRUE] = COLOR_PAIR (COLR_GREEN);
|
|
attr.color[ATTR_FALSE] = COLOR_PAIR (COLR_RED);
|
|
|
|
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]);
|
|
}
|
|
|
|
/* Load the user configuration. */
|
|
void
|
|
custom_load_conf (struct conf *conf, int background)
|
|
{
|
|
FILE *data_file;
|
|
char *mesg_line1 = _("Failed to open config file");
|
|
char *mesg_line2 = _("Press [ENTER] to continue");
|
|
char buf[BUFSIZ], e_conf[BUFSIZ];
|
|
enum conf_var var;
|
|
|
|
data_file = fopen (path_conf, "r");
|
|
if (data_file == NULL)
|
|
{
|
|
status_mesg (mesg_line1, mesg_line2);
|
|
wnoutrefresh (win[STA].p);
|
|
wins_doupdate ();
|
|
(void)keys_getch (win[STA].p);
|
|
}
|
|
pthread_mutex_lock (&nbar.mutex);
|
|
for (;;)
|
|
{
|
|
if (fgets (buf, sizeof buf, data_file) == NULL)
|
|
break;
|
|
io_extract_data (e_conf, buf, sizeof buf);
|
|
|
|
if (strncmp (e_conf, "auto_save=", 10) == 0)
|
|
var = CUSTOM_CONF_AUTOSAVE;
|
|
else if (strncmp (e_conf, "periodic_save=", 14) == 0)
|
|
var = CUSTOM_CONF_PERIODICSAVE;
|
|
else if (strncmp (e_conf, "confirm_quit=", 13) == 0)
|
|
var = CUSTOM_CONF_CONFIRMQUIT;
|
|
else if (strncmp (e_conf, "confirm_delete=", 15) == 0)
|
|
var = CUSTOM_CONF_CONFIRMDELETE;
|
|
else if (strncmp (e_conf, "skip_system_dialogs=", 20) == 0)
|
|
var = CUSTOM_CONF_SKIPSYSTEMDIALOGS;
|
|
else if (strncmp (e_conf, "skip_progress_bar=", 18) == 0)
|
|
var = CUSTOM_CONF_SKIPPROGRESSBAR;
|
|
else if (strncmp (e_conf, "calendar_default_view=", 22) == 0)
|
|
var = CUSTOM_CONF_CALENDAR_DEFAULTVIEW;
|
|
else if (strncmp (e_conf, "week_begins_on_monday=", 22) == 0)
|
|
var = CUSTOM_CONF_WEEKBEGINSONMONDAY;
|
|
else if (strncmp (e_conf, "color-theme=", 12) == 0)
|
|
var = CUSTOM_CONF_COLORTHEME;
|
|
else if (strncmp (e_conf, "layout=", 7) == 0)
|
|
var = CUSTOM_CONF_LAYOUT;
|
|
else if (strncmp (e_conf, "side-bar_width=", 15) == 0)
|
|
var = CUSTOM_CONF_SBAR_WIDTH;
|
|
else if (strncmp (e_conf, "notify-bar_show=", 16) == 0)
|
|
var = CUSTOM_CONF_NOTIFYBARSHOW;
|
|
else if (strncmp (e_conf, "notify-bar_date=", 16) == 0)
|
|
var = CUSTOM_CONF_NOTIFYBARDATE;
|
|
else if (strncmp (e_conf, "notify-bar_clock=", 17) == 0)
|
|
var = CUSTOM_CONF_NOTIFYBARCLOCK;
|
|
else if (strncmp (e_conf, "notify-bar_warning=", 19) == 0)
|
|
var = CUSTOM_CONF_NOTIFYBARWARNING;
|
|
else if (strncmp (e_conf, "notify-bar_command=", 19) == 0)
|
|
var = CUSTOM_CONF_NOTIFYBARCOMMAND;
|
|
else if (strncmp (e_conf, "output_datefmt=", 15) == 0)
|
|
var = CUSTOM_CONF_OUTPUTDATEFMT;
|
|
else if (strncmp (e_conf, "input_datefmt=", 14) == 0)
|
|
var = CUSTOM_CONF_INPUTDATEFMT;
|
|
else if (strncmp (e_conf, "notify-daemon_enable=", 21) == 0)
|
|
var = CUSTOM_CONF_DMON_ENABLE;
|
|
else if (strncmp (e_conf, "notify-daemon_log=", 18) == 0)
|
|
var = CUSTOM_CONF_DMON_LOG;
|
|
else
|
|
{
|
|
var = CUSTOM_CONF_NOVARIABLE;
|
|
continue;
|
|
}
|
|
|
|
if (fgets (buf, sizeof buf, data_file) == NULL)
|
|
break;
|
|
io_extract_data (e_conf, buf, sizeof buf);
|
|
|
|
switch (var)
|
|
{
|
|
case CUSTOM_CONF_NOVARIABLE:
|
|
break;
|
|
case CUSTOM_CONF_AUTOSAVE:
|
|
conf->auto_save = fill_config_var (e_conf);
|
|
break;
|
|
case CUSTOM_CONF_PERIODICSAVE:
|
|
if (atoi (e_conf) < 0)
|
|
conf->periodic_save = 0;
|
|
else
|
|
conf->periodic_save = atoi (e_conf);
|
|
break;
|
|
case CUSTOM_CONF_CONFIRMQUIT:
|
|
conf->confirm_quit = fill_config_var (e_conf);
|
|
break;
|
|
case CUSTOM_CONF_CONFIRMDELETE:
|
|
conf->confirm_delete = fill_config_var (e_conf);
|
|
break;
|
|
case CUSTOM_CONF_SKIPSYSTEMDIALOGS:
|
|
conf->skip_system_dialogs = fill_config_var (e_conf);
|
|
break;
|
|
case CUSTOM_CONF_SKIPPROGRESSBAR:
|
|
conf->skip_progress_bar = fill_config_var (e_conf);
|
|
break;
|
|
case CUSTOM_CONF_CALENDAR_DEFAULTVIEW:
|
|
calendar_set_view (atoi (e_conf));
|
|
break;
|
|
case CUSTOM_CONF_WEEKBEGINSONMONDAY:
|
|
if (fill_config_var (e_conf))
|
|
calendar_set_first_day_of_week (MONDAY);
|
|
else
|
|
calendar_set_first_day_of_week (SUNDAY);
|
|
break;
|
|
case CUSTOM_CONF_COLORTHEME:
|
|
custom_load_color (e_conf, background);
|
|
break;
|
|
case CUSTOM_CONF_LAYOUT:
|
|
wins_set_layout (atoi (e_conf));
|
|
break;
|
|
case CUSTOM_CONF_SBAR_WIDTH:
|
|
wins_set_sbar_width (atoi (e_conf));
|
|
break;
|
|
case CUSTOM_CONF_NOTIFYBARSHOW:
|
|
nbar.show = fill_config_var (e_conf);
|
|
break;
|
|
case CUSTOM_CONF_NOTIFYBARDATE:
|
|
(void)strncpy (nbar.datefmt, e_conf, strlen (e_conf) + 1);
|
|
break;
|
|
case CUSTOM_CONF_NOTIFYBARCLOCK:
|
|
(void)strncpy (nbar.timefmt, e_conf, strlen (e_conf) + 1);
|
|
break;
|
|
case CUSTOM_CONF_NOTIFYBARWARNING:
|
|
nbar.cntdwn = atoi (e_conf);
|
|
break;
|
|
case CUSTOM_CONF_NOTIFYBARCOMMAND:
|
|
(void)strncpy (nbar.cmd, e_conf, strlen (e_conf) + 1);
|
|
break;
|
|
case CUSTOM_CONF_OUTPUTDATEFMT:
|
|
if (e_conf[0] != '\0')
|
|
(void)strncpy (conf->output_datefmt, e_conf, strlen (e_conf) + 1);
|
|
break;
|
|
case CUSTOM_CONF_INPUTDATEFMT:
|
|
conf->input_datefmt = atoi (e_conf);
|
|
if (conf->input_datefmt <= 0 || conf->input_datefmt >= DATE_FORMATS)
|
|
conf->input_datefmt = 1;
|
|
break;
|
|
case CUSTOM_CONF_DMON_ENABLE:
|
|
dmon.enable = fill_config_var (e_conf);
|
|
break;
|
|
case CUSTOM_CONF_DMON_LOG:
|
|
dmon.log = fill_config_var (e_conf);
|
|
break;
|
|
default:
|
|
EXIT (_("configuration variable unknown"));
|
|
/* NOTREACHED */
|
|
}
|
|
}
|
|
file_close (data_file, __FILE_POS__);
|
|
pthread_mutex_unlock (&nbar.mutex);
|
|
}
|
|
|
|
/* Draws the configuration bar */
|
|
void
|
|
custom_config_bar (void)
|
|
{
|
|
const int SMLSPC = 2;
|
|
const int SPC = 15;
|
|
|
|
custom_apply_attr (win[STA].p, ATTR_HIGHEST);
|
|
mvwprintw (win[STA].p, 0, 2, "Q");
|
|
mvwprintw (win[STA].p, 1, 2, "G");
|
|
mvwprintw (win[STA].p, 0, 2 + SPC, "L");
|
|
mvwprintw (win[STA].p, 1, 2 + SPC, "S");
|
|
mvwprintw (win[STA].p, 0, 2 + 2 * SPC, "C");
|
|
mvwprintw (win[STA].p, 1, 2 + 2 * SPC, "N");
|
|
mvwprintw (win[STA].p, 0, 2 + 3 * SPC, "K");
|
|
custom_remove_attr (win[STA].p, ATTR_HIGHEST);
|
|
|
|
mvwprintw (win[STA].p, 0, 2 + SMLSPC, _("Exit"));
|
|
mvwprintw (win[STA].p, 1, 2 + SMLSPC, _("General"));
|
|
mvwprintw (win[STA].p, 0, 2 + SPC + SMLSPC, _("Layout"));
|
|
mvwprintw (win[STA].p, 1, 2 + SPC + SMLSPC, _("Sidebar"));
|
|
mvwprintw (win[STA].p, 0, 2 + 2 * SPC + SMLSPC, _("Color"));
|
|
mvwprintw (win[STA].p, 1, 2 + 2 * SPC + SMLSPC, _("Notify"));
|
|
mvwprintw (win[STA].p, 0, 2 + 3 * SPC + SMLSPC, _("Keys"));
|
|
|
|
wnoutrefresh (win[STA].p);
|
|
wmove (win[STA].p, 0, 0);
|
|
wins_doupdate ();
|
|
}
|
|
|
|
static void
|
|
layout_selection_bar (void)
|
|
{
|
|
struct binding quit = {_("Exit"), KEY_GENERIC_QUIT};
|
|
struct binding select = {_("Select"), KEY_GENERIC_SELECT};
|
|
struct binding up = {_("Up"), KEY_MOVE_UP};
|
|
struct binding down = {_("Down"), KEY_MOVE_DOWN};
|
|
struct binding left = {_("Left"), KEY_MOVE_LEFT};
|
|
struct binding right = {_("Right"), KEY_MOVE_RIGHT};
|
|
struct binding help = {_("Help"), KEY_GENERIC_HELP};
|
|
|
|
struct binding *binding[] = {&quit, &select, &up, &down, &left, &right, &help};
|
|
int binding_size = sizeof (binding) / sizeof (binding[0]);
|
|
|
|
keys_display_bindings_bar (win[STA].p, binding, 0, binding_size);
|
|
}
|
|
|
|
#define NBLAYOUTS 8
|
|
#define LAYOUTSPERCOL 2
|
|
|
|
/* Used to display available layouts in layout configuration menu. */
|
|
static void
|
|
display_layout_config (struct window *lwin, int mark, int cursor)
|
|
{
|
|
#define CURSOR (32 | A_REVERSE)
|
|
#define MARK 88
|
|
#define LAYOUTH 5
|
|
#define LAYOUTW 9
|
|
char *box = "[ ]";
|
|
const int BOXSIZ = strlen (box);
|
|
const int NBCOLS = NBLAYOUTS / LAYOUTSPERCOL;
|
|
const int COLSIZ = LAYOUTW + BOXSIZ + 1;
|
|
const int XSPC = (lwin->w - NBCOLS * COLSIZ) / (NBCOLS + 1);
|
|
const int XOFST = (lwin->w - NBCOLS * (XSPC + COLSIZ)) / 2;
|
|
const int YSPC = (lwin->h - 8 - LAYOUTSPERCOL * LAYOUTH) / (LAYOUTSPERCOL + 1);
|
|
const int YOFST = (lwin->h - LAYOUTSPERCOL * (YSPC + LAYOUTH)) / 2;
|
|
enum {YPOS, XPOS, NBPOS};
|
|
int pos[NBLAYOUTS][NBPOS];
|
|
char *layouts[LAYOUTH][NBLAYOUTS] = {
|
|
{"+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+"},
|
|
{"| | c |", "| | t |", "| c | |", "| t | |", "| | c |", "| | a |", "| c | |", "| a | |"},
|
|
{"| a +---+", "| a +---+", "+---+ a |", "|---+ a |", "| t +---+", "| t +---+", "+---+ t |", "+---+ t |"},
|
|
{"| | t |", "| | c |", "| t | |", "| c | |", "| | a |", "| | c |", "| a | |", "| c | |"},
|
|
{"+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+"}
|
|
};
|
|
int i;
|
|
|
|
for (i = 0; i < NBLAYOUTS; i++)
|
|
{
|
|
pos[i][YPOS] = YOFST + (i % LAYOUTSPERCOL) * (YSPC + LAYOUTH);
|
|
pos[i][XPOS] = XOFST + (i / LAYOUTSPERCOL) * (XSPC + COLSIZ);
|
|
}
|
|
|
|
for (i = 0; i < NBLAYOUTS; i++)
|
|
{
|
|
int j;
|
|
|
|
mvwprintw (lwin->p, pos[i][YPOS] + 2, pos[i][XPOS], box);
|
|
if (i == mark)
|
|
custom_apply_attr (lwin->p, ATTR_HIGHEST);
|
|
for (j = 0; j < LAYOUTH; j++)
|
|
{
|
|
mvwprintw (lwin->p, pos[i][YPOS] + j, pos[i][XPOS] + BOXSIZ + 1,
|
|
layouts[j][i]);
|
|
}
|
|
if (i == mark)
|
|
custom_remove_attr (lwin->p, ATTR_HIGHEST);
|
|
}
|
|
mvwaddch (lwin->p, pos[mark][YPOS] + 2, pos[mark][XPOS] + 1, MARK);
|
|
mvwaddch (lwin->p, pos[cursor][YPOS] + 2, pos[cursor][XPOS] + 1, CURSOR);
|
|
|
|
layout_selection_bar ();
|
|
wnoutrefresh (win[STA].p);
|
|
wnoutrefresh (lwin->p);
|
|
wins_doupdate ();
|
|
if (notify_bar ())
|
|
notify_update_bar ();
|
|
}
|
|
|
|
/* Choose the layout */
|
|
void
|
|
custom_layout_config (void)
|
|
{
|
|
struct scrollwin hwin;
|
|
struct window conf_win;
|
|
int ch, mark, cursor, need_reset;
|
|
char label[BUFSIZ];
|
|
char *help_text =
|
|
_("With this configuration menu, one can choose where panels will be\n"
|
|
"displayed inside calcurse screen. \n"
|
|
"It is possible to choose between eight different configurations.\n"
|
|
"\nIn the configuration representations, letters correspond to:\n\n"
|
|
" 'c' -> calendar panel\n\n"
|
|
" 'a' -> appointment panel\n\n"
|
|
" 't' -> todo panel\n\n");
|
|
|
|
conf_win.p = (WINDOW *)0;
|
|
(void)snprintf (label, BUFSIZ, _("layout configuration"));
|
|
custom_confwin_init (&conf_win, label);
|
|
cursor = mark = wins_layout () - 1;
|
|
display_layout_config (&conf_win, mark, cursor);
|
|
clear ();
|
|
|
|
while ((ch = keys_getch (win[STA].p)) != KEY_GENERIC_QUIT)
|
|
{
|
|
need_reset = 0;
|
|
switch (ch)
|
|
{
|
|
case KEY_GENERIC_HELP:
|
|
help_wins_init (&hwin, 0, 0,
|
|
(notify_bar ()) ? row - 3 : row - 2, col);
|
|
mvwprintw (hwin.pad.p, 1, 0, "%s", help_text);
|
|
hwin.total_lines = 7;
|
|
wins_scrollwin_display (&hwin);
|
|
wgetch (hwin.win.p);
|
|
wins_scrollwin_delete (&hwin);
|
|
need_reset = 1;
|
|
break;
|
|
case KEY_GENERIC_SELECT:
|
|
mark = cursor;
|
|
break;
|
|
case KEY_MOVE_DOWN:
|
|
if (cursor % LAYOUTSPERCOL < LAYOUTSPERCOL - 1)
|
|
cursor++;
|
|
break;
|
|
case KEY_MOVE_UP:
|
|
if (cursor % LAYOUTSPERCOL > 0)
|
|
cursor--;
|
|
break;
|
|
case KEY_MOVE_LEFT:
|
|
if (cursor >= LAYOUTSPERCOL)
|
|
cursor -= LAYOUTSPERCOL;
|
|
break;
|
|
case KEY_MOVE_RIGHT:
|
|
if (cursor < NBLAYOUTS - LAYOUTSPERCOL)
|
|
cursor += LAYOUTSPERCOL;
|
|
break;
|
|
case KEY_GENERIC_CANCEL:
|
|
need_reset = 1;
|
|
break;
|
|
}
|
|
|
|
if (resize)
|
|
{
|
|
resize = 0;
|
|
endwin ();
|
|
wins_refresh ();
|
|
curs_set (0);
|
|
need_reset = 1;
|
|
}
|
|
|
|
if (need_reset)
|
|
custom_confwin_init (&conf_win, label);
|
|
|
|
display_layout_config (&conf_win, mark, cursor);
|
|
}
|
|
wins_set_layout (mark + 1);
|
|
delwin (conf_win.p);
|
|
}
|
|
|
|
#undef NBLAYOUTS
|
|
#undef LAYOUTSPERCOL
|
|
|
|
/* Sidebar configuration screen. */
|
|
void
|
|
custom_sidebar_config (void)
|
|
{
|
|
struct scrollwin hwin;
|
|
struct binding quit = {_("Exit"), KEY_GENERIC_QUIT};
|
|
struct binding inc = {_("Width +"), KEY_MOVE_UP};
|
|
struct binding dec = {_("Width -"), KEY_MOVE_DOWN};
|
|
struct binding help = {_("Help"), KEY_GENERIC_HELP};
|
|
struct binding *binding[] = {&inc, &dec, &help, &quit};
|
|
char *help_text =
|
|
_("This configuration screen is used to change the width of the side bar.\n"
|
|
"The side bar is the part of the screen which contains two panels:\n"
|
|
"the calendar and, depending on the chosen layout, either the todo list\n"
|
|
"or the appointment list.\n\n"
|
|
"The side bar width can be up to 50% of the total screen width, but\n"
|
|
"can't be smaller than " TOSTRING(SBARMINWIDTH) " characters wide.\n\n");
|
|
int ch, binding_size;
|
|
|
|
binding_size = sizeof (binding) / sizeof (binding[0]);
|
|
|
|
keys_display_bindings_bar (win[STA].p, binding, 0, binding_size);
|
|
wins_doupdate ();
|
|
|
|
while ((ch = keys_getch (win[STA].p)) != KEY_GENERIC_QUIT)
|
|
{
|
|
switch (ch)
|
|
{
|
|
case KEY_MOVE_UP:
|
|
wins_sbar_winc ();
|
|
break;
|
|
case KEY_MOVE_DOWN:
|
|
wins_sbar_wdec ();
|
|
break;
|
|
case KEY_GENERIC_HELP:
|
|
help_wins_init (&hwin, 0, 0,
|
|
(notify_bar ()) ? row - 3 : row - 2, col);
|
|
mvwprintw (hwin.pad.p, 1, 0, "%s", help_text);
|
|
hwin.total_lines = 6;
|
|
wins_scrollwin_display (&hwin);
|
|
wgetch (hwin.win.p);
|
|
wins_scrollwin_delete (&hwin);
|
|
break;
|
|
case KEY_RESIZE:
|
|
break;
|
|
default:
|
|
continue;
|
|
}
|
|
|
|
if (resize)
|
|
{
|
|
resize = 0;
|
|
wins_reset ();
|
|
}
|
|
else
|
|
{
|
|
wins_reinit_panels ();
|
|
wins_update_border ();
|
|
wins_update_panels ();
|
|
keys_display_bindings_bar (win[STA].p, binding, 0, binding_size);
|
|
wins_doupdate ();
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
set_confwin_attr (struct window *cwin)
|
|
{
|
|
cwin->h = (notify_bar ())? row - 3 : row - 2;
|
|
cwin->w = col;
|
|
cwin->x = cwin->y = 0;
|
|
}
|
|
|
|
/*
|
|
* Create a configuration window and initialize status and notification bar
|
|
* (useful in case of window resize).
|
|
*/
|
|
void
|
|
custom_confwin_init (struct window *confwin, char *label)
|
|
{
|
|
if (confwin->p)
|
|
{
|
|
erase_window_part (confwin->p, confwin->x, confwin->y,
|
|
confwin->x + confwin->w, confwin->y + confwin->h);
|
|
(void)delwin (confwin->p);
|
|
}
|
|
|
|
wins_get_config ();
|
|
set_confwin_attr (confwin);
|
|
confwin->p = newwin (confwin->h, col, 0, 0);
|
|
box (confwin->p, 0, 0);
|
|
wins_show (confwin->p, label);
|
|
delwin (win[STA].p);
|
|
win[STA].p = newwin (win[STA].h, win[STA].w, win[STA].y, win[STA].x);
|
|
keypad (win[STA].p, TRUE);
|
|
if (notify_bar ())
|
|
{
|
|
notify_reinit_bar ();
|
|
notify_update_bar ();
|
|
}
|
|
}
|
|
|
|
static void
|
|
color_selection_bar (void)
|
|
{
|
|
struct binding quit = {_("Exit"), KEY_GENERIC_QUIT};
|
|
struct binding select = {_("Select"), KEY_GENERIC_SELECT};
|
|
struct binding nocolor = {_("No color"), KEY_GENERIC_CANCEL};
|
|
struct binding up = {_("Up"), KEY_MOVE_UP};
|
|
struct binding down = {_("Down"), KEY_MOVE_DOWN};
|
|
struct binding left = {_("Left"), KEY_MOVE_LEFT};
|
|
struct binding right = {_("Right"), KEY_MOVE_RIGHT};
|
|
|
|
|
|
struct binding *binding[] = {
|
|
&quit, &nocolor, &up, &down, &left, &right, &select
|
|
};
|
|
int binding_size = sizeof (binding) / sizeof (binding[0]);
|
|
|
|
keys_display_bindings_bar (win[STA].p, binding, 0, binding_size);
|
|
}
|
|
|
|
/*
|
|
* Used to display available colors in color configuration menu.
|
|
* This is useful for window resizing.
|
|
*/
|
|
static void
|
|
display_color_config (struct window *cwin, int *mark_fore, int *mark_back,
|
|
int cursor, int theme_changed)
|
|
{
|
|
#define SIZE (2 * (NBUSERCOLORS + 1))
|
|
#define DEFAULTCOLOR 255
|
|
#define DEFAULTCOLOR_EXT -1
|
|
#define CURSOR (32 | A_REVERSE)
|
|
#define MARK 88
|
|
|
|
char *fore_txt = _("Foreground");
|
|
char *back_txt = _("Background");
|
|
char *default_txt = _("(terminal's default)");
|
|
char *bar = " ";
|
|
char *box = "[ ]";
|
|
const unsigned Y = 3;
|
|
const unsigned XOFST = 5;
|
|
const unsigned YSPC = (cwin->h - 8) / (NBUSERCOLORS + 1);
|
|
const unsigned BARSIZ = strlen (bar);
|
|
const unsigned BOXSIZ = strlen (box);
|
|
const unsigned XSPC = (cwin->w - 2 * BARSIZ - 2 * BOXSIZ - 6) / 3;
|
|
const unsigned XFORE = XSPC;
|
|
const unsigned XBACK = 2 * XSPC + BOXSIZ + XOFST + BARSIZ;
|
|
enum
|
|
{ YPOS, XPOS, NBPOS };
|
|
unsigned i;
|
|
int pos[SIZE][NBPOS];
|
|
short colr_fore, colr_back;
|
|
int colr[SIZE] = {
|
|
COLR_RED, COLR_GREEN, COLR_YELLOW, COLR_BLUE,
|
|
COLR_MAGENTA, COLR_CYAN, COLR_DEFAULT,
|
|
COLR_RED, COLR_GREEN, COLR_YELLOW, COLR_BLUE,
|
|
COLR_MAGENTA, COLR_CYAN, COLR_DEFAULT
|
|
};
|
|
|
|
for (i = 0; i < NBUSERCOLORS + 1; i++)
|
|
{
|
|
pos[i][YPOS] = Y + YSPC * (i + 1);
|
|
pos[NBUSERCOLORS + i + 1][YPOS] = Y + YSPC * (i + 1);
|
|
pos[i][XPOS] = XFORE;
|
|
pos[NBUSERCOLORS + i + 1][XPOS] = XBACK;
|
|
}
|
|
|
|
if (colorize)
|
|
{
|
|
if (theme_changed)
|
|
{
|
|
pair_content (colr[*mark_fore], &colr_fore, 0L);
|
|
if (colr_fore == 255)
|
|
colr_fore = -1;
|
|
pair_content (colr[*mark_back], &colr_back, 0L);
|
|
if (colr_back == 255)
|
|
colr_back = -1;
|
|
init_pair (COLR_CUSTOM, colr_fore, colr_back);
|
|
}
|
|
else
|
|
{
|
|
/* Retrieve the actual color theme. */
|
|
pair_content (COLR_CUSTOM, &colr_fore, &colr_back);
|
|
|
|
if ((colr_fore == DEFAULTCOLOR) || (colr_fore == DEFAULTCOLOR_EXT))
|
|
*mark_fore = NBUSERCOLORS;
|
|
else
|
|
for (i = 0; i < NBUSERCOLORS + 1; i++)
|
|
if (colr_fore == colr[i])
|
|
*mark_fore = i;
|
|
|
|
if ((colr_back == DEFAULTCOLOR) || (colr_back == DEFAULTCOLOR_EXT))
|
|
*mark_back = SIZE - 1;
|
|
else
|
|
for (i = 0; i < NBUSERCOLORS + 1; i++)
|
|
if (colr_back == colr[NBUSERCOLORS + 1 + i])
|
|
*mark_back = NBUSERCOLORS + 1 + i;
|
|
}
|
|
}
|
|
|
|
/* color boxes */
|
|
for (i = 0; i < SIZE - 1; i++)
|
|
{
|
|
mvwprintw (cwin->p, pos[i][YPOS], pos[i][XPOS], box);
|
|
wattron (cwin->p, COLOR_PAIR (colr[i]) | A_REVERSE);
|
|
mvwprintw (cwin->p, pos[i][YPOS], pos[i][XPOS] + XOFST, bar);
|
|
wattroff (cwin->p, COLOR_PAIR (colr[i]) | A_REVERSE);
|
|
}
|
|
|
|
/* Terminal's default color */
|
|
i = SIZE - 1;
|
|
mvwprintw (cwin->p, pos[i][YPOS], pos[i][XPOS], box);
|
|
wattron (cwin->p, COLOR_PAIR (colr[i]));
|
|
mvwprintw (cwin->p, pos[i][YPOS], pos[i][XPOS] + XOFST, bar);
|
|
wattroff (cwin->p, COLOR_PAIR (colr[i]));
|
|
mvwprintw (cwin->p, pos[NBUSERCOLORS][YPOS] + 1,
|
|
pos[NBUSERCOLORS][XPOS] + XOFST, default_txt);
|
|
mvwprintw (cwin->p, pos[SIZE - 1][YPOS] + 1,
|
|
pos[SIZE - 1][XPOS] + XOFST, default_txt);
|
|
|
|
custom_apply_attr (cwin->p, ATTR_HIGHEST);
|
|
mvwprintw (cwin->p, Y, XFORE + XOFST, fore_txt);
|
|
mvwprintw (cwin->p, Y, XBACK + XOFST, back_txt);
|
|
custom_remove_attr (cwin->p, ATTR_HIGHEST);
|
|
|
|
if (colorize)
|
|
{
|
|
mvwaddch (cwin->p, pos[*mark_fore][YPOS],
|
|
pos[*mark_fore][XPOS] + 1, MARK);
|
|
mvwaddch (cwin->p, pos[*mark_back][YPOS],
|
|
pos[*mark_back][XPOS] + 1, MARK);
|
|
}
|
|
|
|
mvwaddch (cwin->p, pos[cursor][YPOS], pos[cursor][XPOS] + 1, CURSOR);
|
|
color_selection_bar ();
|
|
wnoutrefresh (win[STA].p);
|
|
wnoutrefresh (cwin->p);
|
|
wins_doupdate ();
|
|
if (notify_bar ())
|
|
notify_update_bar ();
|
|
}
|
|
|
|
/* Color theme configuration. */
|
|
void
|
|
custom_color_config (void)
|
|
{
|
|
struct window conf_win;
|
|
int ch, cursor, need_reset, theme_changed;
|
|
int mark_fore, mark_back;
|
|
char label[BUFSIZ];
|
|
|
|
conf_win.p = 0;
|
|
(void)snprintf (label, BUFSIZ, _("color theme"));
|
|
custom_confwin_init (&conf_win, label);
|
|
mark_fore = NBUSERCOLORS;
|
|
mark_back = SIZE - 1;
|
|
cursor = 0;
|
|
theme_changed = 0;
|
|
display_color_config (&conf_win, &mark_fore, &mark_back, cursor, theme_changed);
|
|
clear ();
|
|
|
|
while ((ch = keys_getch (win[STA].p)) != KEY_GENERIC_QUIT)
|
|
{
|
|
need_reset = 0;
|
|
theme_changed = 0;
|
|
|
|
switch (ch)
|
|
{
|
|
case KEY_GENERIC_SELECT:
|
|
colorize = 1;
|
|
need_reset = 1;
|
|
theme_changed = 1;
|
|
if (cursor > NBUSERCOLORS)
|
|
mark_back = cursor;
|
|
else
|
|
mark_fore = cursor;
|
|
break;
|
|
|
|
case KEY_MOVE_DOWN:
|
|
if (cursor < SIZE - 1)
|
|
++cursor;
|
|
break;
|
|
|
|
case KEY_MOVE_UP:
|
|
if (cursor > 0)
|
|
--cursor;
|
|
break;
|
|
|
|
case KEY_MOVE_LEFT:
|
|
if (cursor > NBUSERCOLORS)
|
|
cursor -= (NBUSERCOLORS + 1);
|
|
break;
|
|
|
|
case KEY_MOVE_RIGHT:
|
|
if (cursor <= NBUSERCOLORS)
|
|
cursor += (NBUSERCOLORS + 1);
|
|
break;
|
|
|
|
case KEY_GENERIC_CANCEL:
|
|
colorize = 0;
|
|
need_reset = 1;
|
|
break;
|
|
}
|
|
|
|
if (resize)
|
|
{
|
|
resize = 0;
|
|
endwin ();
|
|
wins_refresh ();
|
|
curs_set (0);
|
|
need_reset = 1;
|
|
}
|
|
|
|
if (need_reset)
|
|
custom_confwin_init (&conf_win, label);
|
|
|
|
display_color_config (&conf_win, &mark_fore, &mark_back, cursor,
|
|
theme_changed);
|
|
}
|
|
delwin (conf_win.p);
|
|
}
|
|
|
|
/*
|
|
* Return a string defining the color theme in the form:
|
|
* foreground color 'on' background color
|
|
* in order to dump this data in the configuration file.
|
|
* Color numbers follow the ncurses library definitions.
|
|
* If ncurses library was compiled with --enable-ext-funcs,
|
|
* then default color is -1.
|
|
*/
|
|
void
|
|
custom_color_theme_name (char *theme_name)
|
|
{
|
|
#define MAXCOLORS 8
|
|
#define NBCOLORS 2
|
|
#define DEFAULTCOLOR 255
|
|
#define DEFAULTCOLOR_EXT -1
|
|
|
|
int i;
|
|
short color[NBCOLORS];
|
|
char *color_name[NBCOLORS];
|
|
char *default_color = "default";
|
|
char *name[MAXCOLORS] = {
|
|
"black",
|
|
"red",
|
|
"green",
|
|
"yellow",
|
|
"blue",
|
|
"magenta",
|
|
"cyan",
|
|
"white"
|
|
};
|
|
|
|
if (!colorize)
|
|
(void)snprintf (theme_name, BUFSIZ, "0");
|
|
else
|
|
{
|
|
pair_content (COLR_CUSTOM, &color[0], &color[1]);
|
|
for (i = 0; i < NBCOLORS; i++)
|
|
{
|
|
if ((color[i] == DEFAULTCOLOR) || (color[i] == DEFAULTCOLOR_EXT))
|
|
color_name[i] = default_color;
|
|
else if (color[i] >= 0 && color[i] <= MAXCOLORS)
|
|
color_name[i] = name[color[i]];
|
|
else
|
|
{
|
|
EXIT (_("unknown color"));
|
|
/* NOTREACHED */
|
|
}
|
|
}
|
|
(void)snprintf (theme_name, BUFSIZ, "%s on %s", color_name[0],
|
|
color_name[1]);
|
|
}
|
|
}
|
|
|
|
/* Prints the general options. */
|
|
static int
|
|
print_general_options (WINDOW *win, struct conf *conf)
|
|
{
|
|
enum {
|
|
AUTO_SAVE,
|
|
PERIODIC_SAVE,
|
|
CONFIRM_QUIT,
|
|
CONFIRM_DELETE,
|
|
SKIP_SYSTEM_DIAGS,
|
|
SKIP_PROGRESS_BAR,
|
|
WEEK_BEGINS_MONDAY,
|
|
OUTPUT_DATE_FMT,
|
|
INPUT_DATE_FMT,
|
|
NB_OPTIONS
|
|
};
|
|
const int XPOS = 1;
|
|
const int YOFF = 3;
|
|
int y;
|
|
char *opt[NB_OPTIONS] = {
|
|
_("auto_save = "),
|
|
_("periodic_save = "),
|
|
_("confirm_quit = "),
|
|
_("confirm_delete = "),
|
|
_("skip_system_dialogs = "),
|
|
_("skip_progress_bar = "),
|
|
_("week_begins_on_monday = "),
|
|
_("output_datefmt = "),
|
|
_("input_datefmt = ")
|
|
};
|
|
|
|
y = 0;
|
|
mvwprintw (win, y, XPOS, "[1] %s ", opt[AUTO_SAVE]);
|
|
print_bool_option_incolor (win, conf->auto_save, y,
|
|
XPOS + 4 + strlen (opt[AUTO_SAVE]));
|
|
mvwprintw (win, y + 1, XPOS,
|
|
_("(if set to YES, automatic save is done when quitting)"));
|
|
y += YOFF;
|
|
mvwprintw (win, y, XPOS, "[2] %s ", opt[PERIODIC_SAVE]);
|
|
custom_apply_attr (win, ATTR_HIGHEST);
|
|
mvwprintw (win, y, XPOS + 4 + strlen (opt[PERIODIC_SAVE]), "%d",
|
|
conf->periodic_save);
|
|
custom_remove_attr (win, ATTR_HIGHEST);
|
|
mvwprintw (win, y + 1, XPOS,
|
|
_("(if not null, automatically save data every 'periodic_save' "
|
|
"minutes)"));
|
|
y += YOFF;
|
|
mvwprintw (win, y, XPOS, "[3] %s ", opt[CONFIRM_QUIT]);
|
|
print_bool_option_incolor (win, conf->confirm_quit, y,
|
|
XPOS + 4 + strlen (opt[CONFIRM_QUIT]));
|
|
mvwprintw (win, y + 1, XPOS,
|
|
_("(if set to YES, confirmation is required before quitting)"));
|
|
y += YOFF;
|
|
mvwprintw (win, y, XPOS, "[4] %s ", opt[CONFIRM_DELETE]);
|
|
print_bool_option_incolor (win, conf->confirm_delete, y,
|
|
XPOS + 4 + strlen (opt[CONFIRM_DELETE]));
|
|
mvwprintw (win, y + 1, XPOS,
|
|
_("(if set to YES, confirmation is required "
|
|
"before deleting an event)"));
|
|
y += YOFF;
|
|
mvwprintw (win, y, XPOS, "[5] %s ", opt[SKIP_SYSTEM_DIAGS]);
|
|
print_bool_option_incolor (win, conf->skip_system_dialogs, y,
|
|
XPOS + 4 + strlen (opt[SKIP_SYSTEM_DIAGS]));
|
|
mvwprintw (win, y + 1, XPOS,
|
|
_("(if set to YES, messages about loaded "
|
|
"and saved data will not be displayed)"));
|
|
y += YOFF;
|
|
mvwprintw (win, y, XPOS, "[6] %s ", opt[SKIP_PROGRESS_BAR]);
|
|
print_bool_option_incolor (win, conf->skip_progress_bar, y,
|
|
XPOS + 4 + strlen (opt[SKIP_PROGRESS_BAR]));
|
|
mvwprintw (win, y + 1, XPOS,
|
|
_("(if set to YES, progress bar will not be displayed "
|
|
"when saving data)"));
|
|
y += YOFF;
|
|
mvwprintw (win, y, XPOS, "[7] %s ", opt[WEEK_BEGINS_MONDAY]);
|
|
print_bool_option_incolor (win, calendar_week_begins_on_monday (), y,
|
|
XPOS + 4 + strlen (opt[WEEK_BEGINS_MONDAY]));
|
|
mvwprintw (win, y + 1, XPOS,
|
|
_("(if set to YES, monday is the first day of the week, "
|
|
"else it is sunday)"));
|
|
y += YOFF;
|
|
mvwprintw (win, y, XPOS, "[8] %s ", opt[OUTPUT_DATE_FMT]);
|
|
custom_apply_attr (win, ATTR_HIGHEST);
|
|
mvwprintw (win, y, XPOS + 4 + strlen (opt[OUTPUT_DATE_FMT]), "%s",
|
|
conf->output_datefmt);
|
|
custom_remove_attr (win, ATTR_HIGHEST);
|
|
mvwprintw (win, y + 1, XPOS,
|
|
_("(Format of the date to be displayed in non-interactive mode)"));
|
|
y += YOFF;
|
|
mvwprintw (win, y, XPOS, "[9] %s ", opt[INPUT_DATE_FMT]);
|
|
custom_apply_attr (win, ATTR_HIGHEST);
|
|
mvwprintw (win, y, XPOS + 4 + strlen (opt[INPUT_DATE_FMT]), "%d",
|
|
conf->input_datefmt);
|
|
custom_remove_attr (win, ATTR_HIGHEST);
|
|
mvwprintw (win, y + 1, XPOS, _("(Format to be used when entering a date: "));
|
|
mvwprintw (win, y + 2, XPOS,
|
|
_(" (1)mm/dd/yyyy (2)dd/mm/yyyy (3)yyyy/mm/dd (4)yyyy-mm-dd)"));
|
|
|
|
return y + YOFF;
|
|
}
|
|
|
|
void
|
|
custom_set_swsiz (struct scrollwin *sw)
|
|
{
|
|
sw->win.x = 0;
|
|
sw->win.y = 0;
|
|
sw->win.h = (notify_bar ()) ? row - 3 : row - 2;
|
|
sw->win.w = col;
|
|
|
|
sw->pad.x = 1;
|
|
sw->pad.y = 3;
|
|
sw->pad.h = BUFSIZ;
|
|
sw->pad.w = col - 2 * sw->pad.x - 1;
|
|
}
|
|
|
|
/* General configuration. */
|
|
void
|
|
custom_general_config (struct conf *conf)
|
|
{
|
|
struct scrollwin cwin;
|
|
char *number_str =
|
|
_("Enter an option number to change its value");
|
|
char *keys =
|
|
_("(Press '^P' or '^N' to move up or down, 'Q' to quit)");
|
|
char *output_datefmt_str =
|
|
_("Enter the date format (see 'man 3 strftime' for possible formats) ");
|
|
char *input_datefmt_str =
|
|
_("Enter the date format (1)mm/dd/yyyy (2)dd/mm/yyyy (3)yyyy/mm/dd "
|
|
"(4)yyyy-mm-dd");
|
|
char *periodic_save_str =
|
|
_("Enter the delay, in minutes, between automatic saves (0 to disable) ");
|
|
int ch;
|
|
char *buf;
|
|
|
|
clear ();
|
|
custom_set_swsiz (&cwin);
|
|
(void)snprintf (cwin.label, BUFSIZ, _("general options"));
|
|
wins_scrollwin_init (&cwin);
|
|
wins_show (cwin.win.p, cwin.label);
|
|
status_mesg (number_str, keys);
|
|
cwin.total_lines = print_general_options (cwin.pad.p, conf);
|
|
wins_scrollwin_display (&cwin);
|
|
|
|
buf = mem_malloc (BUFSIZ);
|
|
while ((ch = wgetch (win[STA].p)) != 'q')
|
|
{
|
|
buf[0] = '\0';
|
|
|
|
switch (ch)
|
|
{
|
|
case CTRL ('N'):
|
|
wins_scrollwin_down (&cwin, 1);
|
|
break;
|
|
case CTRL ('P'):
|
|
wins_scrollwin_up (&cwin, 1);
|
|
break;
|
|
case '1':
|
|
conf->auto_save = !conf->auto_save;
|
|
break;
|
|
case '2':
|
|
status_mesg (periodic_save_str, "");
|
|
if (updatestring (win[STA].p, &buf, 0, 1) == 0)
|
|
{
|
|
int val = atoi (buf);
|
|
if (val >= 0)
|
|
conf->periodic_save = val;
|
|
if (conf->periodic_save > 0)
|
|
io_start_psave_thread (conf);
|
|
else if (conf->periodic_save == 0)
|
|
io_stop_psave_thread ();
|
|
}
|
|
status_mesg (number_str, keys);
|
|
break;
|
|
case '3':
|
|
conf->confirm_quit = !conf->confirm_quit;
|
|
break;
|
|
case '4':
|
|
conf->confirm_delete = !conf->confirm_delete;
|
|
break;
|
|
case '5':
|
|
conf->skip_system_dialogs = !conf->skip_system_dialogs;
|
|
break;
|
|
case '6':
|
|
conf->skip_progress_bar = !conf->skip_progress_bar;
|
|
break;
|
|
case '7':
|
|
calendar_change_first_day_of_week ();
|
|
break;
|
|
case '8':
|
|
status_mesg (output_datefmt_str, "");
|
|
(void)strncpy (buf, conf->output_datefmt,
|
|
strlen (conf->output_datefmt) + 1);
|
|
if (updatestring (win[STA].p, &buf, 0, 1) == 0)
|
|
{
|
|
(void)strncpy (conf->output_datefmt, buf, strlen (buf) + 1);
|
|
}
|
|
status_mesg (number_str, keys);
|
|
break;
|
|
case '9':
|
|
status_mesg (input_datefmt_str, "");
|
|
if (updatestring (win[STA].p, &buf, 0, 1) == 0)
|
|
{
|
|
int val = atoi (buf);
|
|
if (val > 0 && val <= DATE_FORMATS)
|
|
conf->input_datefmt = val;
|
|
}
|
|
status_mesg (number_str, keys);
|
|
break;
|
|
}
|
|
|
|
if (resize)
|
|
{
|
|
resize = 0;
|
|
wins_reset ();
|
|
wins_scrollwin_delete (&cwin);
|
|
custom_set_swsiz (&cwin);
|
|
wins_scrollwin_init (&cwin);
|
|
wins_show (cwin.win.p, cwin.label);
|
|
cwin.first_visible_line = 0;
|
|
delwin (win[STA].p);
|
|
win[STA].p = newwin (win[STA].h, win[STA].w, win[STA].y,
|
|
win[STA].x);
|
|
keypad (win[STA].p, TRUE);
|
|
if (notify_bar ())
|
|
{
|
|
notify_reinit_bar ();
|
|
notify_update_bar ();
|
|
}
|
|
}
|
|
|
|
status_mesg (number_str, keys);
|
|
cwin.total_lines = print_general_options (cwin.pad.p, conf);
|
|
wins_scrollwin_display (&cwin);
|
|
}
|
|
mem_free (buf);
|
|
wins_scrollwin_delete (&cwin);
|
|
}
|
|
|
|
|
|
static void
|
|
print_key_incolor (WINDOW *win, char *option, int pos_y, int pos_x)
|
|
{
|
|
const int color = ATTR_HIGHEST;
|
|
|
|
RETURN_IF (!option, _("Undefined option!"));
|
|
custom_apply_attr (win, color);
|
|
mvwprintw (win, pos_y, pos_x, "%s ", option);
|
|
custom_remove_attr (win, color);
|
|
wnoutrefresh (win);
|
|
}
|
|
|
|
static int
|
|
print_keys_bindings (WINDOW *win, int selected_row, int selected_elm, int yoff)
|
|
{
|
|
const int XPOS = 1;
|
|
const int EQUALPOS = 23;
|
|
const int KEYPOS = 25;
|
|
int noelm, action, y;
|
|
|
|
noelm = y = 0;
|
|
for (action = 0; action < NBKEYS; action++)
|
|
{
|
|
char actionstr[BUFSIZ];
|
|
int nbkeys;
|
|
|
|
nbkeys = keys_action_count_keys (action);
|
|
(void)snprintf (actionstr, BUFSIZ, "%s", keys_get_label (action));
|
|
if (action == selected_row)
|
|
custom_apply_attr (win, ATTR_HIGHEST);
|
|
mvwprintw (win, y, XPOS, "%s ", actionstr);
|
|
mvwprintw (win, y, EQUALPOS, "=");
|
|
if (nbkeys == 0)
|
|
mvwprintw (win, y, KEYPOS, _("undefined"));
|
|
if (action == selected_row)
|
|
custom_remove_attr (win, ATTR_HIGHEST);
|
|
if (nbkeys > 0)
|
|
{
|
|
if (action == selected_row)
|
|
{
|
|
char *key;
|
|
int pos;
|
|
|
|
pos = KEYPOS;
|
|
while ((key = keys_action_nkey (action, noelm)) != NULL)
|
|
{
|
|
if (noelm == selected_elm)
|
|
print_key_incolor (win, key, y, pos);
|
|
else
|
|
mvwprintw (win, y, pos, "%s ", key);
|
|
noelm++;
|
|
pos += strlen (key) + 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mvwprintw (win, y, KEYPOS, "%s", keys_action_allkeys (action));
|
|
}
|
|
}
|
|
y += yoff;
|
|
}
|
|
|
|
return noelm;
|
|
}
|
|
|
|
static void
|
|
custom_keys_config_bar (void)
|
|
{
|
|
struct binding quit = {_("Exit"), KEY_GENERIC_QUIT};
|
|
struct binding info = {_("Key info"), KEY_GENERIC_HELP};
|
|
struct binding add = {_("Add key"), KEY_ADD_ITEM};
|
|
struct binding del = {_("Del key"), KEY_DEL_ITEM};
|
|
struct binding up = {_("Up"), KEY_MOVE_UP};
|
|
struct binding down = {_("Down"), KEY_MOVE_DOWN};
|
|
struct binding left = {_("Prev Key"), KEY_MOVE_LEFT};
|
|
struct binding right = {_("Next Key"), KEY_MOVE_RIGHT};
|
|
|
|
struct binding *binding[] = {
|
|
&quit, &info, &add, &del, &up, &down, &left, &right
|
|
};
|
|
int binding_size = sizeof (binding) / sizeof (binding[0]);
|
|
|
|
keys_display_bindings_bar (win[STA].p, binding, 0, binding_size);
|
|
}
|
|
|
|
void
|
|
custom_keys_config (void)
|
|
{
|
|
struct scrollwin kwin;
|
|
int selrow, selelm, firstrow, lastrow, nbrowelm, nbdisplayed;
|
|
int keyval, used, not_recognized;
|
|
char *keystr;
|
|
WINDOW *grabwin;
|
|
const int LINESPERKEY = 2;
|
|
const int LABELLINES = 3;
|
|
|
|
clear ();
|
|
custom_set_swsiz (&kwin);
|
|
nbdisplayed = (kwin.win.h - LABELLINES) / LINESPERKEY;
|
|
(void)snprintf (kwin.label, BUFSIZ, _("keys configuration"));
|
|
wins_scrollwin_init (&kwin);
|
|
wins_show (kwin.win.p, kwin.label);
|
|
custom_keys_config_bar ();
|
|
selrow = selelm = 0;
|
|
nbrowelm = print_keys_bindings (kwin.pad.p, selrow, selelm, LINESPERKEY);
|
|
kwin.total_lines = NBKEYS * LINESPERKEY;
|
|
wins_scrollwin_display (&kwin);
|
|
firstrow = 0;
|
|
lastrow = firstrow + nbdisplayed - 1;
|
|
for (;;)
|
|
{
|
|
int ch;
|
|
|
|
ch = keys_getch (win[STA].p);
|
|
switch (ch)
|
|
{
|
|
case KEY_MOVE_UP:
|
|
if (selrow > 0)
|
|
{
|
|
selrow--;
|
|
selelm = 0;
|
|
if (selrow == firstrow)
|
|
{
|
|
firstrow--;
|
|
lastrow--;
|
|
wins_scrollwin_up (&kwin, LINESPERKEY);
|
|
}
|
|
}
|
|
break;
|
|
case KEY_MOVE_DOWN:
|
|
if (selrow < NBKEYS - 1)
|
|
{
|
|
selrow++;
|
|
selelm = 0;
|
|
if (selrow == lastrow)
|
|
{
|
|
firstrow++;
|
|
lastrow++;
|
|
wins_scrollwin_down (&kwin, LINESPERKEY);
|
|
}
|
|
}
|
|
break;
|
|
case KEY_MOVE_LEFT:
|
|
if (selelm > 0)
|
|
selelm--;
|
|
break;
|
|
case KEY_MOVE_RIGHT:
|
|
if (selelm < nbrowelm - 1)
|
|
selelm++;
|
|
break;
|
|
case KEY_GENERIC_HELP:
|
|
keys_popup_info (selrow);
|
|
break;
|
|
case KEY_ADD_ITEM:
|
|
#define WINROW 10
|
|
#define WINCOL 50
|
|
do
|
|
{
|
|
used = 0;
|
|
grabwin = popup (WINROW, WINCOL, (row - WINROW) / 2,
|
|
(col - WINCOL) / 2,
|
|
_("Press the key you want to assign to:"),
|
|
keys_get_label (selrow), 0);
|
|
keyval = wgetch (grabwin);
|
|
|
|
/* First check if this key would be recognized by calcurse. */
|
|
if (keys_str2int (keys_int2str (keyval)) == -1)
|
|
{
|
|
not_recognized = 1;
|
|
WARN_MSG (_("This key is not yet recognized by calcurse, "
|
|
"please choose another one."));
|
|
werase (kwin.pad.p);
|
|
nbrowelm = print_keys_bindings (kwin.pad.p, selrow, selelm,
|
|
LINESPERKEY);
|
|
wins_scrollwin_display (&kwin);
|
|
continue;
|
|
}
|
|
else
|
|
not_recognized = 0;
|
|
|
|
used = keys_assign_binding (keyval, selrow);
|
|
if (used)
|
|
{
|
|
enum key action;
|
|
|
|
action = keys_get_action (keyval);
|
|
WARN_MSG (_("This key is already in use for %s, "
|
|
"please choose another one."),
|
|
keys_get_label (action));
|
|
werase (kwin.pad.p);
|
|
nbrowelm = print_keys_bindings (kwin.pad.p, selrow, selelm,
|
|
LINESPERKEY);
|
|
wins_scrollwin_display (&kwin);
|
|
}
|
|
delwin (grabwin);
|
|
}
|
|
while (used || not_recognized);
|
|
nbrowelm++;
|
|
if (selelm < nbrowelm - 1)
|
|
selelm++;
|
|
#undef WINROW
|
|
#undef WINCOL
|
|
break;
|
|
case KEY_DEL_ITEM:
|
|
keystr = keys_action_nkey (selrow, selelm);
|
|
keyval = keys_str2int (keystr);
|
|
keys_remove_binding (keyval, selrow);
|
|
nbrowelm--;
|
|
if (selelm > 0 && selelm <= nbrowelm)
|
|
selelm--;
|
|
break;
|
|
case KEY_GENERIC_QUIT:
|
|
if (keys_check_missing_bindings () != 0)
|
|
{
|
|
WARN_MSG (_("Some actions do not have any associated "
|
|
"key bindings!"));
|
|
}
|
|
wins_scrollwin_delete (&kwin);
|
|
return;
|
|
}
|
|
custom_keys_config_bar ();
|
|
werase (kwin.pad.p);
|
|
nbrowelm = print_keys_bindings (kwin.pad.p, selrow, selelm, LINESPERKEY);
|
|
wins_scrollwin_display (&kwin);
|
|
}
|
|
}
|