getstring() improved to allow the modification of an existing string

shwostring(), showcursor(), del_char() and add_char() created
This commit is contained in:
Frederic Culot 2006-10-28 09:57:07 +00:00
parent ac4a12158c
commit 5e112e69e5

View File

@ -1,4 +1,4 @@
/* $calcurse: utils.c,v 1.10 2006/09/17 10:45:06 culot Exp $ */ /* $calcurse: utils.c,v 1.11 2006/10/28 09:57:07 culot Exp $ */
/* /*
* Calcurse - text-based organizer * Calcurse - text-based organizer
@ -116,49 +116,160 @@ print_in_middle(WINDOW * win, int starty, int startx, int width, char *string)
custom_remove_attr(win, ATTR_HIGHEST); custom_remove_attr(win, ATTR_HIGHEST);
} }
/* Delete a character at the given position in string. */
void del_char(int pos, char *str)
{
str += pos;
for (; *str; ++str)
*str = *(str + 1);
*str = 0;
}
/* Add a character at the given position in string. */
char *add_char(int pos, int ch, char *str)
{
int new, buf;
str += pos;
buf = *str;
*str++ = ch;
new = buf;
for (; *str; ++str) {
buf = *str;
*str = new;
new = buf;
}
*str++ = new;
return str;
}
/*
* Draw the cursor at the correct position in string.
* As echoing is not set, we need to know the string we are working on to
* handle display correctly.
*/
void showcursor(WINDOW *win, int y, int pos, char *str, int l, int offset)
{
char *nc;
nc = str + pos;
wmove(win, y, pos - offset);
(pos >= l) ? waddch(win, SPC|A_REVERSE) : waddch(win, *nc|A_REVERSE);
}
/* Print the string at the desired position. */
void showstring(WINDOW *win, int y, int x, char *str, int len, int pos)
{
const int rec = 30, border = 3;
const int max_col = col - border, max_len = max_col - rec;
int page, max_page, offset, c = 0;
char *orig;
orig = str;
max_page = (len - rec) / max_len;
page = (pos - rec) / max_len;
offset = page * max_len;
str += offset;
mvwaddnstr(win, y, x, str, MIN(len, max_col));
wclrtoeol(win);
if (page > 0 && page < max_page) {
c = '*';
} else if (page > 0) {
c = '<';
} else if (page < max_page) {
c = '>';
} else
c = 0;
mvwprintw(win, y, col - 1, "%c", c);
showcursor(win, y, pos, orig, len, offset);
}
/* /*
* Getstring allows to get user input and to print it on a window, * Getstring allows to get user input and to print it on a window,
* even if noecho() is on. * even if noecho() is on. This function is also used to modify an existing
* text (the variable string can be non-NULL).
* We need to do the echoing manually because of the multi-threading
* environment, otherwise the cursor would move from place to place without
* control.
*/ */
void getstring(win, colr, string, start_x, start_y) int getstring(WINDOW *win, int colr, char *string, int x, int y)
WINDOW *win;
int colr;
char *string;
int start_x, start_y;
{ {
int ch; int ch, newpos, len = 0;
int charcount = 0; char *orig;
orig = string;
custom_apply_attr(win, ATTR_HIGHEST); custom_apply_attr(win, ATTR_HIGHEST);
if (start_x != -1) for (; *string; ++string, ++len);
wmove(win, start_y, start_x); newpos = x + len;
showstring(win, y, x, orig, len, newpos);
while ((ch = wgetch(win)) != '\n') { while ((ch = wgetch(win)) != '\n') {
if ((ch == KEY_BACKSPACE) ||
(ch == 330) || switch (ch) {
(ch == 263) ||
(ch == 127) || case KEY_BACKSPACE: /* delete one character */
(ch == CTRL('H')) ) { case 330:
if (charcount > 0) { case 127:
string--; case CTRL('H'):
charcount--; if (len > 0) {
wmove(win, start_y, start_x + charcount); --newpos; --len;
waddch(win, ' '); if (newpos >= x + len)
wmove(win, start_y, start_x + charcount); --string;
else /* to be deleted inside string */
del_char(newpos, orig);
} }
} else if (ch == ESCAPE) { break;
*string = NULL;
return; case CTRL('D'): /* delete next character */
} else { --len;
*string++ = ch; del_char(newpos, orig);
charcount++; break;
waddch(win, ch);
case CTRL('K'): /* delete to end-of-line */
string = orig + newpos;
for (; *string; ++string)
*string = 0;
len -= (len - newpos);
break;
case CTRL('A'): /* go to begginning of string */
newpos = x;
break;
case CTRL('E'): /* go to end of string */
newpos = x + len;
break;
case KEY_LEFT: /* move one char backward */
case CTRL('B'):
if (newpos > x) newpos--;
break;
case KEY_RIGHT: /* move one char forward */
case CTRL('F'):
if (newpos < len) newpos++;
break;
case ESCAPE: /* cancel editing */
return 1;
break;
default: /* insert one character */
if (len < MAX_LENGTH - 1) {
if (newpos >= len)
*string++ = ch;
else // char is to be inserted inside string
string = add_char(newpos, ch, orig);
++len; ++newpos;
}
} }
showstring(win, y, x, orig, len, newpos);
doupdate(); doupdate();
} }
*string = 0; *string = 0;
custom_remove_attr(win, ATTR_HIGHEST); custom_remove_attr(win, ATTR_HIGHEST);
return; return 0;
} }
/* checks if a string is only made of digits */ /* checks if a string is only made of digits */